/*********************************************************************************
* 【编写时间】: 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仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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提供下载:
12864可调倒计时可调显示okampire12864.rar
(130.72 KB, 下载次数: 27)
|