https://www.micro-examples.com/articles/index.php?title=PicoOSD&feed=atom&action=historyPicoOSD - Revision history2024-03-29T15:55:37ZRevision history for this page on the wikiMediaWiki 1.18.1https://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=227&oldid=prevBrunog at 21:10, 12 February 20122012-02-12T21:10:09Z<p></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 21:10, 12 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">[[File:PicoOSD.jpg|thumb|PicoOSD components]]</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>An On-Screen-Display with only 5 components !</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>An On-Screen-Display with only 5 components !</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=203&oldid=prevBrunog at 22:35, 11 February 20122012-02-11T22:35:14Z<p></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 22:35, 11 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 451:</td>
<td colspan="2" class="diff-lineno">Line 451:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==Discussion and comments==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==Discussion and comments==</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">{{#w4grb_rate:}}</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><discussion /></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div><discussion /></div></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=171&oldid=prevBrunog: /* PicoOSD : a PIC-based simple and cheap OSD */2012-02-09T23:56:54Z<p><span class="autocomment">PicoOSD : a PIC-based simple and cheap OSD</span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 23:56, 9 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 2:</td>
<td colspan="2" class="diff-lineno">Line 2:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==PicoOSD : a PIC-based simple and cheap OSD==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==PicoOSD : a PIC-based simple and cheap OSD==</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div><del class="diffchange diffchange-inline">Let me introduce PicoOSD to you with this </del>short video clip :</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">A </ins>short video clip <ins class="diffchange diffchange-inline">is sometimes better than a long explanation </ins>:</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=130&oldid=prevBrunog: /* PicoOSD : a PIC-based simple and cheap OSD */2012-02-09T15:06:21Z<p><span class="autocomment">PicoOSD : a PIC-based simple and cheap OSD</span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 15:06, 9 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 5:</td>
<td colspan="2" class="diff-lineno">Line 5:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div>The idea of this circuit is to push an 8-bit PIC to the limits to build a cheap video superimposer : MCU extracts PAL sync in real-time and <del class="diffchange diffchange-inline">adds </del>a line of text to the video.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>The idea of this circuit is to push an 8-bit PIC to the limits to build a cheap video superimposer : MCU extracts PAL sync in real-time and <ins class="diffchange diffchange-inline">overlays </ins>a line of text to the video.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>If you like it, please see also my [[Pic Pal Video Library]], to turn a [[PIC18]] into a black and white PAL video generator.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>If you like it, please see also my [[Pic Pal Video Library]], to turn a [[PIC18]] into a black and white PAL video generator.</div></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=129&oldid=prevBrunog: /* PicoOSD : a PIC-based simple and cheap OSD */2012-02-09T15:06:01Z<p><span class="autocomment">PicoOSD : a PIC-based simple and cheap OSD</span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 15:06, 9 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 5:</td>
<td colspan="2" class="diff-lineno">Line 5:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>{{#ev:youtube|u1N5WJ_dZ3s}}</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div>The idea of this circuit is to push an 8-bit PIC to the limits to build a cheap video superimposer : MCU extracts PAL sync in real-time and <del class="diffchange diffchange-inline">add </del>a line text to the video.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>The idea of this circuit is to push an 8-bit PIC to the limits to build a cheap video superimposer : MCU extracts PAL sync in real-time and <ins class="diffchange diffchange-inline">adds </ins>a line <ins class="diffchange diffchange-inline">of </ins>text to the video.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>If you like it, please see also my [[Pic Pal Video Library]], to turn a [[PIC18]] into a black and white PAL video generator.</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>If you like it, please see also my [[Pic Pal Video Library]], to turn a [[PIC18]] into a black and white PAL video generator.</div></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=126&oldid=prevBrunog: /* C Source code */2012-02-09T14:07:49Z<p><span class="autocomment">C Source code</span></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 14:07, 9 February 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 422:</td>
<td colspan="2" class="diff-lineno">Line 422:</td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></pre></div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div></pre></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="background: #ffa; color:black; font-size: smaller;"><div>As you can see, there is no assembly in C source code but the SETPIXEL(c) macro. Video synchronization and generation is made by interrupt routine, main loop only controls shape and position of the text.</div></td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div>As you can see, there is no assembly in C source code but the SETPIXEL(c) macro. Video synchronization and generation is made by interrupt routine, main loop only controls shape and position of the text <ins class="diffchange diffchange-inline">:</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">To superimpose text to a PAL video signal, we need to control timing with precision to get a stable picture.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">We have to deal with vertical synchronization, which tells us when a new frame starts, and with horizontal synchronization, which tells us when a new line starts.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">Usually, and external circuit is used to extract both vertical and horizontal synchronization pulses from the PAL video signal, the LM1881 integrated circuit does it very well for example.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">Since I wanted to have a very simple circuit, I had to find a way to make the PIC do this job.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">First, we must be able to know when a video line starts : we will use the PIC internal comparator module to do it. The internal voltage reference module will be programmed with a voltage clip level, the comparator will then trigger an interrupt each time the input voltage will become lower or higher than the clip level. This will be our horizontal sync separator.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">Second, we must be able to know when a frame starts do get vertical sync : PAL signal uses special sync pulses to announce a new frame. We have to detect a 28 µs low level pulse, there are five of them in the vertical sync and none elsewhere. The internal timer module of the PIC will be used to count time of low level pulses.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">This done, we must be able to know what to superimpose to the video signal. A bitmap representation of the text to be displayed is built in RAM from a 5x7 fonts table. On each new line interrupt, we check if we are in display time window for adding pixels or not.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div> </div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins class="diffchange diffchange-inline">To add a pixel to the video signal, we change output pin from high Z state to output, the output then imposes +Vcc or 0V to display either a white or a black pixel. The result is a superimposed text on transparent background </ins>.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==Download project==</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>==Download project==</div></td></tr>
</table>Brunoghttps://www.micro-examples.com/articles/index.php?title=PicoOSD&diff=125&oldid=prevBrunog: Created page with "An On-Screen-Display with only 5 components ! ==PicoOSD : a PIC-based simple and cheap OSD== Let me introduce PicoOSD to you with this short video clip : {{#ev:youtube|u1N5WJ..."2012-02-09T13:49:20Z<p>Created page with "An On-Screen-Display with only 5 components ! ==PicoOSD : a PIC-based simple and cheap OSD== Let me introduce PicoOSD to you with this short video clip : {{#ev:youtube|u1N5WJ..."</p>
<p><b>New page</b></p><div>An On-Screen-Display with only 5 components !<br />
<br />
==PicoOSD : a PIC-based simple and cheap OSD==<br />
Let me introduce PicoOSD to you with this short video clip :<br />
{{#ev:youtube|u1N5WJ_dZ3s}}<br />
<br />
The idea of this circuit is to push an 8-bit PIC to the limits to build a cheap video superimposer : MCU extracts PAL sync in real-time and add a line text to the video.<br />
<br />
If you like it, please see also my [[Pic Pal Video Library]], to turn a [[PIC18]] into a black and white PAL video generator.<br />
<br />
==Circuit Schematic==<br />
[[File:PicoOSD-schematic.jpg]]<br />
* The PIC12 MCU is slightly overclocked : 25 MHz instead of 20 MHz max<br />
* There is no signal mixer : output signal is directly added to input signal, not very clean but fine for the demo<br />
<br />
==C Source code==<br />
<pre><br />
/*<br />
*******************************************************************************<br />
* pico OSD : simple PIC OSD PAL video superimposer<br />
*******************************************************************************<br />
*<br />
* This program shows how to superimpose a text on a PAL composite video signal<br />
* with a PIC and only 4 resistors.<br />
*<br />
* source code for mikro C compiler V7.0.0.3<br />
* feel free to use this code at your own risks<br />
*<br />
* target : PIC12F683 @25MHz<br />
* HS clock, no watchdog.<br />
*<br />
* Author : Bruno Gavand, October 2007<br />
* see more details on http://www.micro-examples.com/<br />
*<br />
*******************************************************************************<br />
*/<br />
#include "built_in.h"<br />
#include "fonts.h"<br />
<br />
/*************************<br />
* CONSTANTS DEFINITIONS<br />
*************************/<br />
<br />
/*<br />
* CVREF = (VR<3:0>/24) × VDD<br />
* PAL CLIP LEVEL : 0.625 V<br />
*/<br />
#define CLIP_VOLTAGE 625 // in mV<br />
#define CLIP_LEVEL (CLIP_VOLTAGE * 24 / 5000) // for VR bits CMCON<3:0><br />
<br />
#define OUT GPIO.F2 // video output<br />
<br />
#define HSYMBOLS 11 // number of horizontal symbols<br />
#define FONTH 7 // pixel font height<br />
<br />
#define T0FREQ (Clock_kHz() * 1000 / 4) // number of TMR0 ticks in one second<br />
#define T028us (unsigned char)(T0FREQ * 0.000028) // number of TMR0 ticks in 28 µs<br />
<br />
/************************<br />
* PSEUDO FUNCTIONS<br />
************************/<br />
<br />
/*<br />
* this macro definition sets message display from line l, color c (1=white, 0=black), font size s<br />
*/<br />
#define setMsg(l, c, s) vStart = l ; vStop = vStart + FONTH * s ; lHeight = s ; OUT = c<br />
<br />
/*<br />
* set output depending on bit number x of the current position indexed to by FSR<br />
* Note : if you use a 20 Mhz crystal instead of a 25 Mhz crystal, remove NOP<br />
*/<br />
#define SETPIXEL(x) asm { BTFSC INDF, x ; skip next intruction if bit x is set } \<br />
asm { BCF TRISIO, 2 ; set GP2 as output and superimpose pixel } \<br />
asm { NOP ; no operation (enlarges pixel) } \<br />
asm { BSF TRISIO, 2 ; set GP2 as high Z input (no pixel superimposed) }<br />
<br />
/*<br />
* write the 5 bits of the current character in the current line,<br />
* then increment FSR to point to the next character<br />
*/<br />
#define WRITECHAR() SETPIXEL(0) \<br />
SETPIXEL(1) \<br />
SETPIXEL(2) \<br />
SETPIXEL(3) \<br />
SETPIXEL(4) \<br />
FSR++<br />
<br />
/***********************<br />
* VARIABLES DEFINITIONS<br />
***********************/<br />
<br />
/*<br />
* demo message to be scrolled<br />
*/<br />
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 !" ;<br />
<br />
unsigned char line = 0 ; // current line number<br />
unsigned char ctrLine = 0 ; // counter of line to be repeated (to make big sized fonts)<br />
<br />
unsigned char bm[FONTH][HSYMBOLS] absolute 0x23 ; // bitmap to be superimposed to video<br />
unsigned char display absolute 0xa0 ; // address of data to be displayed, ensure it is in the same memory bank as TRISIO<br />
<br />
unsigned char msg[HSYMBOLS + 1] ; // dynamic string to be displayed<br />
<br />
volatile unsigned char vStart = 255 absolute 0x20, // vertical start : first line to be superimposed<br />
vStop absolute 0x21, // vertical stop : last line to be superimposed<br />
lHeight absolute 0x22 ; // line height : number of time the same line must be displayed<br />
<br />
unsigned int frm ; // frame counter<br />
unsigned char sec = 0, // RTC seconds,<br />
mn = 0, // minutes,<br />
hours = 0 ; // hours<br />
<br />
/****************************<br />
* Interrupt Service routine<br />
****************************/<br />
/*<br />
* since no other interrupts but CMIE are enabled, no need to check this flag.<br />
*/<br />
void interrupt()<br />
{<br />
if(CMCON0.COUT) // if comparator output changed to high<br />
{<br />
if((line >= vStart) && (line < vStop)) // if we are in display window<br />
{<br />
FSR = display ; // load FSR with current bitmap address<br />
<br />
WRITECHAR() ; // set character pixels<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
WRITECHAR() ;<br />
<br />
ctrLine++ ; // increment same line counter<br />
if(ctrLine == lHeight) // do we have to change ?<br />
{<br />
display += HSYMBOLS ; // yes, change display location to next bitmap row<br />
ctrLine = 0 ; // reset counter<br />
}<br />
TMR0 = 0 ; // keep timer 0 clear to prevent false start of frame detection<br />
}<br />
else if(TMR0 >= T028us) // if, check low pulse duration<br />
{<br />
line = 0 ; // we are in a new frame sync, reset line counter<br />
ctrLine = 0 ; // reset same line counter<br />
display = (char)bm ; // points to the bitmap start<br />
}<br />
}<br />
else // compatator output changed to low<br />
{<br />
TMR0 = 0 ; // clear timer 0<br />
if(line < 254) // if we can<br />
{<br />
line++ ; // increment line counter (only first 255 lines are used)<br />
}<br />
<br />
/*<br />
* Real Time Clock<br />
*/<br />
frm++ ; // increment frames counter<br />
if(frm == 625 * 25) // PAL is made of 25 frames of 625 lines per second<br />
{<br />
frm = 0 ; // clear counter<br />
sec++ ; // increment seconds<br />
if(sec >= 60) // check for seconds rollover<br />
{<br />
sec = 0 ; // clear seconds<br />
mn++ ; // increment minutes<br />
if(mn >= 60) // check for minutes rollover<br />
{<br />
mn = 0 ; // clear minutes<br />
hours++ ; // increment hours<br />
}<br />
}<br />
}<br />
}<br />
PIR1.CMIF = 0 ; // clear comparator interrupt flag<br />
}<br />
<br />
/*<br />
* update display bitmap with character c at column pos<br />
*/<br />
void updatechar(unsigned char c, unsigned char pos)<br />
{<br />
unsigned char py, col ;<br />
<br />
/*<br />
* check for under/overflow<br />
*/<br />
if(c < 32) c = 32 ;<br />
else if(c > 128) c = 32 ;<br />
else c -= 32 ; // control characters under space in ASCII table are not displayed<br />
<br />
for(col = 0 ; col < 5 ; col++) // for each character columns<br />
{<br />
unsigned char fnt = fonts[c * 5 + col] ; // get bitmap font<br />
unsigned char mask = 1 << col ; // build bitmap mask<br />
<br />
for(py = 0 ; py < FONTH ; py++) // for each character lines<br />
{<br />
if(fnt.F0)<br />
{<br />
bm[py][pos] |= mask ; // set pixel<br />
}<br />
else<br />
{<br />
bm[py][pos] &= ~mask ; // clear pixel<br />
}<br />
fnt >>= 1 ; // shift bitmap mask<br />
}<br />
}<br />
}<br />
<br />
/*<br />
* update display message with constant string pointed to by m with offset o within the string<br />
*/<br />
void updateMsg(const char *m, unsigned char o)<br />
{<br />
unsigned char n, l, c ;<br />
<br />
/*<br />
* get string length<br />
*/<br />
l = 0 ;<br />
while(m[l++]) ;<br />
<br />
for(n = 0 ; n < HSYMBOLS ; n++) // for all symbols<br />
{<br />
c = m[o++] ; // get character<br />
o %= l ; // circularize string<br />
updateChar(c, n) ; // put character to display bitmap<br />
}<br />
}<br />
<br />
/*<br />
* 10 ms delay, c times<br />
*/<br />
void delay10ms(unsigned char c)<br />
{<br />
do<br />
{<br />
Delay_ms(10) ;<br />
}<br />
while(--c) ;<br />
}<br />
<br />
/*<br />
* program entry<br />
*/<br />
void main()<br />
{<br />
unsigned char i ;<br />
<br />
GPIO = 0b100 ; // GP2 is set to one be default (text is superimposed in white)<br />
TRISIO = 0b110 ; // GP1 is video input, GP2 is video output (set to high Z first)<br />
CMCON0 = 0b10100 ; // comparator module : no output, uses internal voltage reference<br />
VRCON = 0b10100000 | CLIP_LEVEL ; // voltage reference module : inverted output, low level<br />
ANSEL = 0b10 ; // all pins but GP1 (comparator input) as digital<br />
<br />
OPTION_REG = 0b10001000 ; // no prescaler on TMR0<br />
<br />
PIE1.CMIE = 1 ; // enable comparator interrupt<br />
INTCON.PEIE = 1 ; // enable peripheral interrupt<br />
INTCON.GIE = 1 ; // enable global interrupt<br />
<br />
/*<br />
* init display window<br />
*/<br />
lHeight = 1 ;<br />
vStart = 10 ;<br />
vStop = 10 ;<br />
<br />
/*************************<br />
* pico OSD demonstration<br />
*************************/<br />
<br />
/*<br />
* welcome messages<br />
*/<br />
updateMsg("Welcome to ", 0) ;<br />
for(i = 1 ; i < 10 ; i++)<br />
{<br />
setMsg(50, 1, i) ;<br />
delay10ms(5) ;<br />
}<br />
delay10ms(100) ;<br />
<br />
updateMsg(" pico OSD ", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(100) ;<br />
<br />
updateMsg("the tiniest", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(100) ;<br />
<br />
updateMsg("OSD of the ", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(100) ;<br />
<br />
updateMsg("WORLD !!!!!", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(500) ;<br />
<br />
updateMsg(" It can... ", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(500) ;<br />
<br />
/*<br />
* move message along vertical axe<br />
*/<br />
updateMsg(" Move text ", 0) ;<br />
for(i = 20 ; i < 195 ; i++)<br />
{<br />
setMsg(i, 1, 6) ;<br />
delay10ms(1) ;<br />
}<br />
for( ; i > 20 ; i--)<br />
{<br />
setMsg(i, 1, 6) ;<br />
delay10ms(1) ;<br />
}<br />
for( ; i < 100 ; i++)<br />
{<br />
setMsg(i, 1, 6) ;<br />
delay10ms(1) ;<br />
}<br />
delay10ms(100) ;<br />
<br />
/*<br />
* horizontal scroll<br />
*/<br />
updateMsg(scroll_msg, 0) ;<br />
delay10ms(200) ;<br />
for(i = 0 ; i < sizeof(scroll_msg) - HSYMBOLS ; i++)<br />
{<br />
updateMsg(scroll_msg, i) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(10) ;<br />
}<br />
delay10ms(50) ;<br />
for( ; i > 0 ; i--)<br />
{<br />
updateMsg(scroll_msg, i) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(3) ;<br />
}<br />
updateMsg(scroll_msg, 0) ;<br />
delay10ms(100) ;<br />
<br />
/*<br />
* change text size<br />
*/<br />
updateMsg("Resize text", 0) ;<br />
delay10ms(100) ;<br />
for(i = 6 ; i < 20 ; i++)<br />
{<br />
setMsg(100, 1, i) ;<br />
delay10ms(10) ;<br />
}<br />
for( ; i > 0 ; i--)<br />
{<br />
setMsg(100, 1, i) ;<br />
delay10ms(10) ;<br />
}<br />
for(i = 1 ; i < 6 ; i++)<br />
{<br />
setMsg(100, 1, i) ;<br />
delay10ms(10) ;<br />
}<br />
delay10ms(100) ;<br />
<br />
/*<br />
* change text color<br />
*/<br />
for(i = 0 ; i < 2 ; i++)<br />
{<br />
updateMsg(" In Black ", 0) ;<br />
setMsg(100, 0, 6) ;<br />
delay10ms(100) ;<br />
<br />
updateMsg(" Or White ", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(100) ;<br />
}<br />
<br />
/*<br />
* prepare to display run time<br />
*/<br />
updateMsg("Run time : ", 0) ;<br />
setMsg(100, 1, 6) ;<br />
delay10ms(100) ;<br />
setMsg(40, 1, 3) ;<br />
delay10ms(100) ;<br />
<br />
updateChar('H', 2) ;<br />
updateChar('m', 5) ;<br />
updateChar('i', 6) ;<br />
updateChar('n', 7) ;<br />
updateChar('s', 10) ;<br />
<br />
/*<br />
* update run time clock display<br />
*/<br />
for(;;)<br />
{<br />
updateChar(hours / 10 + '0', 0) ;<br />
updateChar(hours % 10 + '0', 1) ;<br />
<br />
updateChar(mn / 10 + '0', 3) ;<br />
updateChar(mn % 10 + '0', 4) ;<br />
<br />
updateChar(sec / 10 + '0', 8) ;<br />
updateChar(sec % 10 + '0', 9) ;<br />
}<br />
}<br />
</pre><br />
<br />
As you can see, there is no assembly in C source code but the SETPIXEL(c) macro. Video synchronization and generation is made by interrupt routine, main loop only controls shape and position of the text.<br />
<br />
==Download project==<br />
Download PicoOSD-project.zip file for mikroC : [[File:PicoOSD-project.zip]] <br />
<br />
Includes :<br />
<br />
* [[mikroC PRO]] project files for [[PIC12F683]], should work also with most of PIC <br />
* picoOSD C source code <br />
* picoOSD .HEX files<br />
[[Category:Projects]]<br />
[[Category:PIC12]]<br />
<br />
==Discussion and comments==<br />
<discussion /></div>Brunog