- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit BEEP=P3^6;
- sbit RS=P2^0;
- sbit RW=P2^1;
- sbit E=P2^2;
- sbit BF=P0^7;
- uchar code digit[]="0123456789ABCDEF";
- uchar code key_code[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77 };
- uchar code str[]="Input Data:";
- uchar key;
- /************************************
- 函数功能:1ms基准延时
- 入口参数:n
- ************************************/
- void delay1ms(unsigned int n )
- {
- unsigned char i;
- while(n--)
- for(i=0;i<115;i++);
- }
- /************************************
- 函数功能: 500us延时
- ************************************/
- void delay500us()
- {
- uchar i;
- for(i=0;i<57;i++);
- }
- /************************************
- 函数功能: 蜂鸣器产生1KHZ频率声音,
- ************************************/
- void beep()
- {
- uchar i;
- for(i=0;i<200;i++){
- BEEP=~BEEP;
- delay500us();
- }
- BEEP=1;
- }
- /************************************
- 函数功能:判断液晶的忙碌状态
- 返回值:result=1,忙碌;result=0,不忙
- ************************************/
- bit BusyTest()
- {
- bit result;
- RS=0; //读状态时,RS=0,RW=1,E=1
- RW=1;
- E=1;
- _nop_(); //延时一个时钟周期
- _nop_();
- _nop_();
- _nop_(); //4个周期延时,给硬件反应时间
- result=BF;
- E=0; //将E置0,不允许读
- return result;
- }
- /************************************
- 函数功能:将模式设置指令或显示地址送入液晶
- 入口参数:dictate
- ************************************/
- void WriteInstruction(uchar dictate)
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0; //写指令时,RS=0.RW=0,E=负跳变
- RW=0;
- E=0; //先将E拉低
- _nop_();
- _nop_(); //给硬件反应时间
- P0=dictate; //将数据送入P0口,即指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //反应时间
- E=1; //上升沿读入指令或地址
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
- }
- /************************************
- 函数功能:指定字符显示的实际地址
- 入口参数:x
- ************************************/
- void WriteAddress(uchar x)
- {
- WriteInstruction(x|0x80); //显示位置的确定方法为“0x80+地址码x”
- }
- /************************************
- 函数功能:将数据(ASKII码)写入液晶模块
- 入口参数:y(字符常量)
- ************************************/
- void WriteData(unsigned char y)
- {
- while(BusyTest()==1); //如果忙碌就等待
- RS=1; //写数据时RS=1,RW=0,E=负跳变
- RW=0;
- E=0; //先将E拉低
- _nop_();
- _nop_();
- P0=y;
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //反应时间
- E=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
- }
- /************************************
- 函数功能:对LCD的显示模式进行初始化
- ************************************/
- void LcdInt()
- {
- delay1ms(15); //首次写指令时给LCD一段较长的反应时间
- WriteInstruction(0x38); //显示模式设置:16X2显示,5X7点阵,8位数据总线
- delay1ms(5);
- WriteInstruction(0x38);
- delay1ms(5);
- WriteInstruction(0x38);
- delay1ms(5); //3次写 设置模式
- WriteInstruction(0x0c); //显示模式设置:显示开,有光标,光标闪烁
- delay1ms(5);
- WriteInstruction(0x06); //显示模式设置:光标右移,字符不移
- delay1ms(5);
- WriteInstruction(0x01); //清屏
- delay1ms(5);
- }
- /************************************
- 函数功能: 扫描键盘
- ************************************/
- void key_scan()
- {
- uchar scan1,scan2,keycode,i;
- P1=0xf0;
- scan1=P1;
- if((scan1&0xf0)!=0xf0){ //判断是否按键
- delay1ms(15); //延时消陡
- scan1=P1;
- if((P1&0xf0)!=0xf0){ //二次判断是否按键
- P1=0x0f; //线反转法德核心
- scan2=P1;
- keycode=scan1|scan2; //组合成键编码
- }
- for(i=0;i<16;i++){
- if(keycode==key_code[i]){ //查表得键值
- key=i;
- }
- }
- }
- else{
- P1=0xff; //P1口写1,输入状态
- }
-
- }
- /***************************************
- 函数功能:显示数字
- ***************************************/
- void Display()
- {
- WriteAddress(0x47);
- delay1ms(5);
- WriteData(digit[key]);
- }
-
- /***********************************
- 函数功能:主函数
- ***********************************/
- void main()
- {
- uchar i;
- P1=0xff; //写1,读状态
- delay1ms(15);
- LcdInt();
- WriteInstruction(0x01);
- delay1ms(5);
- WriteAddress(0x02);
- delay1ms(5);
- for(i=0;str[i]!='\0';i++){
- WriteData(str[i]);
- delay1ms(10);
- }
-
- WriteAddress(0x47);
- delay1ms(5);
- WriteData('0');
- while(1){
- P1=0xf0;
- if((P1&0xf0)!=0xf0){
- delay1ms(15);
- if((P1&0xf0)!=0xf0){
-
- key_scan();
- Display();
- beep();
- delay1ms(200);
- }
- }
- }
- }
-
复制代码
|