完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 agy518 于 2016-3-19 23:09 编辑
[img=110,0][/img][img=300,218][/img]
大家好,我刚刚学习单片机不久,想做个51单片机定时开关1602液晶显示AT24C02存储,我是在网上找的程序,照程序画的图,大家看看我画的图有问题吗?还有为什么没有DS1302时钟模块,哪来的时间 程序 #include #include #include #define uchar unsigned char #define uint unsigned int #define LCM_Data P0 #define Busy 0x80 //用于检测LCM状态字中的Busy标识 ***it LCM_RS = P3^3; ***it LCM_RW = P3^4;//定义引脚 ***it LCM_E = P3^5; ***it key1 = P1^4; //- ***it key2 = P1^3; //+ ***it key3 = P1^2; //set ***it key4 = P1^5; //run ***it key5 = P1^6; //off ***it key6 = P1^7; //on ***it scl = P1^0; ***it sda = P1^1; ***it jdq = P3^6; uchar id,timecount,fl=0; int r_hour,r_min,r_sec,r_hour2,r_min2,r_sec2; int hour,min,sec,hour2,min2,sec2,mode=1,aa; bit flag,sflag; //flag是时钟冒号闪烁标志,sflag是温度负号显示标志 void Disp_line1(void); //显示屏幕第一行 void Disp_line2(void); //显示屏幕第二行 void id_case1_key(); void WriteDataLCM(uchar WDLCM); void WriteCommandLCM(uchar WCLCM,BuysC); uchar ReadStatusLCM(void); void LCMInit(void); void DisplayOneChar(uchar X, uchar Y, uchar DData); void DisplayListChar(uchar X, uchar Y, uchar code *DData); void Delay5Ms(void); void Delay400Ms(void); void runtime(); void ScanKey(); void LedDisplay(); void delay() //延时5us { ; ; } void init() //总线初始化 { sda=1; scl=1; } void start() //开始信号 { sda=1; delay(); scl=1; delay(); sda=0; delay(); } void stop() //停止信号 { sda=0; delay(); scl=1; delay(); sda=1; delay(); } void respons() //应答信号 { uchar i=0; scl=1; delay(); while((sda==1)&&(i<250)) i++; //若sda为0,退出,若sda在250us内sda一直为1,则表示未收到应答,也退出。 scl=0; delay(); } void write_byte(uchar date)//向sda数据线上写一字节数据 { uchar i,temp; temp=date; scl=0; delay(); for(i=0;i<8;i++) { temp=temp<<1; sda=CY; delay(); scl=1; //和数码管类似,都是先送数据再打开开关 delay(); scl=0; delay(); } sda=1;//释放总线,为读取应答的低电平信号 delay(); } uchar read_byte() //从sda数据线上读一字节数据 { uchar i,j,k; scl=0; delay(); sda=1; delay(); for(i=0;i<8;i++) { scl=1; delay(); j=sda; k=(k<<1)|j; scl=0; delay(); } return k; } void write_add(uchar add,uchar date)//向24C02指定存储地址写入指定1字节数据 { start(); //s write_byte(0xa0); //器件地址+0:0xa0=1010 0000 B,板子硬件设计地址为1010 000 respons(); //A write_byte(add); //写入首地址 respons(); //A write_byte(date); //写入数据 respons(); //A stop(); //p } uchar read_add(uchar add)//从24C02指定存储地址中读取1字节数据 { uchar date; start(); //s write_byte(0xa0); //器件地址+0,表示主机要传送 respons(); //A write_byte(add); //要读出数据的首地址 respons(); //A start(); //s write_byte(0xa1); //器件地址+1,表示主机要接受 respons(); //A date=read_byte(); //读出数据 stop(); //p return date; } void ScanKey(void) //按键判断程序 { if(key3==0) //判断是否按下键盘 { Delay5Ms(); if(key3==0) //确认按键按下 { mode++; //按键计数加1 if(mode>=5) //计4次重新计数 { mode=1; } //将mode清零 } while(key3==0);//按键锁定,每按一次mode只加1 } if(key4==0) //判断是否按下键盘 { Delay5Ms(); if(key4==0) //确认按键按下 { WriteCommandLCM(0x01,1); //显示清屏 write_add(3,hour); Delay5Ms(); write_add(4,min); Delay5Ms(); write_add(5,sec); Delay5Ms(); write_add(6,hour2); Delay5Ms(); write_add(7,min2); Delay5Ms(); write_add(8,sec2); r_min=min; r_sec=sec; r_hour=hour; r_min2=min2; r_sec2=sec2; r_hour2=hour2; fl=0; runtime(); } } } void setonhour() { TR0=0; sec=0; jdq=1; DisplayListChar(0,0,"Set ON Time "); DisplayListChar(10,1,"hour"); DisplayOneChar(8,1,hour/10+0x30); DisplayOneChar(9,1,hour%10+0x30); if (key2==0) // 设置和选择项目键 { Delay5Ms(); if(key2==0) { hour=hour+1; if(hour>10) hour=0; } while(key2==0); } if (key1==0) // 设置和选择项目键 { Delay5Ms(); if(key1==0) { hour=hour-1; if(hour<0) hour=10; } while(key1==0); } } void setonmin() { TR0=0; jdq=1; sec=0; DisplayListChar(0,0,"Set ON Time "); DisplayListChar(10,1,"min "); DisplayOneChar(8,1,min/10+0x30); DisplayOneChar(9,1,min%10+0x30); if (key2==0) // 设置和选择项目键 { Delay5Ms(); if(key2==0) { min=min+1; if(min>60) min=0; } while(key2==0); } if (key1==0) // 设置和选择项目键 { Delay5Ms(); if(key1==0) { min=min-1; if(min<0) min=60; } while(key1==0); } } void setoffhour() { TR0=0; jdq=1; sec=0; DisplayListChar(0,0,"Set OFF Time"); DisplayListChar(10,1,"hour"); DisplayOneChar(8,1,hour2/10+0x30); DisplayOneChar(9,1,hour2%10+0x30); if (key2==0) // 设置和选择项目键 { Delay5Ms(); if(key2==0) { hour2=hour2+1; if(hour2>10) hour2=0; } while(key2==0); } if (key1==0) // 设置和选择项目键 { Delay5Ms(); if(key1==0) { hour2=hour2-1; if(hour2<0) hour2=10; } while(key1==0); } } void setoffmin() { TR0=0; jdq=1; sec=0; DisplayListChar(0,0,"Set OFF Time"); DisplayListChar(10,1,"min "); DisplayOneChar(8,1,min2/10+0x30); DisplayOneChar(9,1,min2%10+0x30); if (key2==0) // 设置和选择项目键 { Delay5Ms(); if(key2==0) { min2=min2+1; if(min2>60) min2=0; } while(key2==0); } if (key1==0) // 设置和选择项目键 { Delay5Ms(); if(key1==0) { min2=min2-1; if(min2<0) min2=60; } while(key1==0); } } void runontime() { DisplayListChar(0,0,"Run ON Time "); DisplayOneChar(1,1,r_hour/10+0x30); //显示固定字符 DisplayOneChar(2,1,r_hour%10+0x30); DisplayListChar(3,1,":"); DisplayOneChar(4,1,r_min/10+0x30); //显示固定字符 DisplayOneChar(5,1,r_min%10+0x30); DisplayListChar(6,1,":"); DisplayOneChar(7,1,r_sec/10+0x30); //显示固定字符 DisplayOneChar(8,1,r_sec%10+0x30); TR0=1; jdq=0; } void runofftime() { DisplayListChar(0,0,"Run OFF Time"); DisplayOneChar(1,1,r_hour2/10+0x30); //显示固定字符 DisplayOneChar(2,1,r_hour2%10+0x30); DisplayListChar(3,1,":"); DisplayOneChar(4,1,r_min2/10+0x30); //显示固定字符 DisplayOneChar(5,1,r_min2%10+0x30); DisplayListChar(6,1,":"); DisplayOneChar(7,1,r_sec2/10+0x30); //显示固定字符 DisplayOneChar(8,1,r_sec2%10+0x30); TR0=1; jdq=1; } void set() { WriteCommandLCM(0x01,1); //显示清屏 while(1) { ScanKey(); LedDisplay(); } } void allon() { WriteCommandLCM(0x01,1); //显示清屏 TR0=0; while(1) { DisplayListChar(0,0,"Always ON "); jdq=0; if(key5==0) //判断是否按下键盘 { Delay5Ms(); if(key5==0) //确认按键按下 { TR0=1; fl=1; r_min=min; r_sec=sec; r_hour=hour; r_min2=min2; r_sec2=sec2; r_hour2=hour2; } while(key5==0);//按键锁定,每按一次mode只加1 runtime(); } } } void alloff() { WriteCommandLCM(0x01,1); //显示清屏 TR0=0; while(1) { DisplayListChar(0,0,"Always OFF"); jdq=1; if(key6==0) //判断是否按下键盘 { Delay5Ms(); if(key6==0) //确认按键按下 { TR0=1; fl=0; r_min=min; r_sec=sec; r_hour=hour; r_min2=min2; r_sec2=sec2; r_hour2=hour2; } while(key6==0);//按键锁定,每按一次mode只加1 runtime(); } } } void runtime() { while(1) { if(fl==0) runontime(); if(fl==1) runofftime(); if(key3==0) //判断是否按下键盘 { Delay5Ms(); if(key3==0) //确认按键按下 { mode=1; set(); //将mode清零 } while(key3==0);//按键锁定,每按一次mode只加1 } if(key5==0) //判断是否按下键盘 { Delay5Ms(); if(key5==0) //确认按键按下 { } while(key5==0);//按键锁定,每按一次mode只加1 allon(); //将mode清零 } if(key6==0) //判断是否按下键盘 { Delay5Ms(); if(key6==0) //确认按键按下 { } while(key6==0);//按键锁定,每按一次mode只加1 alloff(); //将mode清零 } } } void LedDisplay(void) { if(mode==1) { setonhour(); } else if(mode==2) { setonmin(); } else if(mode==3) { setoffhour(); } else if(mode==4) { setoffmin(); } } void main(void) { jdq=1; Delay400Ms(); //启动等待,等LCM讲入工作状态 LCMInit(); //LCM初始化 Delay5Ms(); //延时片刻(可不要) TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; init(); Delay5Ms(); hour=read_add(3); Delay5Ms(); min=read_add(4); Delay5Ms(); sec=read_add(5); Delay5Ms(); hour2=read_add(6); Delay5Ms(); min2=read_add(7); Delay5Ms(); sec2=read_add(8); r_min=min; r_sec=sec; r_hour=hour; r_min2=min2; r_sec2=sec2; r_hour2=hour2; while(1) { runtime(); } } void WriteDataLCM(uchar WDLCM) { ReadStatusLCM(); //检测忙 LCM_Data = WDLCM; LCM_RS = 1; LCM_RW = 0; LCM_E = 0; //若晶振速度太高可以在这后加小的延时 LCM_E = 0; //延时 LCM_E = 1; } void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测 { if(BuysC) ReadStatusLCM(); //根据需要检测忙 LCM_Data = WCLCM; LCM_RS = 0; LCM_RW = 0; LCM_E = 0; LCM_E = 0; LCM_E = 1; } uchar ReadStatusLCM(void) { LCM_Data = 0xFF; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while (LCM_Data & Busy); //检测忙信号 return(LCM_Data); } void LCMInit(void) { LCM_Data = 0; WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号 Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,0); Delay5Ms(); WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号 WriteCommandLCM(0x08,1); //关闭显示 WriteCommandLCM(0x01,1); //显示清屏 WriteCommandLCM(0x06,1); // 显示光标移动设置 WriteCommandLCM(0x0C,1); // 显示开及光标设置 } void DisplayOneChar(uchar X, uchar Y, uchar DData) { Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40; X |= 0x80; //算出指令码 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码 WriteDataLCM(DData); } void DisplayListChar(uchar X, uchar Y, uchar code *DData) { uchar ListLength,j; ListLength = strlen(DData); Y &= 0x1; X &= 0xF; //限制X不能大于15,Y不能大于1 if (X <= 0xF) //X坐标应小于0xF { for(j=0;j { DisplayOneChar(X, Y, DData[j]); //显示单个字符 X++; } } } void Delay5Ms(void) { uint TempCyc = 5552; while(TempCyc--); } void Delay400Ms(void) { uchar TempCycA = 5; uint TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); }; } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; aa++; if(fl==0) { if(aa==20) { aa=0; r_sec--; if(r_sec<0) { r_min--; r_sec=59; if(r_min<0) { r_hour--; r_min=59; } if(r_hour<0) { r_min=0; r_sec=0; r_hour=0; jdq=1; fl=1; r_min2=min2; r_sec2=sec2; r_hour2=hour2; } } } return; } if(fl==1) { if(aa==20) { aa=0; r_sec2--; if(r_sec2<0) { r_min2--; r_sec2=59; if(r_min2<0) { r_hour2--; r_min2=59; } if(r_hour2<0) { r_min2=0; r_sec2=0; r_hour2=0; jdq=0; fl=0; r_min=min; r_sec=sec; r_hour=hour; } } } return; } } |
|
相关推荐
8个回答
|
|
没什么吧,没怎么看
|
|
|
|
51单片机EA端口要接电源,那个黑圈圈L1是电源吧,不过看写的12v,是不能直接用作单片机电源的,如果12v是用于控制继电器的话,继电器的驱动电路不对,把三极管发射级与地相连的那根线换成二极管。按键一般要接上拉电阻,1602供电没接。不用DS1302产生时间却得到时间是因为用的51定时器,也可以做时间的。
|
|
|
|
wling597074509 发表于 2016-3-20 07:24 你好,看来你详细的解答,非常满意,辛苦了,再次请教个问题,是不是用51定时器的时间,那么断电后,在开启,时间是不是就从初始值开始走时间,AT24C02存储的应该使我们设置的时间吧,如果是请指定点改用DS1302时间加个纽扣电池,这样设备断电了,时间走起,也不用每次设置时间, |
|
|
|
wling597074509 发表于 2016-3-20 07:24 高手老师好,51单片机只有两个定时器,是不是就只能做两路定时开关了,怎么修改 |
|
|
|
agy518 发表于 2016-03-20 23:51 是的,每次开启读的是结束时的时间,需要显示当前时间的话用ds1302比较好,有纽扣电池,主电路断开了它还工作。 |
|
|
|
定时就是设置变量的问题,假如定时器设置好了为1s,那么如果设置变量t为5s控制一路,也可以设置变量x为10s控制另外一路,多设几个变量就可以控制多路了 |
|
|
|
谢谢分享谢谢分享谢谢分享
|
|
|
|
不错的文档,值得收藏
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】简介、环境搭建、工程测试
177 浏览 0 评论
312 浏览 0 评论
imx6ull裸机编程,使用宏定义无法驱动,使用指针就可以驱动
691 浏览 1 评论
《DNK210使用指南 -CanMV版 V1.0》第三十二章 音频FFT实验
384 浏览 0 评论
飞凌嵌入式ElfBoard EL 1板卡-i2c与从设备通讯编程示例之i2c-tools工具使用
1284 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11620 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-6 04:52 , Processed in 0.759169 second(s), Total 84, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号