矩阵键盘可调闹钟
来源:互联网 发布:周芷若 知乎 编辑:程序博客网 时间:2024/04/30 07:46
#include <reg52.h>#include <intrins.h>#include "i2c.h"sbit RS = P2^4;sbit RW = P2^5;sbit EN = P2^6;#define RS_CLR RS=0 #define RS_SET RS=1#define RW_CLR RW=0 #define RW_SET RW=1 #define EN_CLR EN=0#define EN_SET EN=1#define DataPort P0#define KeyPort P1bit KeyPressFlag;//定义按键标志位unsigned int sec,min,h;unsigned char dat[3] = 0;//unsigned int i;/******************函数声明********************/void LCD_Init(void);void DelayUs2x(unsigned char t);void DelayMs(unsigned char t);void LCD_Write_Com(unsigned char com);bit LCD_Check_Busy(void);void LCD_Write_Data(unsigned char Data);void LCD_Clear(void);void LCD_Write_String(unsigned char x,unsigned char y, unsigned char *s);void LCD_Write_Char(unsigned char x,unsigned char y, unsigned char Data);unsigned char KeyScan(void);//键盘扫描unsigned char KeyPro(void);void Init_INT0(void); //外部中断0初始化/******************中断************************/void ISR_T0(void) interrupt 1{unsigned char j;TH0 = 0X3C;TL0 = 0XB0;j++;if(j == 20){sec++;j = 0;}} /*****************初始化函数*****************/void LCD_Init(void){LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); DelayMs(5); LCD_Write_Com(0x38); LCD_Write_Com(0x08); //显示关闭 LCD_Write_Com(0x01); //显示清屏 LCD_Write_Com(0x06); //显示光标移动设置 DelayMs(5); LCD_Write_Com(0x0C); //显示开及光标设置}/***************us延时函数*******************/void DelayUs2x(unsigned char t) //延时 = 2 * t + 5 us{while(--t);}/**************ms延时函数 ******************/void DelayMs(unsigned char t) //大致延时1ms{while(t--){DelayUs2x(245);DelayUs2x(245);}}/*****************写入命令函数***************/void LCD_Write_Com(unsigned char com){DelayMs(5);RS_CLR;RW_CLR;EN_SET;DataPort = com;_nop_(); //空指令,延时一个指令周期,延时时间为1usEN_CLR;} /****************判忙函数******************/bit LCD_Check_Busy(void){DataPort = 0xFF;RS_CLR;RW_SET;EN_CLR;_nop_();EN_SET;return (bit)(DataPort & 0x80);}/***************写入数据函数****************/void LCD_Write_Data(unsigned char Data){DelayMs(5);RS_SET;RW_CLR;EN_SET;DataPort = Data;_nop_();EN_CLR;} /*****************清屏函数*******************/void LCD_Clear(void){LCD_Write_Com(0X01);DelayMs(5);} /*****************写入字符串函数******************/void LCD_Write_String(unsigned char x,unsigned char y, unsigned char *s){if(y == 0){LCD_Write_Com(0X80 + x);}else{ LCD_Write_Com(0XC0 + x);}while(*s){ LCD_Write_Data(*s); s++;}}/*****************写入字符函数******************/void LCD_Write_Char(unsigned char x,unsigned char y, unsigned char Data){if(y == 0){LCD_Write_Com(0X80 + x);}else{ LCD_Write_Com(0XC0 + x);}LCD_Write_Data(Data);}#define _Nop() _nop_() //定义空指令 bit ack; //应答标志位sbit SDA=P2^1;sbit SCL=P2^0;/***************启动总线******************/void Start_I2c(){SDA=1; //发送起始条件的数据信号 _Nop(); SCL=1; _Nop(); //起始条件建立时间大于4.7us,延时 _Nop(); _Nop(); _Nop(); _Nop(); SDA=0; //发送起始信号 _Nop(); //起始条件锁定时间大于4μ _Nop(); _Nop(); _Nop(); _Nop(); SCL=0; //钳住I2C总线,准备发送或接收数据 _Nop(); _Nop();}/******************结束总线******************/void Stop_I2c(){ SDA=0; //发送结束条件的数据信号 _Nop(); //发送结束条件的时钟信号 SCL=1; //结束条件建立时间大于4μ _Nop(); _Nop(); _Nop(); _Nop(); _Nop(); SDA=1; //发送I2C总线结束信号 _Nop(); _Nop(); _Nop(); _Nop();}/*********************字节数据传送函数**************************/void SendByte(unsigned char c){ unsigned char BitCnt; for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位 { if((c<<BitCnt)&0x80)SDA=1; //判断发送位 else SDA=0; _Nop(); SCL=1; //置时钟线为高,通知被控器开始接收数据位 _Nop(); _Nop(); //保证时钟高电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; } _Nop(); _Nop(); SDA=1; //8位发送完后释放数据线,准备接收应答位 _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); _Nop(); if(SDA==1)ack=0; else ack=1; //判断是否接收到应答信号 SCL=0; _Nop(); _Nop();}/************************字节数据传送函数*************************/unsigned char RcvByte(){ unsigned char retc; unsigned char BitCnt; retc=0; SDA=1; //置数据线为输入方式 for(BitCnt=0;BitCnt<8;BitCnt++) { _Nop(); SCL=0; //置时钟线为低,准备接收数据位 _Nop(); _Nop(); //时钟低电平周期大于4.7us _Nop(); _Nop(); _Nop(); SCL=1; //置时钟线为高使数据线上数据有效 _Nop(); _Nop(); retc=retc<<1; if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中 _Nop(); _Nop(); } SCL=0; _Nop(); _Nop(); return(retc);}/*********************应答子函数*********************/void Ack_I2c(void){SDA=0; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); //时钟低电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; //清时钟线,钳住I2C总线以便继续接收 _Nop(); _Nop(); }/**********************非应答子函数************************/void NoAck_I2c(void){SDA=1; _Nop(); _Nop(); _Nop(); SCL=1; _Nop(); _Nop(); //时钟低电平周期大于4μ _Nop(); _Nop(); _Nop(); SCL=0; //清时钟线,钳住I2C总线以便继续接收 _Nop(); _Nop(); }/******************向有子地址器件发送多字节数据函数************************/bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no){unsigned char i;for(i=0;i<no;i++) { Start_I2c(); //启动总线 SendByte(sla); //发送器件地址 if(ack==0)return(0); SendByte(suba); //发送器件子地址 if(ack==0)return(0); SendByte(*s); //发送数据 if(ack==0)return(0); Stop_I2c(); //结束总线 DelayMs(2); //必须延时等待芯片内部自动处理数据完毕 s++; suba++; } return(1);}/**********************向有子地址器件读取多字节数据函数**********************/bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no){unsigned char i;Start_I2c(); //启动总线 SendByte(sla); //发送器件地址 if(ack==0)return(0); SendByte(suba); //发送器件子地址 if(ack==0)return(0); Start_I2c(); SendByte(sla+1); if(ack==0)return(0); for(i=0;i<no-1;i++) { *s=RcvByte(); //发送数据 Ack_I2c(); //发送就答位 s++; } *s=RcvByte(); NoAck_I2c(); //发送非应位 Stop_I2c(); //结束总线 return(1);}/******************外部中断0初始化*****************/void Init_INT0(void){ EA=1; //全局中断开 EX0=1; //外部中断0开 IT0=1; //边沿触发} /*****************外部中断0程序*******************/void ISR_INT0(void) interrupt 0 { KeyPressFlag=1; //表明按键有动作,可以进行按键扫描}/**************按键扫描函数,返回扫描键值*******************/unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法{ unsigned char Val; KeyPort=0xf0;//高四位置高,低四位拉低 if(KeyPort!=0xf0)//表示有按键按下 { DelayMs(10); //去抖if(KeyPort!=0xf0) { //表示有按键按下 KeyPort=0xfe; //检测第一行if(KeyPort!=0xfe) { Val=KeyPort&0xf0; Val+=0x0e; while(KeyPort!=0xfe); DelayMs(10); //去抖 while(KeyPort!=0xfe); return Val; } KeyPort=0xfd; //检测第二行if(KeyPort!=0xfd) { Val=KeyPort&0xf0; Val+=0x0d; while(KeyPort!=0xfd); DelayMs(10); //去抖 while(KeyPort!=0xfd); return Val; } KeyPort=0xfb; //检测第三行if(KeyPort!=0xfb) { Val=KeyPort&0xf0; Val+=0x0b; while(KeyPort!=0xfb); DelayMs(10); //去抖 while(KeyPort!=0xfb); return Val; } KeyPort=0xf7; //检测第四行if(KeyPort!=0xf7) { Val=KeyPort&0xf0; Val+=0x07; while(KeyPort!=0xf7); DelayMs(10); //去抖 while(KeyPort!=0xf7); return Val; } } } return 0xff;}/*****************按键值处理函数,返回扫键值****************/unsigned char KeyPro(void){ switch(KeyScan()) { case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值 case 0x7d:return 1;break;//1 case 0x7b:return 2;break;//2 case 0x77:return 3;break;//3 case 0xbe:return 4;break;//4 case 0xbd:return 5;break;//5 case 0xbb:return 6;break;//6 case 0xb7:return 7;break;//7 case 0xde:return 8;break;//8 case 0xdd:return 9;break;//9 case 0xdb:return 10;break;//a case 0xd7:return 11;break;//b case 0xee:return 12;break;//c case 0xed:return 13;break;//d case 0xeb:return 14;break;//e case 0xe7:return 15;break;//f default:return 0xff;break; }}/*****************主函数********************/void main(){unsigned char num;Init_INT0();LCD_Init();TMOD = 0X01;TH0 = 0X3C;TL0 = 0xb0;EA = 1;ET0 = 1;TR0 = 1;EX0 = 1;IT0 = 1; IRcvStr(0xae,80,dat,8); sec = dat[0]; min = dat[1];h = dat[2]; while(1){KeyPort=0xf0;if(KeyPressFlag == 1){KeyPressFlag = 0;num = KeyPro();if(num == 0) //调秒{sec++;}if(num == 1) //调分{min++;}if(num == 2) //调秒{h++;}if(num == 4) //暂停{ET0 = ~ET0;}}/////////////////////////秒////////////////////////////LCD_Write_Char(7,0,sec % 10 + '0'); DelayUs2x(2000);LCD_Write_Char(6,0,sec / 10 + '0'); DelayUs2x(2000);if(sec == 60){sec = 0;min++;}dat[0] = sec; /////////////////////////分////////////////////////////LCD_Write_Char(4,0,min % 10 + '0'); DelayUs2x(2000);LCD_Write_Char(3,0,min / 10 + '0'); DelayUs2x(2000);LCD_Write_Char(5,0,':');if(min == 60){min = 0;h++;}dat[1] = min;/////////////////////////时////////////////////////////LCD_Write_Char(1,0,h % 10 + '0'); DelayUs2x(2000);LCD_Write_Char(0,0,h / 10 + '0'); DelayUs2x(2000);LCD_Write_Char(2,0,':');if(h == 24){h = 0;}dat[2] = h;ISendStr(0xae,80,dat,8);}}
0 0
- 矩阵键盘可调闹钟
- 矩阵键盘可调时间,可调闹钟(LCD显示)
- 矩阵键盘可调时钟
- 可调闹钟lcd时钟
- 可调闹钟的时钟
- 数码可调时钟(加闹钟)
- 掉电锁存可调时的电子闹钟
- 单片机==矩阵键盘+时钟+键入时间+闹钟(12)
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- 矩阵键盘
- Spark jdbc postgresql数据库连接和写入操作源码解读
- JAVA 线程安全集合
- 启动redis出现Creating Server TCP listening socket *:6379: bind: No such file or directory
- printf 简单用法
- Java笔试解答题
- 矩阵键盘可调闹钟
- CENTOS安装mariadb
- spring4 Controller @ResponseBody中文乱码解决方案
- SQLiteDatabase的tips
- 0210
- 百万数据查询优化技巧三十则
- bzoj3881(ac自动机)
- 【angular2】(1)angular-cli修改端口号
- read,send,write,recv的区别