... 


                     用心打造实用的学习PIC单片机博客
 

...

时 间 记 忆

...
最 新 评 论
...
专 题 分 类
...
最 新 日 志
...
最 新 留 言
...
搜 索
用 户 登 录
...
友 情 连 接
博 客 信 息
...


 
老外的视频字符叠加程序
[ 2007-12-20 14:11:00 | By: PICC学习之家 ]
 

下载地址:http://www.nycht.com/pic16bbs/dispbbs.asp?boardid=5&id=153

/*
 *******************************************************************************
 * pico OSD : simple PIC OSD PAL video superimposer
 *******************************************************************************
 *
 * This program shows how to superimpose a text on a PAL composite video signal
 * with a PIC and only 4 resistors.
 *
 * source code for mikro C compiler V7.0.0.3
 * feel free to use this code at your own risks
 *
 * target : PIC12F683 @25MHz
 * HS clock, no watchdog.
 *
 * Author : Bruno Gavand, October 2007
 
 *
 *******************************************************************************
 */
#i nclude        "built_in.h"
#i nclude        "fonts.h"

/*************************
 * CONSTANTS DEFINITIONS
 *************************/
 
/*
 * CVREF = (VR<3:0>/24) ?VDD
 * PAL CLIP LEVEL : 0.625 V
 */
#define CLIP_VOLTAGE    625             // in mV
#define CLIP_LEVEL      (CLIP_VOLTAGE * 24 / 5000)    // for VR bits CMCON<3:0>

#define OUT             GPIO.F2         // video output

#define HSYMBOLS        11              // number of horizontal symbols
#define FONTH           7               // pixel font height

#define T0FREQ          (Clock_kHz() * 1000 / 4)                // number of TMR0 ticks in one second
#define T028us          (unsigned char)(T0FREQ * 0.000028)      // number of TMR0 ticks in 28 祍

/************************
 * PSEUDO FUNCTIONS
 ************************/

/*
 * this macro definition sets message display from line l, color c (1=white, 0=black), font size s
 */
#define setMsg(l, c, s) vStart = l ; vStop = vStart + FONTH * s ; lHeight = s ; OUT = c

/*
 * set output depending on bit number x of the current position indexed to by FSR
 * Note : if you use a 20 Mhz crystal instead of a 25 Mhz crystal, remove NOP
 */
#define SETPIXEL(x)     asm { BTFSC     INDF, x         ; skip next intruction if bit x is set                  } \
                        asm { BCF       TRISIO, 2       ; set GP2 as output and superimpose pixel               } \
                        asm { NOP                       ; no operation (enlarges pixel)                         } \
                        asm { BSF       TRISIO, 2       ; set GP2 as high Z input (no pixel superimposed)       }

/*
 * write the 5 bits of the current character in the current line,
 * then increment FSR to point to the next character
 */
#define WRITECHAR()             SETPIXEL(0)     \
                                SETPIXEL(1)     \
                                SETPIXEL(2)     \
                                SETPIXEL(3)     \
                                SETPIXEL(4)     \
                                FSR++

/***********************
 * VARIABLES DEFINITIONS
 ***********************/
 
/*
 * demo message to be scrolled
 */
const unsigned char scroll_msg[] = "Scroll text : pico OSD is scrolling this very long message on your screen, and then will rewind it very fast. Ready ? Now !" ;

unsigned char   line = 0 ;              // current line number
unsigned char   ctrLine = 0 ;           // counter of line to be repeated (to make big sized fonts)

unsigned char   bm[FONTH][HSYMBOLS] absolute 0x23 ;     // bitmap to be superimposed to video
unsigned char   display absolute 0xa0 ;                 // address of data to be displayed, ensure it is in the same memory bank as TRISIO

unsigned char   msg[HSYMBOLS + 1] ;                     // dynamic string to be displayed

volatile unsigned char  vStart = 255 absolute 0x20,     // vertical start : first line to be superimposed
                        vStop absolute 0x21,            // vertical stop : last line to be superimposed
                        lHeight absolute 0x22 ;         // line height : number of time the same line must be displayed

unsigned int    frm ;           // frame counter
unsigned char   sec  = 0,       // RTC seconds,
                mn = 0,         // minutes,
                hours = 0 ;     // hours

