本帖最后由 喵喵喵喵喵喵喵 于 2020-3-22 17:27 編輯
IMG20200322042344.jpg (3.19 MB, 下載次數: 24)
下載附件
2020-3-22 04:39 上傳
單片機源程序如下:
- #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);//顯示出時,第二行第一個開始
- }
-
- }
復制代碼
|