📄 paldemo.c
字号:
/*
* file : PALdemo.c
* project : PIC PAL SOFTWARE VIDEO GENERATOR DEMO
* author : Bruno Gavand
* compiler : mikroC V6.2
* date : January 17, 2006
* updated : April 30, 2008
* minor adjustment for mikroC V8.1
*
* 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
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -