|  | 
 
| 本帖最后由 star 于 2012-8-21 15:17 编辑 
 /*
 
 ***************************************************************
 ****************
 * 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.
 *
 *
 *
 *
 
 ***************************************************************
 ****************
 */
 #include        "built_in.h"
 #include        "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 µs
 /************************
 * 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 duration
 {
 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)
 ;
 }
 }
 
 
 | 
 
x本帖子中包含更多资源您需要 登录 才可以下载或查看,没有帐号?立即注册  |