/*********************************************************************************
* 【編寫時間】: 2020年7月3日
* 【作 者】: march
* 【版 本】: 1.0
* 【外部晶振】: 12mhz
* 【主控芯片】: STC89C52RC
* 【編譯環境】: Keil μVisio4
* 【程序功能】: 12864液晶顯示倒計時報警
* 【使用說明】:
液晶引腳定義
sbit rs=P1^4;
sbit E=P1^2;
sbit CS1=P1^1;
sbit CS2=P1^0;
sbit RW=P1^3;
sbit key1 = P3^1; 選擇
sbit key2 = P3^2; =
sbit key3 = P3^3; -
sbit bj = P3^0; 輸出
E_display_R(頁,列,字庫);
E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
E_display_L(3,2*8,19);//冒號
E_display_L(3,3*8,min/10);//分若變化則重新寫入
E_display_L(3,4*8,min%10);//分若變化則重新寫入
E_display_L(3,5*8,19);//冒號
E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
C_display_L(1,3*8,1); 輸出字符
取字模軟件選項(陰碼、逆向、列行式)
**********************************************************************************/
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
倒計時.jpg (1.16 MB, 下載次數: 55)
下載附件
倒計時
2020-9-25 09:29 上傳
單片機源程序如下:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define PAGEADD 0xb8 //設置起始頁10111xxx 轉換后0xb8
- #define TIERADD 0x40
- #define rsS_STARADD 0xc0
- #define _nop {}
- //液晶引腳定義
- sbit rs=P1^4; //rs
- sbit E=P1^2; //e
- sbit CS1=P1^1;
- sbit CS2=P1^0;
- sbit RW=P1^3; //rw
- sbit key1 = P3^1;
- sbit key2 = P3^2;
- sbit key3 = P3^3;
- sbit bj = P3^0;
- uchar key1num,count,hour,min,sec;
- /*****************************
- 字符表
- 顯示"Welcome Use"
- ******************************/
- uchar code table1[]={
- 0x00,0x3e,0x51,0x49,0x45,0x3e,0x00,0x00,//0(0)
- 0x00,0x00,0x42,0x7f,0x40,0x00,0x00,0x00,//1
- 0x00,0x42,0x61,0x51,0x49,0x46,0x00,0x00,//2
- 0x00,0x21,0x41,0x45,0x4b,0x31,0x00,0x00,//3
- 0x00,0x18,0x14,0x12,0x7f,0x10,0x00,0x00,//4
- 0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00,//5
- 0x00,0x3c,0x4a,0x49,0x49,0x30,0x00,0x00,//6
- 0x00,0x01,0x01,0x79,0x05,0x03,0x00,0x00,//7
- 0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00,//8
- 0x00,0x06,0x49,0x49,0x29,0x1e,0x00,0x00,//9
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// (10)
- 0x00,0x00,0x00,0x47,0x00,0x00,0x00,0x00,//!
- 0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00,//%
- 0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00,//&
- 0x00,0x14,0x08,0x3e,0x08,0x14,0x00,0x00,//*
- 0x00,0x08,0x08,0x3e,0x08,0x08,0x00,0x00,//+
- 0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,//-
- 0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00,//.
- 0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00,///
- 0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00,//:(19)
- 0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00,//=
- 0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00,//?
- };
- /****************************
- 中文字符表
- 顯示"歡迎使用液晶模塊"
- *****************************/
- uchar code table2[]={
- /*0x14,0x24,0x44,0x84,0x64,0x1c,0x20,0x18,
- 0x0f,0xe8,0x08,0x08,0x28,0x18,0x08,0x00,
- 0x20,0x10,0x4c,0x43,0x43,0x2c,0x20,0x10,
- 0x0c,0x03,0x06,0x18,0x30,0x60,0x20,0x00,//歡(0)
- 0x40,0x41,0xce,0x04,0x00,0xfc,0x04,0x02,
- 0x02,0xfc,0x04,0x04,0x04,0xfc,0x00,0x00,
- 0x40,0x20,0x1f,0x20,0x40,0x47,0x42,0x41,
- 0x40,0x5f,0x40,0x42,0x44,0x43,0x40,0x00,//迎(1)
- */
- 0x80,0x60,0xF8,0x07,0x04,0x64,0x5C,0xC4,0x64,0x44,0x00,0xF8,0x00,0xFF,0x00,0x00,
- 0x00,0x00,0xFF,0x00,0x20,0x62,0x22,0x1F,0x12,0x12,0x00,0x4F,0x80,0x7F,0x00,0x00,/*"倒",0*/
- /* (16 X 16 , 宋體 )*/
- 0x40,0x40,0x42,0xCC,0x00,0x40,0x40,0x40,0x40,0xFF,0x40,0x40,0x40,0x40,0x40,0x00,
- 0x00,0x00,0x00,0x7F,0x20,0x10,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,/*"計",1*/
- /* (16 X 16 , 宋體 )*/
- 0x00,0xFC,0x84,0x84,0x84,0xFC,0x00,0x10,0x10,0x10,0x10,0x10,0xFF,0x10,0x10,0x00,
- 0x00,0x3F,0x10,0x10,0x10,0x3F,0x00,0x00,0x01,0x06,0x40,0x80,0x7F,0x00,0x00,0x00,/*"時",2*/
- /* (16 X 16 , 宋體 )*/
- };
- /*延時函數*/
- void delay(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=114;j>0;j--);
- }
- /*****************************************
- DEM12864B狀態檢測,從EDM12864B讀出數
- 據檢測標志位BF
- ******************************************/
- void LCD_Busy()
- {
- uchar busy;
- E=0;
- rs=0;
- RW=1;
- while(1)
- {
- E=1;
- _nop;
- busy=P2;//讀狀態標志寄存器
- _nop;
- E=0;
- if((busy&0x90)==0)//檢測BF和RES位,兩者都為零時表示可進行寫入
- break;
- };
- }
- /*1602液晶*/
- //寫命令
- void WRCommand_L(uchar command)
- {
- CS1=1;
- CS2=0;
- LCD_Busy();
- rs=0;
- _nop;
- RW=0;
- _nop;
- E=1;
- _nop;
- P2=command;
- _nop;
- E=0;
- _nop;
- }
- void WRCommand_R(uchar command)
- {
- CS1=0;
- CS2=1;
- LCD_Busy();
- rs=0;
- _nop;
- RW=0;
- _nop;
- E=1;
- _nop;
- P2=command;
- _nop;
- E=0;
- _nop;
- }
- //寫數據
- void WRdata_L(uchar ucdata)
- {
- CS1=1;
- CS2=0;
- LCD_Busy();
- rs=1;
- _nop;
- RW=0;
- _nop;
- E=1;
- _nop;
- P2=ucdata;
- _nop;
- E=0;
- _nop;
- }
- void WRdata_R(uchar ucdata)
- {
- CS1=0;
- CS2=1;
- LCD_Busy();
- rs=1;
- _nop;
- RW=0;
- _nop;
- E=1;
- _nop;
- P2=ucdata;
- _nop;
- E=0;
- _nop;
- }
- /****************************************************
- 字符為16*16顯示,分為兩個部分寫入32個字節
- 前16個字節寫入第一頁(16*8),后16個字節寫入
- 第二頁(16*8)
- 左側寫入"歡迎",右側寫入"使用"
- *****************************************************/
- C_display_L(uchar C_Pagenum,uchar C_Tiernum,uchar C_Temp) // PAGEADD 0xb8
- { //TIERADD 0x40
- uchar k;
- C_Pagenum=PAGEADD+C_Pagenum; //0xb8| 1
- C_Tiernum=TIERADD+C_Tiernum; //0x40| a*16 a=0 1 2 3 4
- WRCommand_L(C_Pagenum);
- WRCommand_L(C_Tiernum);
- for(k=0;k<16;k++)
- {
- WRdata_L(table2[C_Temp*32+k]);
- };
- C_Pagenum=C_Pagenum+1;
- WRCommand_L(C_Pagenum);
- WRCommand_L(C_Tiernum);
- for(k=0;k<16;k++)
- {
- WRdata_L(table2[C_Temp*32+k+16]);
- };
- }
- C_display_R(uchar C_Pagenum,uchar C_Tiernum,uchar C_Temp)
- {
- uchar k;
- C_Pagenum=PAGEADD|C_Pagenum;
- C_Tiernum=TIERADD|C_Tiernum;
- WRCommand_R(C_Pagenum);
- WRCommand_R(C_Tiernum);
- for(k=0;k<16;k++)
- {
- WRdata_R(table2[C_Temp*32+k]);
- };
- C_Pagenum=C_Pagenum+1;
- WRCommand_R(C_Pagenum);
- WRCommand_R(C_Tiernum);
- for(k=0;k<16;k++)
- {
- WRdata_R(table2[C_Temp*32+k+16]);
- };
- }
- /****************************************
- 寫入西文字符,共11個字符,左側寫入6個
- 右側寫入5個,左側起始從16開始,右側從
- 0開始
- *****************************************/
- E_display_L(uchar E_Pagenum,uchar E_Tiernum,uchar E_Temp)
- {
- uchar k;
- WRCommand_L(PAGEADD|E_Pagenum);
- WRCommand_L(TIERADD|E_Tiernum);
- for(k=0;k<8;k++)
- {
- WRdata_L(table1[E_Temp*8+k]);
- };
- }
- E_display_R(uchar E_Pagenum,uchar E_Tiernum,uchar E_Temp)
- {
- uchar k;
- // WRCommand_R(PAGEADD|E_Pagenum);
- // WRCommand_R(TIERADD|E_Tiernum);
- for(k=0;k<8;k++)
- {
- WRdata_R(table1[E_Temp*8+k]);
- };
- }
- //////////////////////////////////////////////////////////////////////////////
- /*********************************
- 清除所有顯示RAM內容
- **********************************/
- CLR_displayRAM()
- {
- uchar C_page,i,k;
- for(i=0;i<8;i++)
- {
- C_page=PAGEADD|i;//清除起始頁為0
- WRCommand_L(C_page);//清除起始頁寫入
- WRCommand_L(TIERADD);//清除起始行地址寫入
- WRCommand_R(C_page);
- WRCommand_R(TIERADD);
- for(k=0;k<64;k++)
- {
- WRdata_L(0x00);
- WRdata_R(0x00);//lcm的ram自動加一,只許循環64次即可
- };
- };
- }
- //初始化
- void Init_LCD(void)
- {
- CLR_displayRAM();//清除所有顯示寄存器
- WRCommand_L(rsS_STARADD);
- WRCommand_R(rsS_STARADD);//設置顯示起始行地址
- WRCommand_L(0x3f);
- WRCommand_R(0x3f);//開顯示 3e關顯示
- }
- /*鍵盤掃描函數*/
- void keyscan()//按鍵掃描函數
- {
-
- if(key1==0)
- {
- delay(5);
- if(key1==0)//確認功能鍵被按下
- {
- key1num++;//功能鍵按下次數記錄
- while(!key1);//釋放確認
- if(key1num==1)//第一次被按下時
- {
- TR0=0; //關閉定時器
- E_display_L(3,6*8,20);//秒若變化則重新寫入
- E_display_L(3,7*8,20);
- // write_com(0x80+0x40+7);//光標定位到秒位置
- // write_com(0x0f); //光標開始閃爍
- }
- if(key1num==2)//第二次按下光標閃爍定位到分鐘位置
- {
- E_display_L(3,3*8,20);//秒若變化則重新寫入
- E_display_L(3,4*8,20);
- // write_com(0x80+0x40+4);
- }
- if(key1num==3)//第三次按下光標閃爍定位到小時位置
- {
- E_display_L(3,0*8,20);//秒若變化則重新寫入
- E_display_L(3,1*8,20);
- // write_com(0x80+0x40+1);
- }
- if(key1num==4)//第四次按下
- {
- key1num=0;//記錄按鍵數清零
- // write_com(0x0c);//取消光標閃爍
- E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
- E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
- E_display_L(3,2*8,19);//冒號
- E_display_L(3,3*8,min/10);//分若變化則重新寫入
- E_display_L(3,4*8,min%10);//分若變化則重新寫入
- E_display_L(3,5*8,19);//冒號
- E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
- E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
- TR0=1; //啟動定時器使時鐘開始走
- }
- }
- }
- if(key1num!=0)//只有功能鍵被按下后,增加和減小鍵才有效
- {
- if(key2==0)
- {
- delay(5);
- if(key2==0)//增加鍵確認被按下
- {
- while(!key2);//按鍵釋放
- if(key1num==1)//若功能鍵第一次按下
- {
- sec++; //則調整秒加1
- if(sec==60)//若滿60后將清零
- sec=0;
- E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
- E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
- // write_sfm(6,sec);//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+7);//顯示位置重新回到調節處
- }
- if(key1num==2)//若功能鍵第二次按下
- {
- min++;//則調整分鐘加1
- if(min==60)//若滿60后將清零
- min=0;
- E_display_L(3,3*8,min/10);//分若變化則重新寫入
- E_display_L(3,4*8,min%10);//分若變化則重新寫入
- // write_sfm(3,min);//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+4);//顯示位置重新回到調節處
- }
- if(key1num==3)//若功能鍵第三次按下
- {
- hour++;//則調整小時加1
- if(hour==24)//若滿24后將清零
- hour=0;
- E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
- E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
- // write_sfm(0,hour);;//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+1);//顯示位置重新回到調節處
- }
- }
- }
- if(key3==0)
- {
- delay(5);
- if(key3==0)//確認減小鍵被按下
- {
- while(!key3);//按鍵釋放
- if(key1num==1)//若功能鍵第一次按下
- {
- sec--;//則調整秒減1
- if(sec==-1)//若減到負數則將其重新設置為59
- sec=59;
- E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
- E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
- // write_sfm(6,sec);//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+7);//顯示位置重新回到調節處
- }
- if(key1num==2)//若功能鍵第二次按下
- {
- min--;//則調整分鐘減1
- if(min==-1)//若減到負數則將其重新設置為59
- min=59;
- E_display_L(3,3*8,min/10);//分若變化則重新寫入
- E_display_L(3,4*8,min%10);//分若變化則重新寫入
- // write_sfm(3,min);//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+4);//顯示位置重新回到調節處
- }
- if(key1num==3)//若功能鍵第二次按下
- {
- hour--;//則調整小時減1
- if(hour==-1)//若減到負數則將其重新設置為23
- hour=23;
- E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
- E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
- // write_sfm(0,hour);//每調節一次送液晶顯示一下
- // write_com(0x80+0x40+1);//顯示位置重新回到調節處
- }
- }
- }
- }
- }
- /*主函數*/
- void main()
- {
- Init_LCD();
- hour=0; //初始化時間
- min=1;
- sec=37;
- count=0;
- C_display_L(1,0*8,0); //倒計時
- C_display_L(1,3*8,1);
- C_display_L(1,6*8,2);
- E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
- E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
- E_display_L(3,2*8,19);//冒號
- E_display_L(3,3*8,min/10);//分若變化則重新寫入
- E_display_L(3,4*8,min%10);//分若變化則重新寫入
- E_display_L(3,5*8,19);//冒號
- E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
- E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
- TMOD=0x01;//設置定時器0工作模式1
- TH0=(65536-50000)/256;//定時器裝初值
- TL0=(65536-50000)%256;
- EA=1; //開總中斷
- ET0=1; //開定時器0中斷
- TR0=1; //啟動定時器0
- while(1)
- { keyscan();
- if(hour==0&min==0&sec==0)
- {
- bj=0;
- EA=0;}
- }
- }
- void timer0() interrupt 1//定時器0中斷服務程序
- {
- TH0=(65536-50000)/256;//再次裝定時器初值
- TL0=(65536-50000)%256;
- count++; //中斷次數累加
- if(count==1) //20次50毫秒為1秒
- {
- count=0;
- sec--;
- if(sec==-1)//秒加到60則進位分鐘
- {
- sec=59;//同時秒數清零
- min--;
- if(min==-1)//分鐘加到60則進位小時
- {
- min=59;//同時分鐘數清零
- hour--;
- if(hour==-1)//小時加到24則小時清零
- {
- hour=23;
- }
- E_display_L(3,0*8,hour/10);//小時若變化則重新寫入
- E_display_L(3,1*8,hour%10);//小時若變化則重新寫入
- }
- E_display_L(3,3*8,min/10);//分變化則重新寫入
- E_display_L(3,4*8,min%10);//分變化則重新寫入
- }
- E_display_L(3,6*8,sec/10);//秒若變化則重新寫入
- E_display_L(3,7*8,sec%10);//秒若變化則重新寫入
- }
- }
復制代碼
51hei.png (15.38 KB, 下載次數: 61)
下載附件
2020-9-25 14:42 上傳
所有資料51hei提供下載:
12864可調倒計時可調顯示okampire12864.rar
(130.72 KB, 下載次數: 27)
2020-9-25 09:30 上傳
點擊文件名下載附件
12864 下載積分: 黑幣 -5
|