/****************************
 * Interrupt Service routine
 ****************************/
/*
 * since no other interrupts but CMIE are enabled, no need to check this flag.
 */
void interrupt()
        {
        if(CMCON0.COUT)                                 // if comparator output changed to high
                {
                if((line >= vStart) && (line < vStop))  // if we are in display window
                        {
                        FSR = display ;                 // load FSR with current bitmap address

                        WRITECHAR() ;                   // set character pixels
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;
                        WRITECHAR() ;

                        ctrLine++ ;                     // increment same line counter
                        if(ctrLine == lHeight)          // do we have to change ?
                                {
                                display += HSYMBOLS ;   // yes, change display location to next bitmap row
                                ctrLine = 0 ;           // reset counter
                                }
                        TMR0 = 0 ;                      // keep timer 0 clear to prevent false start of frame detection
                        }
                else if(TMR0 >= T028us)                 // if, check low pulse durection
                        {
                        line = 0 ;                      // we are in a new frame sync, reset line counter
                        ctrLine = 0 ;                   // reset same line counter
                        display = (char)bm ;            // points to the bitmap start
                        }
                }
        else                                            // compatator output changed to low
                {
                TMR0 = 0 ;                              // clear timer 0
                if(line < 254)                          // if we can
                        {
                        line++ ;                        // increment line counter (only first 255 lines are used)
                        }

                /*
                 * Real Time Clock
                 */
                frm++ ;                                 // increment frames counter
                if(frm == 625 * 25)                     // PAL is made of 25 frames of 625 lines per second
                        {
                        frm = 0 ;                       // clear counter
                        sec++ ;                         // increment seconds
                        if(sec >= 60)                   // check for seconds rollover
                                {
                                sec = 0 ;               // clear seconds
                                mn++ ;                  // increment minutes
                                if(mn >= 60)            // check for minutes rollover
                                        {
                                        mn = 0 ;        // clear minutes
                                        hours++ ;       // increment hours
                                        }
                                }
                        }
                }
        PIR1.CMIF = 0 ;                                 // clear comparator interrupt flag
        }
       
/*
 * update display bitmap with character c at column pos
 */
void updatechar(unsigned char c, unsigned char pos)
        {
        unsigned char   py, col ;

        /*
         * check for under/overflow
         */
        if(c < 32) c = 32 ;
        else if(c > 128) c = 32 ;
        else c -= 32 ;                                  // control characters under space in ASCII table are not displayed

        for(col = 0 ; col < 5 ; col++)                  // for each character columns
                {
                unsigned char fnt = fonts[c * 5 + col] ;        // get bitmap font
                unsigned char mask = 1 << col ;                 // build bitmap mask

                for(py = 0 ; py < FONTH ; py++)         // for each character lines
                        {
                        if(fnt.F0)
                                {
                                bm[py][pos] |= mask ;   // set pixel
                                }
                        else
                                {
                                bm[py][pos] &= ~mask ;  // clear pixel
                                }
                        fnt >>= 1 ;                     // shift bitmap mask
                        }
                }
        }

/*
 * update display message with constant string pointed to by m with offset o within the string
 */
void updateMsg(const char *m, unsigned char o)
        {
        unsigned char   n, l, c ;

        /*
         * get string length
         */
        l = 0 ;
        while(m[l++]) ;

        for(n = 0 ; n < HSYMBOLS ; n++)         // for all symbols
                {
                c = m[o++] ;                    // get character
                o %= l ;                        // circularize string
                updateChar(c, n) ;              // put character to display bitmap
                }
        }

/*
 * 10 ms delay, c times
 */
void    delay10ms(unsigned char c)
        {
        do
                {
                Delay_ms(10) ;
                }
        while(--c) ;
        }

/*
 * program entry
 */
