AT89C51单片机万年历仿真图+代码 您所在的位置:网站首页 万年历万年历 AT89C51单片机万年历仿真图+代码

AT89C51单片机万年历仿真图+代码

2023-09-01 04:24| 来源: 网络整理| 查看: 265

首先申明,这篇博客是用作记录本人实训内容的,代码我个人一字一字码的,就上网查了下数字温度传感器DS18B20的处理方法,基本都是个人完成的。 在这里吐槽下,本人辛辛苦苦码的代码,最后实训分数还没那些抄的人高,吐槽下老师- -,好了接下来说正事。 注意:可能有些人复制代码后会报错,可能是环境问题,也可能其他问题,反正自己简单调试下就行了,不过大部分肯定没问题。

注:在评论有附本人交通灯的图噢,不过我还是建议各位先自己画。噢还要注意图里芯片,双击.hex的路径,可能链接是带本人的,大家要自己编译换成自己的.hex文件路径 在这里插入图片描述

万年历 一、实验内容二、电路仿真图三、代码四、效果图1.开始2.日期3.温度 五、最后

一、实验内容

设计定时器每50ms中断一次,在中断服务程序中,对中断次数进行计数,50ms计数20次,就是1秒,然后再对秒计数得到分的值,对分计数得到小时的值,分别将各值送到相应的段地址端口和位地址端口,通过数码管显示结果,达到电子时钟的计数效果。在计数的基础上,程序增加了按键程序,对电子时钟进行可调(对秒/分/时进行加1,此功能的增加使电子时钟功能更强、更实用,同理对日期也可以日/月/年进行加1。 a. 用AT89S51单片机的定时/计数器T0产生一秒的定时时间,作为秒计数时间。 b. 当一秒产生时,秒计数加1。 c. 开机时,显示00-00-00,并开始连续计时。计时满23-59-59时,返回00-00-00重新开始计时。 在以上设计基础上,在单片机的P1.0-P1.3口分别接入4个按键: d. P1.0控制“秒”的调整,每按一次加1秒 e. P1.1控制“分”的调整,每按一次加1分 f. P1.2控制“时”的调整,每按一次加1时 g. P1.3用作功能选择键,在程序运行过程中如果按下功能选择键,则在年月日、时分秒和显示温度之间进行功能切换。

用AT89C52控制DS18B20,读取数据,并对DS18B20转换后的数据进行处理,最后在数码管上显示DS18B20测出的温度。 a.使用6位数码管显示测得的温度 b.最高位为符号位,如果温度值为正,不显示,如果温度为负,则显示负号 c.第2—4位显示温度值的整数部分,并在第4位数据上显示小数点 d.第5位显示小数部分 e.6,7位显示摄氏度符号“C”。

二、电路仿真图

这里我用的是ISIS Professional仿真,写代码用到是keil4 在这里插入图片描述 https://download.csdn.net/download/kushe123/19392394?spm=1001.2014.3001.5503,为方便懒人们这里加个我的仿真图原图,里面已经装载好了keil4的编译文件,但可能我电脑的路径跟你们不一样,所以需要自己编译替换。 在这里插入图片描述 这是图中所用到的元器件

三、代码 #include //头文件 unsigned char bitcode[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; //选择LED位码 unsigned char code pcode[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //无小数点0~9 ncode[] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef}; //有小数点0~9 unsigned char riqi[] = {2, 0, 2, 1, 0, 2, 0, 8};//在这里改日期 unsigned int key1=1,key2=1,key3=1,key4=1,year=0,month=0,day=0,d; unsigned int bitcnt; unsigned int flag = 0; unsigned int s = 0,m = 0,h = 0; unsigned int n = 0; unsigned int bitcnt; unsigned char Tools[] = {0x63, 0x39,0x40}; sbit p10 = P1 ^ 0; sbit p11 = P1 ^ 1; sbit p12 = P1 ^ 2; sbit p13 = P1 ^ 3; sbit DQ = P2 ^ 4; void DATE(); //声明函数 void changed(); void runnian(); void delay(); void delay2(int z); void time_init(); void button(); void jishu(); void delay3(unsigned int j); void Init_DS18B20(void); char ReadOneChar(void); void WriteOneChar(unsigned char dat); int ReadTemperature(void); void display_tempmain(unsigned int i); void delay() { int i, j; for (i = 0; i P3 = bitcode[bitcnt]; if (bitcnt == 3 || bitcnt == 5) P0 = ncode[riqi[bitcnt]]; else P0 = pcode[riqi[bitcnt]]; delay(); runnian(); if(p10==0) //判断天数按键是否按下 key1=0; if (p10==1&&key1==0) { riqi[7]+=1; key1=1; if (riqi[7]==10) { riqi[7]=0; riqi[6]+=1; } if(day==d) { riqi[6]=0; riqi[7]=1; riqi[5]+=1; } if(month==12&&day==31) { riqi[5]=1; riqi[4]=0; riqi[3]+=1; } } if(p11==0) //判断月份按键是否按下 key2=0; if(p11==1&&key2==0) { riqi[5]+=1; key3=1; if(riqi[5]==10) {riqi[4]+=1; riqi[5]=0;} if(month==12) { riqi[5]=1; riqi[4]=0; riqi[3]+=1; } key2=1; } if(p12==0) //判断年份按键是否按下 key3=0; if(p12==1&&key3==0) { riqi[3]+=1; key3=1; if(riqi[3]==10) { riqi[3]=0; riqi[2]+=1; } } } } void runnian(void) //判断是否为闰年 { year=riqi[0]*1000+riqi[1]*100+riqi[2]*10+riqi[3]; month=riqi[4]*10+riqi[5]; day=riqi[6]*10+riqi[7]; if ((year%4==0)&&(year%100!=0)||(year%400==0)) { if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==10)||(month==12)) {d=31;} if((month==4)||(month==6)||(month==9)||(month==11)) {d=30;} if(month==2) {d=28;} } else { if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==10)||(month==12)) {d=31;} if((month==4)||(month==6)||(month==9)||(month==11)) {d=30;} if(month==2) {d=29;} } } void delay2(int z) { int x, y; for (x = z; x > 0; x--) for (y = 50; y > 0; y--) ; } void time_init() //定时器初始化 { TMOD = 0x01; TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; EA = 1; TR0 = 1; ET0 = 1; } void button() { if (p10==0) //判断s按键是否按下 key1=0; if (p10==1&&key1==0) { s++; key1=1; } if (p11==0) //判断m按键是否按下 key2=0; if (p11==1&&key2==0) { m++; key2=1; } if (p12==0) //判断h按键是否按下 key3=0; if (p12==1&&key3==0) {h++; key3=1;} } void jishu() { for (bitcnt = 0; bitcnt while (j--) ; } void Init_DS18B20(void) { unsigned char x = 0; DQ = 1; delay3(8); DQ = 0; delay3(80); DQ = 1; delay3(14); x = DQ; delay3(20); } char ReadOneChar(void) { unsigned char i = 0; unsigned char dat = 0; for (i = 8; i > 0; i--) { DQ = 0; dat >>= 1; DQ = 1; if (DQ) dat |= 0x80; delay3(4); } return (dat); } void WriteOneChar(unsigned char dat) { unsigned char i = 0; for (i = 8; i > 0; i--) { DQ = 0; DQ = dat & 0x01; delay3(5); DQ = 1; dat >>= 1; } delay3(4); } int ReadTemperature(void) //读取温度 { unsigned char a = 0; unsigned char b = 0; unsigned int t = 0; Init_DS18B20(); WriteOneChar(0xCC); WriteOneChar(0x44); Init_DS18B20(); WriteOneChar(0xCC); WriteOneChar(0xBE); a = ReadOneChar(); b = ReadOneChar(); t = b i = ~i + 1; P0 = 0x00; if((zhengshu % 100 / 10)==0) { P0 = Tools[2]; P3 = 0xfb; } else { P0 = Tools[2]; P3 = 0xfd; } delay3(500); } temp = (0x000f & i) * 10.0 * 0.0625; xiaoshu = temp; zhengshu = i >> 4; P0 = 0x00; if((zhengshu / 100)==0) //温度百位 { delay3(500); P3 = 0xff; } else { P0 = pcode[zhengshu / 100]; P3 = 0xfd; } if((zhengshu / 100)==0&&(zhengshu % 100 / 10)==0) //温度十位 { delay3(500); P3 = 0xff; } else { P0 = pcode[zhengshu % 100 / 10]; P3 = 0xfb; } delay3(500); P0 = 0x00; P0 = pcode[zhengshu % 100 % 10] | ~0x7f; //温度个位 P3 = 0xf7; delay3(500); P0 = 0x00; P0 = pcode[xiaoshu]; //小数 P3 = 0xef; delay3(500); P0 = 0x00; P0 = Tools[0]; //度 P3 = 0xdf; delay3(500); P0 = 0x00; P0 = Tools[1]; //摄氏度C P3 = 0xbf; delay3(500); P3 = 0xff; } void changed() //判断按键是否按下 { if (flag == 0) { while (flag == 0) { jishu(); if (p13 == 0) //判断转换键是否按下 key4=0; if (p13==1&&key4==0) { flag++; key4=1; } } } else if (flag == 1) while (flag == 1) { DATE(); if (p13 == 0) //判断转换键是否按下 key4=0; if (p13==1&&key4==0) { flag++; key4=1; } } else if (flag == 2) { unsigned int temp; while (flag == 2) //涓诲惊鐜? { temp = ReadTemperature(); display_tempmain(temp); if (p13 == 0) //判断转换键是否按下 key4=0; if (p13==1&&key4==0) { flag=0; key4=1; } } } } void main(void) { time_init(); while (1) { changed(); } } void timer() interrupt 1 //1s中断 { TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; n++; if (n == 20) { n = 0; s++; if (s == 60)// { s = 0; m++; } if (m == 60) { m = 0; h++; } if (h == 24) { h = 0; } } } 四、效果图

如果你图画对,代码没问题,hex文件也没问题,程序运行应该如下图所示:

1.开始

从00-00-00开始计时,充当计时器 在这里插入图片描述 在这里插入图片描述 这是按键的功能,比如在刚开始的计时器状态,第一个(从上到下)就+1s,第二个+1m,第三个+1h,第四个就是切换led显示状态,按下就切换到日期,再按下就切换到温度,在按下就又切换到显示计时器的状态。简单的说就是(计时-日期-温度)循环. 注意:按下切换功能按键后计时不会停止,而是在后台继续计时。

2.日期

在这里插入图片描述 注意:这里日期是代码里改的固定的,不会随系统日期的,同样按左边的按键可以实现+天,+月,+年

3.温度

在这里插入图片描述 注意:温度是读取DS18B20的数据来显示的,也就是改变DS18B20的温度,就可以改变显示的温度,所以左边的按键对这个是无效的,只有第四个切换功能的按键有用,按一下就切换到计时的去了

如下图改成4摄氏度(按那两个红色按钮调温度): 在这里插入图片描述

五、最后

希望能对你有用!!

当然还有最重要的事,麻烦各位大佬给个三连,毕竟码字不容易。 如果三连不行就点个赞吧(卑微)。 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有