Summary of PIC PAL Video Library using pic18f4620
This article describes a software video processor library for PIC18 microcontrollers that generates PAL video signals to drive TV screens. It utilizes a 2-resistor digital-to-analog converter and requires a 32 MHz clock speed. The library supports up to 128 vertical lines of 128 pixels, offering functions for initialization, drawing shapes, text, and displaying bitmaps via inline assembly mixed with C code.Parts used in the PIC PAL Video Library:
- PIC18F4620 Microcontroller
- 8 MHz Crystal Oscillator
- 2-Resistor Ladder (R8 and R9)
- Decoupling Capacitors (C1, C3, C4)
- Temperature Sensor Diode (D1)
- Switches with Pull-down Resistors
- TV Screen with PAL Composite Input
- Rickard Gunees PIC PONG page : http://www.rickard.gunee.com/projects/
- Eric Smith video clock : http://www.brouhaha.com/~eric/pic/pictock.html
This projects are fun, but I wanted to build a general purpose software video processor, to drive a TV screen just like a GLCD could be.

PIC PAL SOFTWARE VIDEO LIBRARY
Since the video screen has to be mapped in memory, only PICs with enough RAM are concerned, that's why the PIC PAL Library is for PIC18 family only.
The PIC must be clocked at 32 Mhz with a 8 Mhz crystal, to get the 64 µs horizontal synchronization timing of the PAL system.
The library generates a 625 lines interlaced PAL video signal, and can display up to 248 vertical lines of 128 pixel. Any video display device with a PAL video composite input should be able to display the picture generated by the PIC.
Because timing is critical, the part of the software producing the video uses in-line assembly mixed with C.
You can download the full mikroC project, including the library source code.
Here is the user's manual of the PIC PAL Library :
INITIALIZATION
| PROTOTYPE | void PAL_init(unsigned char y) |
| PARAMETERS | y : number of vertical lines, up to 128 |
| RETURNS | nothing |
| DESCRIPTION | prepare the PIC PAL video library the more vertical lines you want, the less memory & MPU power you haveWarnings :
|
| REQUIRES | the file PAL_library.hmust be included in user's source code.specified hardware with 2 resistors, see schematic the device must be clocked at 32 Mhz |
| EXAMPLE | PAL_init(128) ; |
Video control
| PROTOTYPE | void PAL_control(unsigned char st, unsigned char rd) |
| PARAMETERS | st : PAL synchronization control PAL_CNTL_START : start PAL synchro PAL_CNTL_STOP : stop PAL synchro (free all MCU power)rd : rendering control PAL_CNTL_BLANK : only borders are displayed (free a part of MCU power) PAL_CNTL_RENDER : full video is rendered, with borders and picture (most of MCU power is required) |
| RETURNS | nothing |
| DESCRIPTION | control the video generationwhen the PAL synchro is started, the unsigned long global variable PAL_frameCtr is incremented 25 times per second. |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER) ; |
| PROTOTYPE | void PAL_fill(unsigned char c) |
| PARAMETERS | c : filling pattern |
| RETURNS | nothing |
| DESCRIPTION | fill screen with pattern c use 0 to clear the screen, 0xff to paint the screen in white |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PALL_fill(0) ; |
SET SCREEN BORDER COLOR
| PROTOTYPE | void PAL_setBorder(unsigned char border) |
| PARAMETERS | border : either PAL_COLOR_BLACK or PAL_COLOR_WHITE |
| RETURNS | nothing |
| DESCRIPTION | change the screen border color surrounding the picture |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_border(PAL_COLOR_BLACK) ; |
SET PIXEL
| PROTOTYPE | void PAL_setPixel(char x, char y, unsigned char mode) |
| PARAMETERS | x : pixel column, from 0 to 127 y : pixel row, from 0 to the number of lines - 1 mode : pixel color, either PAL_COLOR_BLACK, PAL_COLOR_WHITE or PAL_COLOR_REVERSE |
| RETURNS | nothing |
| DESCRIPTION | set the color of the pixel located a column x, row y |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_setPixel(10, 20, PAL_COLOR_REVERSE) ; |
draw a line
| PROTOTYPE | void PAL_line(char x0, char y0, char x1, char y1, unsigned char mode) |
| PARAMETERS | x0, y0 : column and row of the start of the line x1, y1 : column and row of the end of the line mode : pixel color, either PAL_COLOR_BLACK, PAL_COLOR_WHITE or PAL_COLOR_REVERSE |
| RETURNS | nothing |
| DESCRIPTION | draw a line from (x0, y0) to (x1, y1) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_line(0, 0, 127, 127, PAL_COLOR_WHITE) ; |
| PROTOTYPE | void PAL_circle(char x, char y, char r, unsigned char mode) |
| PARAMETERS | x : column of the center of the circle y : row of the center of the circle r : radius of the circle mode : pixel color, either PAL_COLOR_BLACK, PAL_COLOR_WHITE or PAL_COLOR_REVERSE |
| RETURNS | nothing |
| DESCRIPTION | draw a circle of radius r centered at (x, y) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_circle(30, 30, 5, PAL_COLOR_WHITE) ; |
DRAW A SOLID BOX
| PROTOTYPE | void PAL_box(char x0, char y0, char x1, char y1, unsigned char mode) |
| PARAMETERS | x0, y0 : top left of the box x1, y1 : bottom right of the box mode : pixel color, either PAL_COLOR_BLACK, PAL_COLOR_WHITE or PAL_COLOR_REVERSE |
| RETURNS | nothing |
| DESCRIPTION | fill a rectangle from corner (x0, y0) to corner (x1, y1) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_box(10, 10, 30, 30, PAL_COLOR_WHITE) ; |
draw a rectangle
| PROTOTYPE | void PAL_rectangle(char x0, char y0, char x1, char y1, unsigned char pcolor) |
| PARAMETERS | x0, y0 : top left of the rectangle x1, y1 : bottom right of the rectangle mode : pixel color, either PAL_COLOR_BLACK, PAL_COLOR_WHITE or PAL_COLOR_REVERSE |
| RETURNS | nothing |
| DESCRIPTION | draw a rectangle from corner (x0, y0) to corner (x1, y1) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_rectangle(10, 10, 30, 30, PAL_COLOR_WHITE) ; |
draw a character
| PROTOTYPE | void PAL_char(unsigned char x, unsigned char y, unsigned char c, unsigned char size) |
| PARAMETERS | x : pixel column of the top left position of the character, from 0 to 127 y : pixel row of the character, from 0 to number of vertical pixels c : ASCII code of the char size : high nibble is height multiplier, low nibble is width multiplier predefined sizes : PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE |
| RETURNS | nothing |
| DESCRIPTION | draw char c at (x, y), always in white on black (use PAL_box() to reverse video) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_char(3, 5, 'A', PAL_CHAR_DSIZE) ; |
DRAW A STRING
| PROTOTYPE | void PAL_write(unsigned char lig, unsigned char col, unsigned char *s, unsigned char size) |
| PARAMETERS | lig : text line of the string col : text column of the string s : pointer to the string (NULL terminated) size : high nibble is height multiplier, low nibble is width multiplier predefined sizes : PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE |
| RETURNS | nothing |
| DESCRIPTION | write string s at position (lig, col) |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_write(0, 5, myString, PAL_CHAR_STANDARD) ; |
DRAW a CONSTANT STRING
| PROTOTYPE | void PAL_constWrite(unsigned char lig, unsigned char col, const unsigned char *s, unsigned char size) |
| PARAMETERS | lig : text line of the string col : text column of the string s : pointer to the constant string (NULL terminated) size : high nibble is height multiplier, low nibble is width multiplier predefined sizes : PAL_CHAR_STANDARD, PAL_CHAR_DWIDTH, PAL_CHAR_DHEIGHT, PAL_CHAR_DSIZE |
| RETURNS | nothing |
| DESCRIPTION | same as PAL_write(), but s is a string located in ROM |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_write(0, 5, myConstantString, PAL_CHAR_STANDARD) ; |
DRAW A PICTURE
| PROTOTYPE | void PAL_picture(unsigned char x, unsigned char y, const unsigned char *bm, unsigned char sx, unsigned char sy) |
| PARAMETERS | x : top left pixel column of the picture y : top left pixel row of the picture bm : pointer to a bitmap picture in ROM sx : width of the picture sy : height of the picture |
| RETURNS | nothing |
| DESCRIPTION | draw the picture pointed to by bm at position (x, y) bitmap is arranged as a monochrome bitmap, use mikroElektronika GLCD bitmap editor and select T6963 to convert bitmap into source code |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | PAL_picture(0, 0, pict, 128, 128) ; |
VIDEO ROUTINE
| PROTOTYPE | void PAL_ISR() |
| PARAMETERS | none |
| RETURNS | nothing |
| DESCRIPTION | this function must not be called directly by user, but must be placed within the interrupt() function.Warning : other interrupts may cause bad video synchronization if they are enabled. |
| REQUIRES | PAL_init() must have been called |
| EXAMPLE | void interrupt(void) { PAL_ISR() ; } |
The core of the circuit is a PIC18F4620 :
C1, C3 and C4 are decoupling capacitors
The PIC is clocked with a 8 Mhz crystal
D1 is used as temperature sensor connected to PIC ADC
Video signal is mixed through R8 and R9
Switches with pull-downs are used for settings
You can connect the video out signal directly to the composite video input of your TV.
For more Detail: PIC PAL Video Library using pic18f4620
-
Which PIC family is compatible with this library?
The library is designed specifically for the PIC18 family because it requires sufficient RAM to map the video screen. -
What clock speed is required for the microcontroller?
The device must be clocked at 32 Mhz using an 8 Mhz crystal to achieve the correct 64 µs horizontal synchronization timing. -
How can I generate a 625 line interlaced signal?
The library automatically generates a 625 lines interlaced PAL video signal when initialized correctly. -
Can I display more than 128 vertical lines?
No, the library can only display up to 128 vertical lines of 128 pixels due to memory constraints. -
Does the library use standard C or assembly?
The video generation part uses in-line assembly mixed with C because timing is critical. -
Which hardware components are needed for the DAC?
A 2-resistor ladder consisting of resistors R8 and R9 is used as a fast and cheap digital to analog converter. -
How do I stop the video generation to save power?
You can call PAL_control with PAL_CNTL_STOP to stop the synchro and free MCU power. -
Where should the PAL_ISR function be placed?
This function must be placed within the interrupt() function and should not be called directly by the user.
Related projects
Converting a Proxxon MF70 Milling Machine To CNC – 2 using PIC18F4620
My layout is shown below. It may not be as intuitive or informative as the layout on a PC display, but contains...
Audio, Sound & Radio · PIC18F4620MIDI Chord Button Keyboard Using PIC18F4620 part 3
Connections The following table documents the connecting leads and molex pin-header numbers tying the various interfaces together. Other connectors are documented on...
Audio, Sound & Radio · PIC18F4620MIDI Chord Button Keyboard Using PIC18F4620 part 2
How chords are formed Before discussing the processor board and software, it is worth mentioning how the chords are composed. I have...
LCD & Display ProjectsLeveraging Blockout Banners for Effective Electronics and Tech Product Displays
Blockout banners have become a popular and effective tool for displaying electronics and tech products in various settings, from trade shows and...
LCD & Display Projects · PIC18F4520Interfacing PIC18F4520 microcontroller with an HD44780 LCD
Introduction Being able to display data from a microcontroller visually has many advantages. It allows for menus, status indicators, and instructions to...
LCD & Display ProjectsVideo Project Development in the Midst of an Impromptu Online Semester
Receiving robot parts in the mail was an unexpected conclusion to the Winter 2020 semester for students. However, when faced with a...