void main()
        {
        unsigned char   i ;
       
        GPIO = 0b100 ;                          // GP2 is set to one be default (text is superimposed in white)
        TRISIO = 0b110 ;                        // GP1 is video input, GP2 is video output (set to high Z first)
        CMCON0 = 0b10100 ;                      // comparator module : no output, uses internal voltage reference
        VRCON = 0b10100000 | CLIP_LEVEL ;       // voltage reference module : inverted output, low level
        ANSEL = 0b10 ;                          // all pins but GP1 (comparator input) as digital

        OPTION_REG = 0b10001000 ;               // no prescaler on TMR0
       
        PIE1.CMIE = 1 ;                         // enable comparator interrupt
        INTCON.PEIE = 1 ;                       // enable peripheral interrupt
        INTCON.GIE = 1 ;                        // enable global interrupt

        /*
         * init display window
         */
        lHeight = 1 ;
        vStart = 10 ;
        vStop = 10 ;

        /*************************
         * pico OSD demonstration
         *************************/

        /*
         * welcome messages
         */
        updateMsg("Welcome to ", 0) ;
        for(i = 1 ; i < 10 ; i++)
                {
                setMsg(50, 1, i) ;
                delay10ms(5) ;
                }
        delay10ms(100) ;

        updateMsg("  pico OSD ", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(100) ;

        updateMsg("the tiniest", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(100) ;

        updateMsg("OSD of the ", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(100) ;

        updateMsg("WORLD !!!!!", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(500) ;

        updateMsg(" It can... ", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(500) ;

        /*
         * move message along vertical axe
         */
        updateMsg(" Move text ", 0) ;
        for(i = 20 ; i < 195 ; i++)
                {
                setMsg(i, 1, 6) ;
                delay10ms(1) ;
                }
        for( ; i > 20 ; i--)
                {
                setMsg(i, 1, 6) ;
                delay10ms(1) ;
                }
        for( ; i < 100 ; i++)
                {
                setMsg(i, 1, 6) ;
                delay10ms(1) ;
                }
        delay10ms(100) ;

        /*
         * horizontal scroll
         */
        updateMsg(scroll_msg, 0) ;
        delay10ms(200) ;
        for(i = 0 ; i < sizeof(scroll_msg) - HSYMBOLS ; i++)
                {
                updateMsg(scroll_msg, i) ;
                setMsg(100, 1, 6) ;
                delay10ms(10) ;
                }
        delay10ms(50) ;
        for( ; i > 0 ; i--)
                {
                updateMsg(scroll_msg, i) ;
                setMsg(100, 1, 6) ;
                delay10ms(3) ;
                }
        updateMsg(scroll_msg, 0) ;
        delay10ms(100) ;

        /*
         * change text size
         */
        updateMsg("Resize text", 0) ;
        delay10ms(100) ;
        for(i = 6 ; i < 20 ; i++)
                {
                setMsg(100, 1, i) ;
                delay10ms(10) ;
                }
        for( ; i > 0 ; i--)
                {
                setMsg(100, 1, i) ;
                delay10ms(10) ;
                }
        for(i = 1 ; i < 6 ; i++)
                {
                setMsg(100, 1, i) ;
                delay10ms(10) ;
                }
        delay10ms(100) ;

        /*
         * change text color
         */
        for(i = 0 ; i < 2 ; i++)
                {
                updateMsg("  In Black ", 0) ;
                setMsg(100, 0, 6) ;
                delay10ms(100) ;

                updateMsg("  Or White ", 0) ;
                setMsg(100, 1, 6) ;
                delay10ms(100) ;
                }

        /*
         * prepare to display run time
         */
        updateMsg("Run time : ", 0) ;
        setMsg(100, 1, 6) ;
        delay10ms(100) ;
        setMsg(40, 1, 3) ;
        delay10ms(100) ;

        updateChar('H', 2) ;
        updateChar('m', 5) ;
        updateChar('i', 6) ;
        updateChar('n', 7) ;
        updateChar('s', 10) ;

        /*
         * update run time clock display
         */
        for(;;)
                {
                updateChar(hours / 10 + '0', 0) ;
                updateChar(hours % 10 + '0', 1) ;

                updateChar(mn / 10 + '0', 3) ;
                updateChar(mn % 10 + '0', 4) ;

                updateChar(sec / 10 + '0', 8) ;
                updateChar(sec % 10 + '0', 9) ;
                }
        }

 
 
Re:老外的视频字符叠加程序
[ 2007-12-21 11:58:10 | By: nana ]
 
nanathanks!
 
发表评论:
...

Powered by Mcublog.