本帖最后由 喵喵喵喵喵喵喵 于 2020-3-22 17:27 编辑
单片机源程序如下:
- #include<reg52.h>
- #include "intrins.h"
- #define uint unsigned int
- #define uchar unsigned char
- uchar a,miao,shi,fen,ri,yue,nian,week,keynum,temp,flagtime,ledcount,count,alarmflag,flagT/*时间分段标志*/,year1,month1,day1,lednum;
- uint flag;//取温度
- bit c_moon;
- data uchar year_moon,month_moon,day_moon;
- #define h1 0x80 //LCD第一行的初始化位置
- #define h2 0x80+0x40 //LCD第二行初始化位置
- sbit Gled=P1^6;//定义粉色led灯的管脚
- sbit Yled=P3^7;//定义黄色led灯的管脚
- //定义1602相关管脚
- sbit rs=P2^7;
- sbit en=P2^5;
- sbit rw=P2^6;
- //sbit led=P2^3;/*控制背光:15脚(串联10欧电阻)背光源正极*/
- //sbit busy=P0^7;//测忙线
- //DS1302芯片的管脚定义
- sbit IO=P2^2;
- sbit SCLK=P2^1;
- sbit RST=P2^3;
- sbit DQ=P2^0;/*定义DS18b20管脚*/
- sbit ACC0=ACC^0;//设置累加器
- sbit ACC7=ACC^7;
- //按键
- sbit key1=P3^0;//设置按键
- sbit key2=P3^4;
- sbit key3=P3^6;
- sbit beep=P1^7;//蜂鸣器,用于报时
- sbit lcdbusy=P0^7;
- void delay(uint z)//延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void testbusy()//测忙
- {
- P0=0xff;//注意是P0组
- rs=0;
- rw=1;
- en=1;
- while(lcdbusy);//等待不忙
- en=0;
- }
- void writecom(uchar com)//写入指令函数
- {
- testbusy();
- P0=com;
- rs=0;
- rw=0;
- en=1;
- en=0;
- }
- void writedata(uchar dat)//写入数据函数
- {
- testbusy();//先测忙
- P0=dat;
- rs=1;
- rw=0;
- en=1;
- en=0;
- }
- void print(uchar a3,uchar *str)//写字符串函数(没有延时)
- {
- writecom(a3|0x80);
- while(*str!='\0')
- {
- //delay(100);//延时一下
- writedata(*str++);
- }
- *str=0;
- }
- void print2(uchar a2,uchar *str)//用于头字条的显示延时
- {
- writecom(a2|0x80);
- while(*str!='\0')
- {
- delay(130);//延时一下
- writedata(*str++);
- }
- *str=0;
- }
- void lcdinit()//1602初始化函数
- {
- writecom(0x38);//设置为两行显示,8位显示
- writecom(0x0c);//开显示,不显示光标
- writecom(0x06);//光标右移
- writecom(0x01);//清零
- print2(0x80,"^_^ @_@ U_U -_-");//第一行显示制作者
- print2(0x40,"Enjoy Your Life!");//第二行显示制作人
- delay(3000);// 延时3秒
- //writecom(0x01);//再次清零
- //writecom(h1);//第一行第一个字开始写入
- }
- /*以下是温度芯片DS18b20的相关函数*/
- void delay2(uint s)//延时,用于温度程序部分
- {
- while(s--);//区分i,用s表示
- }
- void Init_DS18B20(void)//初始化DS18b20
- {
- uchar W=0;//注意是w
- DQ=1;
- delay2(8);
- DQ=0;//拉低
- delay2(29);//延时大于480us(此处延时时间不确定,实际时修改)
- DQ=1;//拉高
- delay2(3);//(时间不确定)
- W=DQ;//稍作延时后如W=0则初始化成功
- delay2(20);
- }
- uchar ReadOneChar(void)//DS18b20读一个字节函数
- {
- uchar i=0;
- uchar dat=0;
- for(i=8;i>0;i--)
- {
- DQ=0;//给脉冲信号
- dat>>=1;//右移一位
- DQ=1;//给脉冲信号
- if(DQ)
- dat|=0x80;
- delay2(4);
- }
- return(dat);
- }
- void WriteOneChar(uchar dat)//写一个字节函数
- {
- uchar i=0;
- for(i=8;i>0;i--)
- {
- DQ=0;
- DQ=dat&0x01;
- delay2(5);
- DQ=1;
- dat>>=1;
- }
- }
- uint ReadTemperature(void)//读取温度
- {
- uchar a1=0;//用于合并
- uchar b1=0;
- uint t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC);//跳过读取序列号的操作
- WriteOneChar(0x44);//启动温度转换
- Init_DS18B20();//再次初始化
- WriteOneChar(0xCC);//跳过读取序列号
- WriteOneChar(0xBE);//读取温度寄存器
- a1=ReadOneChar();//先读取低位
- b1=ReadOneChar();//后读取高位
- t=b1;
- t<<=8;
- t=t|a1;
- tt=t*0.0625;
- t=tt*10+0.5;//放大10倍并四舍五入
- return(t);
- }
- /*下面是相关数据的显示函数*/
- //温度显示函数
- void writetemp(uchar add,uint dat)//写入温度值函数指定位置
- {
- uchar gw,sw,xw;//个位,十位,小数位(注意得到为三位有效数)
- gw=dat%100/10;/*特别注意此处*/
- sw=dat/100;
- xw=dat%10;
- writecom(h2+add);//h2为头文件规定的值0x80+0x40
- writedata(0x30+sw);//数字+30得到显示码
- writedata(0x30+gw);//个位数
- writedata(0x2e);//小数点
- writedata(0x30+xw);//小数位
- writedata(0xdf);//显示“°”(度)
- //writedata(0x43);//显示“C”符号,为液晶字符的地址码(考虑是否要)
- }
- /*以下是主函数部分*/
- void main()
- {
- alarmflag=1;
- //led=0;
- lcdinit();//初始化液晶函数
- ds1302_init();//DS1302时钟芯片初始化函数
- init();//定时器初始化函数
- beep=0;
- delay(200);
- beep=1;
- //led=0;
- while(1)
- {
- year1=(nian)/10*16+(nian)%10;//转换为bcd码
- month1=(yue)/10*16+(yue)%10;
- day1=(ri)/10*16+(ri)%10;
- chushihua();//初始化时间函数
- Conversion(0,year1,month1,day1);//
- timealarm();//报时程序
- keyscan();//不断扫面按键函数
- /*if(key2==1)//加键不按下时才有用
- {
- ledcontrol();//背光控制
- } */
- }
- }
- void timer0() interrupt 1//中断任务:取数据并显示
- {
- TH0=(65536-60000)/256;//重新赋初值
- TL0=(65536-60000)%256;
- //读取数据
- flag=ReadTemperature();//读取温度(考虑是否放在此处)
- miao=turnBCD(read_1302(0x81));//读出秒
- fen=turnBCD(read_1302(0x83));//读出分
- shi=turnBCD(read_1302(0x85));//读出时
- ri=turnBCD(read_1302(0x87));//读出日
- yue=turnBCD(read_1302(0x89));//读出月
- nian=turnBCD(read_1302(0x8d));//读出年
- week=turnBCD(read_1302(0x8b));//读出周
- //显示数据
-
- if(((0<=miao)&&(miao<15))||(((miao/10==2)||(miao/10==4))&&(miao%10<=5))||((54<=miao)&&(miao<60))) /*显示所有信息的时间段*/
- {
- print(0x80,"20 / / W < >");
- writecom(h1+0x0c);
- writedata(0x7e);//→右箭头
- writeday(8,ri);//显示日
- writeday(5,yue);//显示月
- writeday(2,nian);//显示年
- writeweek(week);//显示星期
- print(0x40," : : ");
- writetemp(9,flag);//显示温度,第二行显示
- writetime(6,miao);//显示出秒
- writetime(3,fen);//显示出分
- writetime(0,shi);//显示出时,第二行第一个开始
- }
- //if(15<=miao)/*当秒大于15时才显示*/
- //{
- if(((miao/10==1)||(miao/10==3))&&(miao%10>=5))
- {
- switch(flag/100)//取出温度的十位数
- {
- case 0:print(0x80,"Pretty cold now!");
- break;
- case 1:print(0x80,"little cold now!");
- break;
- case 2:print(0x80,"It is warm now. ");
- break;
- case 3:print(0x80,"It's hot !!! ");
- break;
- case 4:print(0x80,"Very very hot!!!");
- break;
- case 5:print(0x80,"Very very hot!!!");
- break;
- case 6:print(0x80,"Very very hot!!!");
- break;
- }
-
- //print(0x80,"It is warm now. ");
- print(0x40," : : ");
- writetemp(9,flag);//显示温度,第二行显示
- writetime(6,miao);//显示出秒
- writetime(3,fen);//显示出分
- writetime(0,shi);//显示出时,第二行第一个开始
- }
-
- }
复制代码
|