Did you ever need to display some informations on your TV screen, for your home application project for example ? But you gave up, because the hardware and software involved in this kind of project is not easy to operate.
This time is over ! This page will show you, how to turn a PIC18 into a B&W Text & Graphics PAL video processor with a very few and inexpensive hardware, and a minimum of coding effort !
See also my tiny PIC PAL composite video superimposer
Page index :
WHY A PIC PAL LIBRARY ?
If you are into PICs, you maybe tried one day or another to build a software video processor, either for fun or for a project. If you tried to generate video signals, you surely know some of this web pages :
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.
I kept the idea to use a 2-resistor ladder as a fast and cheap digital to analog converter, and started to work on the software.
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 have
Warnings :
- this library takes control of TIMER 0 and associated interrupts !
- this library takes control of the PORTD !
|
REQUIRES |
the file PAL_library.h must 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 generation
when 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) ; |
FILL SCREEN
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) ; |
DRAW A CIRCLE
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() ; } |
CIRCUIT EXAMPLE
Click on the picture to enlarge
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.
PROGRAM EXAMPLE
This program example shows you most of the features of the PIC PAL Library.
On a PIC18F4620, it uses 25% of the ROM and 55% of the RAM only !
The first screen of the program example is a 128x128 picture with a blinking border
The program waits for the key RB7 to be pressed and then goes to the second screen
The second screen is a calendar clock with temperature. The time is displayed both as digital and graphic clock.
Press RB0 to change minutes, RB1 to change hours, RB2 to change month day, RB3 to change month, RB4 to change year. Press RB5 to adjust temperature. Press RB7 at the same time to decrement values, instead of to increment.
MIKROC SOURCE CODE EXAMPLE
Here is the mikroC source code of the program example. You have to use the zipped mikroC project to build it.
This program shows how to use the new mikroC time library too, very usefull to build rapidly clocks & calendars !
/*
* file : PALdemo.c
* project : PIC PAL SOFTWARE VIDEO GENERATOR DEMO
* author : Bruno Gavand
* compiler : mikroC V6.2
* date : January 17, 2006
*
* description :
* This program displays a clock, a calendar and the temperature on a TV screen
* and shows how to use the PIC PAL library.
* press RB7 to skip the welcome screen
* to adjust clock and calendar, press :
* RB0 to adjust minute
* RB1 to adjust hour
* RB2 to adjust day
* RB3 to adjust month
* RB4 to adjust year
* RB5 to adjust temperature
* press RB7 at the same time to decrement.
*
* target device :
* PIC18F4620 @ 32 Mhz (8 Mhz crystal + HS PLL)
*
* Licence :
* Feel free to use this source code at your own risks.
*
* history :
* created january 2007
*
* see more details on http://www.micro-examples.com/
*/
#include "PAL_Library.h"
#include "pictures.h"
/*************
* DEFINITIONS
*************/
/*
* graphic clock
*/
#define CLK_CENTER_X 90 // center
#define CLK_CENTER_Y 60
#define CLK_RADIUS_PSS 28 // clock radius
#define CLK_RADIUS_SS 25 // seconds
#define CLK_RADIUS_MN 20 // minutes
#define CLK_RADIUS_HH 15 // hours
#define DEG_NBHISTO 16 // number of temperature samples
/*
* number of vertical pixels
* from 1 to 128 included
* the more pixels you have :
* - the less RAM you have
* - the less MCU time you have
*/
#define PAL_Y 128
/*
* simple time structure definition
*/
typedef struct
{
unsigned char ss ; // seconds
unsigned char mn ; // minutes
unsigned char hh ; // hours
unsigned char md ; // day in month, from 1 to 31
unsigned char wd ; // day in week, monday=0, tuesday=1, .... sunday=6
unsigned char mo ; // month number, from 1 to 12 (and not from 0 to 11 as with unix C time !)
unsigned int yy ; // year Y2K compliant, from 1892 to 2038
} TimeStruct ;
/********************
* ROM CONSTANTS
********************/
/*
* month names
*/
const unsigned char monthStr[13][4] =
{
"???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
} ;
/*
* day of week names
*/
const unsigned char wDaystr[7][4] =
{
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
} ;
/********************
* RAM VARIABLES
********************/
/*
* screen memory map
* do not change this line !
*/
unsigned char PAL_screen[PAL_X * PAL_Y / 8] ;
/*
* general purpose string
*/
unsigned char str[20] ;
char degRef ; // DAC temperature reference
char degHisto[DEG_NBHISTO] ; // temperature samples buffer
char tIdx = 0 ; // temperature samples index
unsigned long secOffset = 0 ; // reference timestamp
unsigned long oldCtr = 0 ; // frame counter backup
TimeStruct ts ; // time struct
/*************************
* FUNCTIONS
*************************/
/*
* adjust time struct member
*/
void adjust(unsigned char *v, unsigned char min, unsigned char max)
{
if(PORTB.F7)
{
if(*v == min) *v = max ;
else (*v)-- ;
}
else
{
if(*v == max) *v = min ;
else (*v)++ ;
}
}
/*
* convert value v into string pointed to by p, leading zero blanks if blk is set
*/
void char2str(unsigned char *p, unsigned char v, unsigned char blk)
{
*p = v / 10 + '0' ;
if(blk && (*p == '0'))
{
*p = ' ' ;
}
p++ ;
*p = v % 10 + '0' ;
p++ ;
*p = 0 ;
}
/*
* draw screen with decoration if full is set, using video mode mode
*/
void drawScreen(unsigned char full, unsigned char mode)
{
static unsigned char osx = CLK_CENTER_X, osy = CLK_CENTER_Y,
omx = CLK_CENTER_X, omy = CLK_CENTER_Y,
ohx = CLK_CENTER_X, ohy = CLK_CENTER_Y ;
unsigned int i ;
int t ;
unsigned char ss ;
unsigned char sx, sy, mx, my, hx, hy ;
PAL_control(PAL_CNTL_START, mode) ;
if(full) // draw full screen with decoration
{
PAL_fill(0) ;
PAL_constWrite( 0, 0, "\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB", PAL_CHAR_STANDARD) ;
PAL_constWrite( 1, 0, "\xBA PAL LIBRARY DEMO \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 2, 0, "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC", PAL_CHAR_STANDARD) ;
PAL_box(0, 0, 127, 21, PAL_COLOR_REVERSE) ;
PAL_constWrite( 3, 0, "\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCB\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB", PAL_CHAR_STANDARD) ;
PAL_constWrite( 4, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 5, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 6, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 7, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 8, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite( 9, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite(10, 0, "\xBA \xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite(11, 0, "\xCC\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCA\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xB9", PAL_CHAR_STANDARD) ;
PAL_constWrite(12, 0, "\xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite(13, 0, "\xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite(14, 0, "\xBA \xBA", PAL_CHAR_STANDARD) ;
PAL_constWrite(15, 0, "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC", PAL_CHAR_STANDARD) ;
PAL_write(4, 3, "H :", PAL_CHAR_DHEIGHT) ;
PAL_constWrite(12, 3, "TEMP. : ", 0x31) ;
PAL_constWrite(12, 17, "\xf8C", 0x31) ;
for(ss = 0 ; ss < 60 ; ss++)
{
sx = CLK_CENTER_X - (cosE3(90 + 6 * ss) * CLK_RADIUS_PSS) / 1000 ;
sy = CLK_CENTER_Y - (sinE3(90 + 6 * ss) * CLK_RADIUS_PSS) / 1000 ;
PAL_setPixel(sx, sy, PAL_COLOR_WHITE) ;
if((ss % 5) == 0)
{
PAL_setPixel(sx + 1, sy, PAL_COLOR_WHITE) ;
PAL_setPixel(sx - 1, sy, PAL_COLOR_WHITE) ;
PAL_setPixel(sx, sy + 1, PAL_COLOR_WHITE) ;
PAL_setPixel(sx, sy - 1, PAL_COLOR_WHITE) ;
}
}
}
if(PAL_frameCtr > OldCtr) // it's time to update the clock & calendar
{
unsigned char h ;
oldCtr = PAL_frameCtr + 24 ; // prepare oldCtr for next update time
Time_EpochToDate(secOffset + PAL_frameCtr / 25, &ts) ; // convert timestamp to date and time
/*
* draw analog clock
*/
sx = CLK_CENTER_X - (cosE3(90 + 6 * ts.ss) * CLK_RADIUS_SS) / 1000 ;
sy = CLK_CENTER_Y - (sinE3(90 + 6 * ts.ss) * CLK_RADIUS_SS) / 1000 ;
mx = CLK_CENTER_X - (cosE3(90 + 6 * ts.mn) * CLK_RADIUS_MN) / 1000 ;
my = CLK_CENTER_Y - (sinE3(90 + 6 * ts.mn) * CLK_RADIUS_MN) / 1000 ;
h = (ts.hh % 12) * 5 + (ts.mn / 8) ;
hx = CLK_CENTER_X - (cosE3(90 + 6 * h) * CLK_RADIUS_HH) / 1000 ;
hy = CLK_CENTER_Y - (sinE3(90 + 6 * h) * CLK_RADIUS_HH) / 1000 ;
if((hx != ohx) || (hy != ohy))
{
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, ohx, ohy, PAL_COLOR_BLACK) ;
}
if((mx != omx) || (my != omy))
{
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, omx, omy, PAL_COLOR_BLACK) ;
}
if((sx != osx) || (sy != osy))
{
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, osx, osy, PAL_COLOR_BLACK) ;
}
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, hx, hy, PAL_COLOR_WHITE) ;
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, mx, my, PAL_COLOR_WHITE) ;
PAL_line(CLK_CENTER_X, CLK_CENTER_Y, sx, sy, PAL_COLOR_WHITE) ;
/*
* print date and time
*/
char2str(str, ts.ss, 0) ;
PAL_write(4, 7, str, PAL_CHAR_DHEIGHT) ;
char2str(str, ts.mn, 0) ;
PAL_write(4, 4, str, PAL_CHAR_DHEIGHT) ;
char2str(str, ts.hh, 1) ;
PAL_write(4, 1, str, PAL_CHAR_DHEIGHT) ;
PAL_constWrite(6, 2, wdayStr[ts.wd], PAL_CHAR_STANDARD) ;
PAL_constWrite(7, 2, monthStr[ts.mo], PAL_CHAR_DHEIGHT) ;
char2str(str, ts.md, 1) ;
PAL_write(6, 5, str, 0x32) ;
wordToStr(ts.yy, str) ;
PAL_write(9, 1, str + 1, PAL_CHAR_DSIZE) ;
/*
* save old value for fast analog clock cleaning at next update
*/
osx = sx ;
osy = sy ;
omx = mx ;
omy = my ;
ohx = hx ;
ohy = hy ;
t = degRef - Adc_Read(4) ; // read temperature sensor
t *= 221 ; // temperature coefficient of the silicon junction
t /= 102 ;
t = 25 + t ; // get the result in celcius
/*
* adjust limits
*/
if(t < -99)
{
t = -99 ;
}
if(t > 99)
{
t = 99 ;
}
/*
* average values
*/
degHisto[tIdx] = t ;
tIdx++ ;
if(tIdx == DEG_NBHISTO)
{
tIdx = 0 ;
}
t = 0 ;
for(i = 0 ; i < DEG_NBHISTO ; i++)
{
t += degHisto[i] ;
}
t /= DEG_NBHISTO ;
/*
* print temperature
*/
if(t < 0)
{
i = -t ;
PAL_constWrite(12, 11, "-", 0x31) ;
}
else
{
i = t ;
PAL_constWrite(12, 11, " ", 0x31) ;
}
char2str(str, i, 1) ;
PAL_write(12, 12, str, 0x32) ;
}
PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER) ; // restore video rendering if it was stopped
}
/*
* interrupt service routine
*/
void interrupt(void)
{
/*
* do PAL stuff
*/
PAL_ISR() ; // library call
}
/*
* main program
*/
void main(void)
{
unsigned char i ;
/*
* I/O configuration
*/
ADCON1 = 0x0f ;
TRISA = 0xff ;
PORTA = 0 ;
TRISB = 0xff ;
PORTB = 0 ;
TRISC = 0xff ;
PORTC = 0 ;
TRISD = 0 ;
PORTD = 0 ;
TRISE = 0 ;
PORTE = 0 ;
degRef = EEPROM_read(0) ; // get temperature calibration from EEPROM
/*
* default time and date
*/
ts.ss = 0 ;
ts.mn = 0 ;
ts.hh = 12 ;
ts.md = 1 ;
ts.mo = 1 ;
ts.yy = 2007 ;
secOffset = Time_dateToEpoch(&ts) ;
/*
* start video and display first screen
*/
PAL_init(PAL_Y) ; // init PAL library
PAL_fill(0) ; // clear screen
PAL_picture(0, 0, logo_bmp, 128, 128) ; // paint picture
PAL_control(PAL_CNTL_START, PAL_CNTL_RENDER) ; // start video and rendering
i = 0 ;
while(PORTB == 0) // wait for a key to be pressed
{
/*
* change border color two times per second
*/
if(PAL_frameCtr > 12)
{
PAL_setBorder(i) ;
i = !i ;
PAL_frameCtr = 0 ;
}
}
PAL_setBorder(PAL_COLOR_BLACK) ; // clear border
drawScreen(1, PAL_CNTL_BLANK) ; // draw full screen in blank mode (faster)
for(;;)
{
if(PORTB & 0b1111111) // a key is pressed
{
Time_EpochToDate(secOffset + PAL_frameCtr / 25, &ts) ;
/*
* calendar settings
*/
if(PORTB.F0)
{
adjust(&ts.mn, 0, 59) ;
ts.ss = 0 ;
}
if(PORTB.F1)
{
adjust(&ts.hh, 0, 59) ;
ts.ss = 0 ;
}
if(PORTB.F2)
{
adjust(&ts.md, 1, 31) ;
}
if(PORTB.F3)
{
adjust(&ts.mo, 1, 12) ;
}
if(PORTB.F4)
{
if(PORTB.F7) ts.yy-- ; else ts.yy++ ;
}
secOffset = Time_dateToEpoch(&ts) ; // new timestamp
/*
* temperature calibration
*/
if(PORTB.F5)
{
if(PORTB.F7)
{
degRef-- ;
EEPROM_write(0, degref) ;
}
else
{
degRef++ ;
EEPROM_write(0, degref) ;
}
}
while(PORTB & 0b1111111) ; // wait for the key to be released
PAL_frameCtr = 0 ; // reset counters
oldCtr = 0 ;
}
drawScreen(0, PAL_CNTL_RENDER) ; // update screen
}
}
|
PROJECT DOWNLOAD
You can use this software as you wish, if you accept to do it at your own risks.
Download PIC PAL Library with demo example for mikroC : zipped file, 29.64 Ko
content of the archive :
- PAL_library.c, 37 Ko : library C source code
- PAL_library.h, 2 Ko : library C definitions
- PALdemo.c, 15 Ko : demo example C source code
- PALdemo.eed, 1 Ko : PIC EEPROM definition
- PALdemo.hex, 46 Ko : demo example HEX file for PIC18F4620
- PALdemo.ppc, 2 Ko : mikroC project file
- pictures.h, 9 Ko : demo example picture bitmap
You can get mikroC from here : http://www.mikroe.com/en/compilers/mikroc/pic/
Please report any bug, comment or suggestion in my forums. Thanks !
|