⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paldemo.c

📁 Pal Signal generation with 8-Bit microcontroller. PIC18F4620
💻 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 + -