4MHz時(shí)鐘--PIC-KIT3。 main.c: #include #include #include "Display.h" #include "main.h" __CONFIG(WDTDIS & LVPDIS & HS & PWRTDIS & BORDIS); //設(shè)置877配置位 /************************定義顯示字符*****************************************/ uchar Welcome_1[] = {" Welcome To Use "}; //uchar Welcome_2[] = {" DSK-27 System !"}; //uchar Power_On1[] = {" Power On "}; //uchar Auto_Mode1[] = {" Automatic Mode "}; uchar Time_Now[] = {"Time Now"}; uchar Time_Now_buf[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; //定義Time Now顯示緩沖單元 uchar hour=8; //定義小時(shí)分鐘和秒變量 uchar min=12; uchar sec=0; uchar count_10ms; //定義10ms計(jì)數(shù)器 /******************************************************************************* * 函 數(shù) 名: Delay_US(uint8 delay) * 函數(shù)功能: 微秒延時(shí)--12us * 入口參數(shù): delay * 返 回: 無(wú) *******************************************************************************/ void Delay_US(uint delay) { for(;delay;) { delay--; } } /******************************************************************************* * 函 數(shù) 名: Delay_MS(uint16 delay) * 函數(shù)功能: 毫秒延時(shí)--1ms * 入口參數(shù): delay * 返 回: 無(wú) *******************************************************************************/ void Delay_Ms(uint delay) { uint i; for(i=0;i<delay;i++) Delay_US(83); } /******************************************************************************* * 函 數(shù) 名: Delay_Sec(uint16 delay) * 函數(shù)功能: 毫秒延時(shí)--1ms * 入口參數(shù): delay * 返 回: 無(wú) *******************************************************************************/ void Delay_Sec(uint delay) { uint i,j; for(i=0;i<20*delay;i++) { for(j=0;j<4536;j++); } } /*********定時(shí)器1初始化**********/ void Timer1_Init(void) { GIE = 1; //開(kāi)總中斷 PEIE = 1; //開(kāi)外圍功能模塊中斷 T1CKPS0=1;T1CKPS1=1; //分頻比為1:8 TMR1CS = 0; //設(shè)置為定時(shí)功能 TMR1IE = 1; //使能TMRI中斷 TMR1ON = 1; //啟動(dòng)定時(shí)器TMR1 TMR1H = 0xfb; //設(shè)置計(jì)數(shù)值高位,定時(shí)時(shí)間為10ms TMR1L = 0x1e; //設(shè)置計(jì)數(shù)值高低位 } /*******中斷服務(wù)函數(shù),用于產(chǎn)生秒、分鐘和小時(shí)信號(hào)*******/ void interrupt ISR(void) { if(TMR1IF==1) { TMR1IF=0; TMR1H = 0xfb; TMR1L = 0x1e; count_10ms++; if(count_10ms>=100) { count_10ms=0; sec++; if(sec==60) { sec=0; min++; if(min==60) { min=0; hour++; if(hour==24) { hour=0;min=0;sec=0; //若到24h,小時(shí)、分鐘和秒單元清零 } } } } } Time_Now_buf[0] = hour/10; //小時(shí)十位數(shù)據(jù)--轉(zhuǎn)換并存儲(chǔ)時(shí)鐘數(shù)據(jù) Time_Now_buf[1] = hour%10; //小時(shí)個(gè)位數(shù)據(jù) Time_Now_buf[2] = min/10; //分鐘十位數(shù)據(jù) Time_Now_buf[3] = min%10; //分鐘個(gè)位數(shù)據(jù) Time_Now_buf[4] = sec/10; //秒鐘十位數(shù)據(jù) Time_Now_buf[5] = sec%10; //秒鐘個(gè)位數(shù)據(jù) } /****************************************************************************** * 函 數(shù) 名: main() * 函數(shù)功能: LCD顯示字符 * 入口參數(shù): 無(wú) * 返 回: 無(wú) *******************************************************************************/ void main() { uchar j=0; Port_1602_Init(); INIT_1602(); TRISA3=0; //RA3和RA5已經(jīng)初始化為普通IO口,此處只需設(shè)定方向,可以作為后續(xù)輸出口使用 TRISA5=0; Delay_Ms(200); Display_1602_string(0,0,16,Welcome_1);//顯示歡迎詞 //Display_1602_string(0,1,16,Welcome_2);//顯示歡迎詞 Delay_Ms(100); Timer1_Init(); Clear_Display(); Display_1602_string(4,0,8,Time_Now); //顯示當(dāng)前時(shí)間xx:xx:xx while(1) { DispNum_XY_1602(4,1,Time_Now_buf[0]); DispNum_XY_1602(5,1,Time_Now_buf[1]); DispChar_XY_1602(6,1,':'); DispNum_XY_1602(7,1,Time_Now_buf[2]); DispNum_XY_1602(8,1,Time_Now_buf[3]); DispChar_XY_1602(9,1,':'); DispNum_XY_1602(10,1,Time_Now_buf[4]); DispNum_XY_1602(11,1,Time_Now_buf[5]); //Clear_Display(); //Display_1602_string(3,0,10,Power_On1); //顯示Power On //Delay_Ms(1000); //Close_Disp(); //Display_1602_string(0,0,15,Auto_Mode1); //Automatic Mode //Open_Disp(); //DispChar_XY_1602(15,1,'L'); //Delay_Ms(1000); } } main.h: #ifndef __MAIN_H__ #define __MAIN_H__ #define uchar unsigned char #define uint unsigned int void Delay_US(uint delay); //12微秒延時(shí) void Delay_Ms(uint delay); //1毫秒延時(shí) void Delay_Sec(uint delay); //1秒延時(shí) void Timer1_Init(void); void interrupt ISR(void); #endif Display.c: #include #include "Display.h" #include "main.h" /******************************************************************************* * 函 數(shù) 名: uchar Chk_1602_busy(void) * 函數(shù)功能: 讀液晶忙通道數(shù)據(jù) * 入口參數(shù): 無(wú) * 返 回: 無(wú) *******************************************************************************/ uchar Chk_1602_busy(void) { uint gR_data; uint gwait_time=0xff; //設(shè)置忙超時(shí)數(shù) LCD_RS=0; //表示狀態(tài) LCD_RW=1; //選擇讀 LCD_EN=1; TRISC = 0xFF; //接收口設(shè)為輸入口 Delay_US(30); gR_data=PORTC; while(TESTBIT(gR_data,7)) //表示busy { --gwait_time; if(!gwait_time) { LCD_EN=0;TRISC = 0x00; return 0; } } LCD_EN=0; TRISC = 0x00; //恢復(fù)為輸出口 return 1; } /****************************************************************************** * 函 數(shù) 名: void Write_1602_command(uchar gcmd,uchar gvalue) * 函數(shù)功能: 寫(xiě)指令 * 入口參數(shù): gcmd--指令 gvalue--是否查忙 * 返 回: 無(wú) *******************************************************************************/ void Write_1602_command(uchar gcmd,uchar gvalue) { if(gvalue) //寫(xiě)命令時(shí)大部分情況下是在LCD空閑模式下寫(xiě) { if(Chk_1602_busy()) { LCD_RS=0; //選擇指令 LCD_RW=0; //選擇寫(xiě) PORTC=gcmd; //賦指令 LCD_EN=1; //使能 Delay_US(30); LCD_EN=0; } } else { LCD_RS=0; //選擇指令 LCD_RW=0; //選擇寫(xiě) PORTC=gcmd; //賦指令 LCD_EN=1; //使能 Delay_US(30); LCD_EN=0; } } /****************************************************************************** * 函 數(shù) 名: void Write_1602_data(uchar gdata) * 函數(shù)功能: 寫(xiě)數(shù)據(jù) * 入口參數(shù): gdata--數(shù)據(jù) * 返 回: 無(wú) *******************************************************************************/ /*----------- 寫(xiě)數(shù)據(jù) -------------*/ void Write_1602_data(uchar gdata) { if(Chk_1602_busy()) //寫(xiě)數(shù)據(jù)必須是在LCD空閑模式下才能寫(xiě) { LCD_RS=1; //選擇數(shù)據(jù) LCD_RW=0; //選擇寫(xiě) PORTC=gdata; LCD_EN=1; //使能 Delay_US(30); LCD_EN=0; Delay_US(10); } } /****************************************************************************** * 函 數(shù) 名: void INIT_1602(void) * 函數(shù)功能: 初始化1602LCD * 入口參數(shù): 無(wú) * 返 回: 無(wú) *******************************************************************************/ /*-----------1602初始化函數(shù)-------------*/ void INIT_1602(void) { Delay_Ms(15); Write_1602_command(0x38,0); //設(shè)置16X2顯示,5X7點(diǎn)陣,8位數(shù)據(jù)傳送,不檢測(cè)忙信號(hào) Delay_Ms(5); Write_1602_command(0x38,0); Delay_Ms(5); Write_1602_command(0x38,0); //設(shè)置16X2顯示,5X7點(diǎn)陣,8位數(shù)據(jù)傳送,不檢測(cè)忙信號(hào) Write_1602_command(0x38,1); //設(shè)置16X2顯示,5X7點(diǎn)陣,8位數(shù)據(jù)傳送,檢測(cè)忙信號(hào) Write_1602_command(0x08,1); //關(guān)閉顯示、無(wú)光標(biāo)、檢測(cè)忙信號(hào) Write_1602_command(0x01,1); //清屏、光標(biāo)歸位、AC=0、檢測(cè)忙信號(hào) Write_1602_command(0x06,1); //顯示光標(biāo)右移位置、檢測(cè)忙信號(hào) Write_1602_command(0x0C,1); //顯示功能開(kāi)、無(wú)光標(biāo) } /****************************************************************************** * 函 數(shù) 名: void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata) * 函數(shù)功能: 顯示字符串 * 入口參數(shù): gadd_start-列號(hào),uchar gline-行號(hào),glength-數(shù)據(jù)長(zhǎng)度,pdata-數(shù)組元素 * 返 回: 無(wú) *******************************************************************************/ /*-----------顯示字符串-------------*/ // 列號(hào) 行號(hào) 數(shù)據(jù)長(zhǎng)度 數(shù)組元素 void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata) { uchar gaddress; uchar *pdat; uchar gcount=0; if(!gline) //第0行 { gaddress=0x80+gadd_start; } //地址對(duì)應(yīng) else { gaddress=0xc0+gadd_start; } //第一行 for(;gcount<glength;gcount++) { Write_1602_command(gaddress,1); //設(shè)定數(shù)據(jù)地址 Write_1602_data(*pdata); //取設(shè)定地址里的數(shù)據(jù) gaddress++; pdata++; } } /****************************************************************************** * 函 數(shù) 名: void Display_1602(uchar x,uchar y,uchar gdata) * 函數(shù)功能: 指定位置顯示字符 * 入口參數(shù): x-起始地址橫坐標(biāo),y-起始地址縱坐標(biāo),gdata-要顯示的字符 * 返 回: 無(wú) *******************************************************************************/ /*-----------指定位置顯示字符-------------*/ void DispChar_XY_1602(uchar x,uchar y,uchar gdata) { uchar gaddress; if(!y) { gaddress=0x80+x; } else { gaddress=0xc0+x; } Write_1602_command(gaddress,1); //設(shè)定數(shù)據(jù)地址 Write_1602_data(gdata); } /*-----------指定位置顯示數(shù)字-------------*/ void DispNum_XY_1602(uchar x,uchar y,uchar gdata) { uchar gaddress; if(!y) { gaddress=0x80+x; } else { gaddress=0xc0+x; } Write_1602_command(gaddress,1); //設(shè)定數(shù)據(jù)地址 Write_1602_data(gdata+0x30); } /*-----------清屏-------------*/ void Clear_Display(void) { Write_1602_command(0x01,1); Delay_Ms(5); } void Open_Disp(void) { Write_1602_command(0x0c,1); } void Close_Disp(void) { Write_1602_command(0x08,1); } /*-----------顯示光標(biāo)-------------*/ void Display_Cursor(void) { Write_1602_command(0x06,1); //顯示光標(biāo)右移位置、檢測(cè)忙信號(hào) Write_1602_command(0x0D,1); //顯示功能開(kāi)、無(wú)光標(biāo) } /*-----------1602端口初始化-------------*/ void Port_1602_Init(void) { ADCON1 = 0x87;//設(shè)置PORTA為普通IO口 TRISA0 = 0; TRISA1 = 0; TRISA2 = 0; TRISC = 0x00;//設(shè)置PORTC為輸出 } Display.h: #ifndef __Display_H__ #define __Display_H__ #define uchar unsigned char #define uint unsigned int #define TESTBIT(a,b) ((a)&(1<<(b))) #defineLCD_RSRA0 #defineLCD_RWRA1 #defineLCD_EN RA2 /************************聲明函數(shù)*********************************************/ uchar Chk_1602_busy(void); void Write_1602_command(uchar gcmd,uchar gvalue); void Write_1602_data(uchar gdata); void INIT_1602(void); void Display_1602_string(uchar gadd_start,uchar gline,uchar glength,uchar *pdata); void DispChar_XY_1602(uchar x,uchar y,uchar gdata); void DispNum_XY_1602(uchar x,uchar y,uchar gdata); void Clear_Display(void); void Open_Disp(void); void Close_Disp(void); void Display_Cursor(void); void Port_1602_Init(void); #endif