完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
设计要求:
最多可记录十组数据 可删除其中多组数据 可上下查阅所记录的数据 数据通过lcd1602显示 计时精度到0.01s 由于并没有使用24c02,导致程序去数据较大,仿真可能不行。实际验证通过 程序界面如图: 仿真界面如图: 如果编译出错,将keil按如图参数设置: 以下为程序代码: 包括两个文件,主程序里面是: #include《1602.h》 #include《reg52.h》 #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif /*按键定义*/ /*开始键,计数键,停止计数键或者清零键,上下查阅键,删除数据键*/ ***it key_start=P1^0; ***it key_count=P1^1; ***it key_stop=P1^2; ***it key_up=P1^3; ***it key_down=P1^4; /*变量定义*/ int count=0;//计数器 uint i,j,state,k=0,countnum,m,delete; /*设置标志位*/ char flag; char maxflag; char clearflag; char turnflag; // char upflag; //为1时可以继续上翻 char minflag=0; //为0时可以继续下翻 char downflag; /*定义数组 */ unsigned char str[] = “time:”; unsigned char str2[]= “num:”; unsigned char str3[; unsigned char str4[; unsigned char str5[; unsigned char str6[; unsigned char str7[; int number[10]=0; int num2[5]=0; void keyscan(); void init(); void main() { InitLcd1602(); init(); /*以下为调试程序段*/ LcdShowStr(0,0,str3); // LcdShowStr(0,1,str2); // LcdWriteCom(0x91); // LcdWriteData(‘0’+1); // LcdWriteCom(0x90); // LcdWriteData(‘0’+1); /*以上为调试程序段*/ while(1) { //LcdShowStr(0,1,str4); //测试 keyscan(); Lcd1602_Delay1ms(50); } } void init() { IT0=0; EX0=0; TMOD=0x01; TH0=(65536-10000)/256; TL0=(65536-10000)%256; EA=0; //开总中断 // key_count=0; // key_stop=0; // key_up=0; // key_down=0; // key_delete=0; flag=0; //标志位为0时代表未计时状态,为1时代表为计时状态 i=0; maxflag=0;//定时标志位,为1时代表定时已满 clearflag=0;//清除标志位 turnflag=0;//为1时可以上下翻页显示 downflag=0; upflag=1; } void keyscan() { if((key_start==0)&&(flag==0)) //防抖处理 { Lcd1602_Delay1ms(10); //防抖处理 if((key_start==0)&&(flag==0))//防抖处理 { while((!(key_start==0)&&(flag==0)));//防抖处理 InitLcd1602(); EA=1;//检测到开始按键按下后,启动定时器 ET0=1; //计时器0开启 TR0=1; //计时器打开 flag=1;//设置标志位为计时状态 LcdShowStr(0,0,str4); LcdShowStr(0,1,str5); } } if((key_count==0)&&(flag==1)&&(maxflag==0)) { Lcd1602_Delay1ms(50); if((key_count==0)&&(flag==1)&&(maxflag==0)) { while(!((key_count==0)&&(flag==1)&&(maxflag==0))); InitLcd1602(); LcdShowStr(0,0,str); LcdShowStr(0,1,str2); number=count; LcdWriteCom(0xC7); LcdWriteData(‘0’+i+1); LcdWriteCom(0xC6); LcdWriteData(‘0’); if(i==9) { LcdWriteCom(0xC7); LcdWriteData(‘0’); LcdWriteCom(0xC6); LcdWriteData(‘0’+1); } num2[0]=number/10000; num2[1]=number/1000%10; num2[2]=number/100%10; num2[3]=number/10%10; num2[4]=number%10; LcdWriteCom(0x86); LcdWriteData(‘0’+num2[0]); LcdWriteCom(0x87); LcdWriteData(‘0’+num2[1]); LcdWriteCom(0x88); LcdWriteData(‘0’+num2[2]); LcdWriteCom(0x89); LcdWriteData(‘。’); LcdWriteCom(0x8A); LcdWriteData(‘0’+num2[3]); LcdWriteCom(0x8B); LcdWriteData(‘0’+num2[4]); LcdWriteCom(0x8D); LcdWriteData(‘S’); i++; state=i; if(i==10) { maxflag=1; } } } if(key_stop==0) { Lcd1602_Delay1ms(50); if(key_stop==0) { while(!(key_stop==0)); if(clearflag==0) { TR0=0; //关定时器,查阅时定时就停止 EX0=1; //开外部中断,保证只有在上下翻阅时才能触发外部中断 count=0;//计数清零 clearflag=1;//清除标志位打开,也就是说再按一下这个按键所有制清零 turnflag=1; minflag=0; } else if(clearflag==1)//此块执行清除任务 { InitLcd1602(); number[10]=0; clearflag=0; LcdShowStr(0,0,str3); turnflag=0; maxflag=0; flag=0; i=0;//将数组计数给清零 } } } if(key_up==0) { Lcd1602_Delay1ms(50); if(key_up==0) { while(!(key_up==0)); if(upflag==0) { InitLcd1602(); LcdShowStr(0,0,str); LcdShowStr(0,1,str2); minflag=0;//只要上翻过后都可以下翻 state++; if(state==10) { LcdWriteCom(0xC7); LcdWriteData(‘0’); LcdWriteCom(0xC6); LcdWriteData(‘0’+1); } else { LcdWriteCom(0xC7); LcdWriteData(‘0’+state); LcdWriteCom(0xC6); LcdWriteData(‘0’); } m=state-1; delete=m; /*显示时间*/ num2[0]=number[m]/10000; num2[1]=number[m]/1000%10; num2[2]=number[m]/100%10; num2[3]=number[m]/10%10; num2[4]=number[m]%10; LcdWriteCom(0x86); LcdWriteData(‘0’+num2[0]); LcdWriteCom(0x87); LcdWriteData(‘0’+num2[1]); LcdWriteCom(0x88); LcdWriteData(‘0’+num2[2]); LcdWriteCom(0x89); LcdWriteData(‘。’); LcdWriteCom(0x8A); LcdWriteData(‘0’+num2[3]); LcdWriteCom(0x8B); LcdWriteData(‘0’+num2[4]); LcdWriteCom(0x8D); LcdWriteData(‘S’); if(state==10) { upflag=1; } } } } if(key_down==0) { Lcd1602_Delay1ms(50); if(key_down==0) { while(!(key_down==0)); if((turnflag==1)&&(minflag==0)) { InitLcd1602(); LcdShowStr(0,0,str); LcdShowStr(0,1,str2); /*显示组号*/ state--; LcdWriteCom(0xC7); LcdWriteData(‘0’+state); LcdWriteCom(0xC6); LcdWriteData(‘0’); k=state-1; delete=k; /*显示时间*/ num2[0]=number[k]/10000; num2[1]=number[k]/1000%10; num2[2]=number[k]/100%10; num2[3]=number[k]/10%10; num2[4]=number[k]%10; LcdWriteCom(0x86); LcdWriteData(‘0’+num2[0]); LcdWriteCom(0x87); LcdWriteData(‘0’+num2[1]); LcdWriteCom(0x88); LcdWriteData(‘0’+num2[2]); LcdWriteCom(0x89); LcdWriteData(‘。’); LcdWriteCom(0x8A); LcdWriteData(‘0’+num2[3]); LcdWriteCom(0x8B); LcdWriteData(‘0’+num2[4]); LcdWriteCom(0x8D); LcdWriteData(‘S’); if(state==1) { minflag=1; } upflag=0; } } } } void timer0() interrupt 1 { TH0=(65536-10000)/256; TL0=(65536-10000)%256; count++; if(count==6000) { count=0; ET0=0; //计时器0关闭 TR0=0; //计时器关闭 turnflag=1; EX0=1; InitLcd1602(); LcdShowStr(0,0,str6); LcdShowStr(0,1,str7); } } void counter0(void) interrupt 0 using 1 { number[delete]=0; LcdWriteCom(0x86); LcdWriteData(‘0’); LcdWriteCom(0x87); LcdWriteData(‘0’); LcdWriteCom(0x88); LcdWriteData(‘0’); LcdWriteCom(0x89); LcdWriteData(‘。’); LcdWriteCom(0x8A); LcdWriteData(‘0’); LcdWriteCom(0x8B); LcdWriteData(‘0’); LcdWriteCom(0x8D); LcdWriteData(‘S’); } 然后是lcd的驱动程序: #include《1602.h》 void Read_Busy() //忙检测函数,判断bit7是0,允许执行;1禁止 { unsigned char sta; // LCD1602_DB = 0xff; LCD1602_RS = 0; LCD1602_RW = 1; do { LCD1602_EN = 1; sta = LCD1602_DB; LCD1602_EN = 0; //使能,用完就拉低,释放总线 }while(sta & 0x80); } void Lcd1602_Write_Cmd(unsigned char cmd) //写命令 { Read_Busy(); LCD1602_RS = 0; LCD1602_RW = 0; LCD1602_DB = cmd; LCD1602_EN = 1; LCD1602_EN = 0; } void Lcd1602_Write_Data(unsigned char dat) //写数据 { Read_Busy(); LCD1602_RS = 1; LCD1602_RW = 0; LCD1602_DB = dat; LCD1602_EN = 1; LCD1602_EN = 0; } void LcdSetCursor(unsigned char x,unsigned char y) //坐标显示 { unsigned char addr; if(y == 0) addr = 0x00 + x; else addr = 0x40 + x; Lcd1602_Write_Cmd(addr|0x80); } void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str) //显示字符串 { LcdSetCursor(x,y); //当前字符的坐标 while(*str != ‘ ’) { Lcd1602_Write_Data(*str++); } } void InitLcd1602() //1602初始化 { Lcd1602_Write_Cmd(0x38); //打开,5*8,8位数据 Lcd1602_Write_Cmd(0x0c); Lcd1602_Write_Cmd(0x06); Lcd1602_Write_Cmd(0x01); //清屏 } void Lcd1602_Delay1ms(uint c) //误差 0us { uchar a,b; for (; c》0; c--) { for (b=199;b》0;b--) { for(a=1;a》0;a--); } } } /******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的命令 * 输 入 : com * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com) //写入命令 { LCD1602_EN = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 LCD1602_DB = com; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_EN = 0; } #else void LcdWriteCom(uchar com) //写入命令 { LCD1602_EN = 0; //使能清零 LCD1602_RS = 0; //选择写入命令 LCD1602_RW = 0; //选择写入 LCD1602_DB = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_EN = 0; // Lcd1602_Delay1ms(1); LCD1602_DB = com 《《 4; //发送低四位 Lcd1602_Delay1ms(1); LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_EN = 0; } #endif /******************************************************************************* * 函 数 名 : LcdWriteData * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS void LcdWriteData(uchar dat) //写入数据 { LCD1602_EN = 0; //使能清零 LCD1602_RS = 1; //选择输入数据 LCD1602_RW = 0; //选择写入 LCD1602_DB = dat; //写入数据 Lcd1602_Delay1ms(1); LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_EN = 0; } #else void LcdWriteData(uchar dat) //写入数据 { LCD1602_EN = 0; //使能清零 LCD1602_RS = 1; //选择写入数据 LCD1602_RW = 0; //选择写入 LCD1602_DB = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_EN = 0; LCD1602_DB = dat 《《 4; //写入低四位 Lcd1602_Delay1ms(1); LCD1602_EN = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_EN = 0; } #endif 还有一个1602.h文件: #include《reg52.h》 #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif #define LCD1602_DB P0 ***it LCD1602_RS = P2^6; ***it LCD1602_RW = P2^5; ***it LCD1602_EN = P2^7; void InitLcd1602(); //初始化lcd1602 void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);//写入一个字符串 void LcdWriteData(uchar dat1);//写入一个单个字 void LcdWriteCom(uchar com);//写入地址 void Lcd1602_Delay1ms(uint c); void InitLcd1602(); |
|
|
|
只有小组成员才能发言,加入小组>>
2513 浏览 0 评论
1083浏览 2评论
700浏览 1评论
452浏览 0评论
193浏览 0评论
329浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:08 , Processed in 1.243798 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号