|
我是按照每個元件的原理圖裝的線路,之前也檢查了下午也沒有發(fā)現(xiàn)錯誤。那些百度到的方法也試過了,也沒用。程序在仿真的時候沒有問題。
程序
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*------------------寄存器地址定義------------*/
- #define WRITE_SECOND 0x80
- #define WRITE_MINUTE 0x82
- #define WRITE_HOUR 0x84
- #define WRITE_DAY 0x86
- #define WRITE_MONTH 0x88
- #define WRITE_YEAR 0x8C
- #define WRITE_PROTECT 0x8E
- #define WRITE_WEEK 0x8A
- #define WRITE_CURRENT 0x90
- #define READ_SECOND 0x81
- #define READ_MINUTE 0x83
- #define READ_HOUR 0x85
- #define READ_DAY 0x87
- #define READ_MONTH 0x89
- #define READ_WEEK 0x8B
- #define READ_YEAR 0x8D
- sbit RST=P3^5; //DS1302片選
- sbit DIO=P3^3; //DS1302數(shù)據(jù)信號
- sbit SCLK=P3^4; //DS1302時鐘信號
- sbit ACC7=ACC^7;
- sbit ACC0=ACC^0;
- unsigned int count=0;
- sbit beep=P2^2;
- void INITIAL_1302();
- unsigned char READ_1302(unsigned char addr);
- void WRITE_1302(unsigned char addr,unsigned char date);
- sbit LCD_E=P1^7; //液晶使能端
- sbit LCD_RS=P1^5; //液晶數(shù)據(jù)命令選擇端
- sbit LCD_RW=P1^6; //液晶讀寫選擇端
- sbit key0=P2^4; //功能鍵
- sbit key1=P2^5; //增大鍵
- sbit key2=P2^6; //減小鍵
- sbit key3=P2^7;
- sbit DQ=P1^4; //18b20溫度輸入輸出端
- char hour,minute,second,week,day,month,year,temm=1,chour=00,cminute=00,tmpl1,tmph1,tmsecond=00,tsecond=00,dminute=00,dsecond=00;
- uint tem;
- uint mt=1000,key33=0,ts=0;
- unsigned char num=0,flag;
- unsigned char str1[]=" - - : ";
- unsigned char str2[]=" : : C ";
- void speakerr(uint a);
- void delay(unsigned char z);
- void delay4(uint a);
- void LCD_WRITE_COM(unsigned char com);
- void LCD_WRITE_DATA(unsigned char date);
- void LCD_WRITE_SFM(unsigned char addr,unsigned char date);
- void LCD_WRITE_NYR(unsigned char addr,unsigned char date);
- void LCD_WRITE_WEEK(unsigned char week);
- void LCD_INITIAL();
- void LCD_WRITE_TEMP(uchar addr,uchar temp);
- void keyscan();
- void INITIAL_TEMER0();
- uchar TMPH ,TMPL;
- void w1602c(uchar com);
- void w1602d(uchar data01);
- void delay2(uint ms);
- void delay3(uint us);
- uchar read_byte();
- void write_byte(uchar val);
- void display();
- void DelayUs(uint time);
- void Init_Ds18b20(void);
- void WriteByte(uint date);
- uint ReadTemperature(void);
- void beep1();
- void int0();
- void LCD_WRITE_M(uchar M);
- void main()
- {
- LCD_INITIAL(); //液晶初始化
- INITIAL_1302(); //DS1302初始化
- INITIAL_TEMER0(); //定時器初始化
- while(1)
- {
- keyscan(); //按鍵掃描
- beep1();
-
- if(flag==0) //當標志位為0,允許讀取DS1302數(shù)據(jù),將數(shù)據(jù)送入液晶顯示
- {
- second=READ_1302(0x81);
- LCD_WRITE_SFM(6,second);
- minute=READ_1302(0x83);
- LCD_WRITE_SFM(3,minute);
- hour=READ_1302(0x85);
- LCD_WRITE_SFM(0,hour);
- week=READ_1302(0x8b);
- LCD_WRITE_WEEK(week);
- // LCD_WRITE_NYR(11,chour);
- // LCD_WRITE_NYR(14,cminute);
- day=READ_1302(0x87);
- LCD_WRITE_NYR(6,day);
- month=READ_1302(0x89);
- LCD_WRITE_NYR(3,month);
- year=READ_1302(0x8d);
- LCD_WRITE_NYR(0,year);
- tem=ReadTemperature();
- LCD_WRITE_TEMP(10,tem);
- int0();
- }
-
- }
- }
- void int0()
- {
- if(key33==0)//鬧鐘
- {
-
- LCD_WRITE_NYR(11,chour);
- LCD_WRITE_NYR(14,cminute);
- LCD_WRITE_M(key33);
- }
- if(key33==1)//秒表
- {
-
- LCD_WRITE_NYR(11,tsecond);
- LCD_WRITE_NYR(14,tmsecond);
- LCD_WRITE_M(key33);
- }
- if(key33==2)//定時器
- {
-
- LCD_WRITE_NYR(11,dminute);
- LCD_WRITE_NYR(14,dsecond);
- LCD_WRITE_M(key33);
- }
- }
- void beep1()
- {
- if(chour==hour&&cminute==minute)
- beep=~beep;
- }
- /**********************1602BU份******************************************************/
- void delay(unsigned char z) //1602de延時函數(shù)
- {
- unsigned char x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void LCD_WRITE_COM(unsigned char com)
- {
- LCD_RS=0;
- LCD_RW=0;
- LCD_E=1;
- P0=com;
- delay(5);
- LCD_E=0;
- }
- void LCD_WRITE_DATA(unsigned char date)
- {
- LCD_RS=1;
- LCD_RW=0;
- LCD_E=1;
- P0=date;
- delay(5);
- LCD_E=0;
- }
- void LCD_WRITE_SFM(unsigned char addr,unsigned char date)
- {
- unsigned char shi,ge;
- shi=date/10;
- ge=date%10;
- LCD_WRITE_COM(0x80+0x40+addr);
- LCD_WRITE_DATA(0x30+shi);
- LCD_WRITE_DATA(0x30+ge);
-
- }
- void LCD_WRITE_NYR(unsigned char addr,unsigned char date)
- {
- char shi,ge;
- shi=date/10;
- ge=date%10;
- LCD_WRITE_COM(0x80+addr);
- LCD_WRITE_DATA(0x30+shi);
- LCD_WRITE_DATA(0x30+ge);
- }
- void LCD_WRITE_WEEK(unsigned char week)
- {
- LCD_WRITE_COM(0x80+9);
- switch(week)
- {
- case 1: LCD_WRITE_DATA('1');delay(5);
- break;
- case 2: LCD_WRITE_DATA('2');delay(5);
- break;
- case 3: LCD_WRITE_DATA('3');delay(5);
- break;
- case 4: LCD_WRITE_DATA('4');delay(5);
- break;
- case 5: LCD_WRITE_DATA('5');delay(5);
- break;
- case 6: LCD_WRITE_DATA('6');delay(5);
- break;
- case 7: LCD_WRITE_DATA('7');delay(5);
- ;break;
- }
- }
- void LCD_WRITE_M(uchar M)
- {
- LCD_WRITE_COM(0x80+0x40+0x0e);
- switch(M)
- {
- case 0: LCD_WRITE_DATA('N');delay(5);
- break;
- case 1: LCD_WRITE_DATA('M');delay(5);
- break;
- case 2: LCD_WRITE_DATA('D');delay(5);
- break;
- }
- }
- void LCD_WRITE_TEMP(unsigned char addr,unsigned char temp)
- {
- char shi,ge;
- shi=temp/10;
- ge=temp%10;
- LCD_WRITE_COM(0x80+0x40+addr);
- LCD_WRITE_DATA(0x30+shi);
- LCD_WRITE_DATA(0x30+ge);
-
- }
- void LCD_INITIAL()
- {
- unsigned char i;
- LCD_WRITE_COM(0x38);
- LCD_WRITE_COM(0x0c);
- LCD_WRITE_COM(0x06); //經(jīng)本人試驗證明1602初始化不清屏也可實現(xiàn)
- LCD_WRITE_COM(0x80);
- for(i=0;i<16;i++)
- {
- LCD_WRITE_DATA(str1[i]);
- delay(5);
- }
- LCD_WRITE_COM(0x80+0x40);//液晶第二行顯示
- for(i=0;i<16;i++)
- {
- LCD_WRITE_DATA(str2[i]);
- delay(5);
- }
- }
- /***************************1302部分***************************************************/
- void WRITE_1302(unsigned char addr,unsigned char date)
- {
- unsigned char i;
- RST=0;
- SCLK=0;
- RST=1;
- for(i=8;i>0;i--)
- {
- SCLK=0;
- ACC=addr;
- DIO=ACC0;
- addr>>=1;
- SCLK=1;
- }
- for(i=8;i>0;i--)
- {
- SCLK=0;
- ACC=date;
- DIO=ACC0;
- date>>=1;
- SCLK=1;
- }
- RST=0;
- }
- unsigned char READ_1302(unsigned char addr)
- {
- unsigned char i,date1,date2;
- RST=0;
- SCLK=0;
- RST=1;
- for(i=8;i>0;i--)
- {
- SCLK=0;
- ACC=addr;
- DIO=ACC0;
- addr>>=1;
- SCLK=1;
- }
- for(i=8;i>0;i--)
- {
- ACC7=DIO;
- SCLK=1;
- ACC>>=1;
- SCLK=0;
- }
- RST=0;
- date1=ACC;
- date2=date1/16;
- date1=date1%16;
- date1=date1+date2*10;
- return(date1) ;
- }
- void INITIAL_1302()
- {
- WRITE_1302(WRITE_SECOND,READ_1302(READ_SECOND)&0x7f); //啟動DS1302
- }
- /**************************鍵盤掃描部分***************************************************/
- void keyscan()
- {
- if(key0==0)//確認功能鍵按下
- {
- delay(20);
- if(key0==0)//去抖
- {
- speakerr(mt);
- while(!key0);//釋放
-
- num++;
- switch(num)
- {
- case 1: flag=1; //修改時間,禁止從DS1302讀數(shù)據(jù)
- TR0=0; //定時器關
- LCD_WRITE_COM(0x0f); //光標開始閃爍
- LCD_WRITE_COM(0x80+1);//第一次按下,光標定位到年位置
- break;
- case 2: LCD_WRITE_COM(0x80+4);//第二次按下,光標定位到月位置
- break;
- case 3: LCD_WRITE_COM(0x80+7);//第三次按下,光標定位到日位置
- break;
- case 4: LCD_WRITE_COM(0x80+9);//第四次按下,光標定位到星期位置
- break;
- case 5: LCD_WRITE_COM(0x80+12);//第五次按下,光標定位到定時位置
- break;
- case 6: LCD_WRITE_COM(0x80+15);//第五次按下,光標定位到定分位置
- break;
- case 7: LCD_WRITE_COM(0x80+0x40+1);//第五次按下,光標定位到時位置
- break;
- case 8: LCD_WRITE_COM(0x80+0x40+4);//第六次按下,光標定位到分位置
- break;
- case 9: LCD_WRITE_COM(0x80+0x40+7);//第七次按下,光標定位到秒位置
- break;
- case 10: num=0;//第八次按下,記錄清零
- LCD_WRITE_COM(0x0c);//不顯示光標
- WRITE_1302(WRITE_PROTECT,0x00); //允許寫操作
- WRITE_1302(0x80,(second/10*16)+second%10);//將調節(jié)后的秒寫入DS1302
- WRITE_1302(0x82,(minute/10*16)+minute%10);//將調節(jié)后的分寫入DS1302
- WRITE_1302(0x84,(hour/10*16)+hour%10);//將調節(jié)后的時寫入DS1302
- WRITE_1302(0x8a,(week/10*16)+week%10);//將調節(jié)后的星期寫入DS1302
- WRITE_1302(0x86,(day/10*16)+day%10);//將調節(jié)后的日寫入DS1302
- WRITE_1302(0x88,(month/10*16)+month%10);//將調節(jié)后的月寫入DS1302
- WRITE_1302(0x8c,(year/10*16)+year%10);//將調節(jié)后的年寫入DS1302
- WRITE_1302(WRITE_PROTECT,0x80); //開寫保護
- flag=0; //時間修改完畢,允許液晶從DS1302讀數(shù)據(jù)
- TR0=1;
- break;
-
- }
- }
- }
- if(num==0&&key33==1)
- { if(key1==0)//確認增大鍵按下
- {
- delay(20);
- if(key1==0)//增大鍵確實按下
- {while(!key1);
- if(ts==0)ts++;
- else ts--;
- }
- }
- if(key2==0)//確認增大鍵按下
- {
- delay(20);
- if(key2==0)//增大鍵確實按下
- {while(!key2);
- tsecond=tmsecond=0;
- }
- }
- }
- if(num!=0)
- {
- if(key1==0)//確認增大鍵按下
- {
- delay(20);
- if(key1==0)//增大鍵確實按下
- {
-
- speakerr(mt);
- while(!key1);
- switch(num)
- {
- case 1: year++;//調節(jié)年
- if(year==100)year=0;
- LCD_WRITE_NYR(0,year);//將調節(jié)后的年送入液晶顯示
- LCD_WRITE_COM(0x80+1);//光標回到指定處
- break;
-
- case 2: month++;//調節(jié)月
- if(month==13)month=0;
- LCD_WRITE_NYR(3,month);//將調節(jié)后的月送入液晶顯示
- LCD_WRITE_COM(0x80+4);//光標回到指定處
- break;
-
- case 3: day++;//調節(jié)日
- if(day==32)day=0;
- LCD_WRITE_NYR(6,day);//將調節(jié)后的日送入液晶顯示
- LCD_WRITE_COM(0x80+7);//光標回到指定處
- break;
- case 4: week++;
- if(week==8)week=0;
- LCD_WRITE_WEEK(week);//將調節(jié)后的星期送入液晶顯示
- LCD_WRITE_COM(0x80+9);//光標回到指定處
- break;
- /*******************************************************************************************/
- case 5: if(key33==0)
- {
- chour++;
- if(chour==24)chour=0;
- LCD_WRITE_NYR(11,chour);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
- }
- else if(key33==1)
- {
- tsecond++;
- if(tsecond==60)tsecond=0;
- LCD_WRITE_NYR(11,tsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
- }
- else if(key33==2)
- {
- dminute++;
- if(dminute==60)dminute=0;
- LCD_WRITE_NYR(11,dminute);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
- }
- /***************************************************************************************/
-
- case 6: if(key33==0)
- {
- cminute++;
- if(cminute==60)cminute=0;
- LCD_WRITE_NYR(14,cminute);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
- else if(key33==1)
- {
- tmsecond++;
- if(tmsecond==100)tmsecond=0;
- LCD_WRITE_NYR(14,tmsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
- else if(key33==2)
- {
- dsecond++;
- if(dsecond==60)dsecond=0;
- LCD_WRITE_NYR(14,dsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
-
-
- /********************************************************************************************/
- case 7: hour++;
- if(hour==24)hour=0;
- LCD_WRITE_SFM(0,hour);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+0x40+1);//光標回到指定處
- break;
-
- case 8: minute++;
- if(minute==60)minute=0;
- LCD_WRITE_SFM(3,minute);//將調節(jié)后的分送入液晶顯示
- LCD_WRITE_COM(0x80+0x40+4);//光標回到指定處
- break;
- case 9: second++;
- if(second==60)second=0;
- LCD_WRITE_SFM(6,second);//將調節(jié)后的秒送入液晶顯示
- LCD_WRITE_COM(0x80+0x40+7);//光標回到指定處
- break;
- default:break;
- }
-
- }
- }
- if(key2==0)//確認減小鍵按下
- {
- delay(20);
- if(key2==0)//減小鍵確實按下
- {
- speakerr(mt);
- while(!key2);
- switch(num)
- {
- case 1: year--;//調節(jié)年
- if(year==-1)year=99;
- LCD_WRITE_NYR(0,year);
- LCD_WRITE_COM(0x80+1);
- break;
- case 2: month--;//調節(jié)月
- if(month==-1)month=12;
- LCD_WRITE_NYR(3,month);
- LCD_WRITE_COM(0x80+4);
- break;
- case 3: day--;//調節(jié)日
- if(day==-1)day=31;
- LCD_WRITE_NYR(6,day);
- LCD_WRITE_COM(0x80+7);
- break;
- case 4: week--;//調節(jié)星期
- if(week==0)week=7;
- LCD_WRITE_WEEK(week);
- LCD_WRITE_COM(0x80+9);
- break;
- /**************************************************************************************************/
- case 5: if(key33==0)
- {
- chour--;
- if(chour==-1)chour=23;
- LCD_WRITE_NYR(11,chour);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
- }
- else if(key33==1)
- {
- tsecond--;
- if(tsecond==-1)tsecond=59;
- LCD_WRITE_NYR(11,tsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
-
-
- }
- else if(key33==2)
- {
- dminute--;
- if(dminute==-1)dminute=59;
- LCD_WRITE_NYR(11,dminute);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+12);//光標回到指定處
- break;
-
-
- }
- /*************************************************************************************************/
- case 6:
- if(key33==0)
- {
- cminute--;
- if(cminute==-1)cminute=59;
- LCD_WRITE_NYR(14,cminute);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
- else if(key33==1)
- {
- tmsecond--;
- if(tmsecond==-1)tmsecond=59;
- LCD_WRITE_NYR(14,tmsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
- else if(key33==2)
- {
- dsecond--;
- if(dsecond==-1)dsecond=59;
- LCD_WRITE_NYR(14,dsecond);//將調節(jié)后的小時送入液晶顯示
- LCD_WRITE_COM(0x80+15);//光標回到指定處
- break;
- }
-
-
-
- /***********************************************************************************************/
- case 7: hour--;//調節(jié)時
- if(hour==-1)hour=23;
- LCD_WRITE_SFM(0,hour);
- LCD_WRITE_COM(0x80+0x40+1);
- break;
- case 8: minute--;//調節(jié)分
- if(minute==-1)minute=59;
- LCD_WRITE_SFM(3,minute);
- LCD_WRITE_COM(0x80+0x40+4);
- break;
- case 9: second--;//調節(jié)秒
- if(second==-1)second=59;
- LCD_WRITE_SFM(6,second);
- LCD_WRITE_COM(0x80+0x40+7);
- break;
- default:break;
-
- }
- }
- }
-
- }
- }
- /*******************************蜂鳴器部分******************************************/
- /*-----------定時器0初始化-------------------------*/
- void INITIAL_TEMER0()
- {
- TMOD=0x01;
- TH0=(65536-20000)/256;
- TL0=(65536-20000)%256; //晶振頻率12MHZ 定時20ms作右
-
- EA=1;
- ET0=1;
- TR0=1;
- EX0=1;//開外部中斷0
- IT0=1;//邊沿觸發(fā)
- }
- /*-------------------------------------------*/
- void timer0()interrupt 1
- {
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256; //重裝
-
-
- count++;
- if(ts==1) tmsecond++;
- if(tmsecond==100)
- {
- tmsecond=0;tsecond++;
- if(tsecond==60)tsecond=0;
- }
- if(count==100) //1秒到
- {
- count=0;
- beep=0; //蜂鳴器響
- delay(5);
- beep=1; //蜂鳴器滅
- }
- if(tem>=30)
- {
- beep=0;
- }
- }
- /*****************************18b20部分**********************************************/
- void DelayUs(uint time)
- {
- while(time--);
- }
- /**************************************
- **Function Name:void Init_Ds18b20(void)
- **Description:DS18B20的初始化
- **Input :None
- **Output:None
- **Return: None
- **************************************/
- void Init_Ds18b20(void)
- {
- uchar ready;
- DQ=1; //首先DQ是高電平
- DelayUs(15); //延時,等DQ穩(wěn)定
- DQ=0; //拉低
- DelayUs(75); //延時大概600US
- DQ=1; //拉高(釋放)
- DelayUs(15); //15US左右
- ready=DQ; //開始采樣
- DelayUs(7); //延時 (這個延時在仿真時很重要)
- //return ready; //返回0, 說明總線上有器件響應
- //返回1, 說明總線上沒有器件響應
- }
- /**************************************
- **Fuction Name:void WriteByte(uchar date)
- **Description:寫一個字節(jié)
- **Input:Write Data Byte
- **Output:None
- **Return: None
- **************************************/
- void WriteByte(uint date)
- {
- uint i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=date&0x01;
- DelayUs(7);
- DQ=1;
- date>>=1;
- }
- DelayUs(7);
- }
- /**************************************
- **Function Name:uchar ReadByte(void)
- **Description:讀一個字節(jié)
- **Input:None
- **Output:Read Data Byte
- **Return: Read Data Byte
- **************************************/
- uint ReadByte(void)
- {
- uint i,value;
- for(i=0;i<8;i++)
- {
- DQ=0;
- value>>=1;
- DQ=1;
- if(DQ)
- {
- value|=0x80;
- }
- DelayUs(7);
- }
- return value;
- }
- /**************************************
- **Function Name:uchar ReadTemperature(void)
- **Description:讀出溫度值
- **Input:None
- **Output:Read Temperature
- **Return: Read Temperature
- **************************************/
- uint ReadTemperature(void)
- {
- uint a,b;
- Init_Ds18b20(); //初始化
- WriteByte(0xcc); //跳過ROM
- WriteByte(0x44); //啟動轉換
- DelayUs(35);
-
- Init_Ds18b20(); //初始化
- WriteByte(0xcc); //跳過ROM
- WriteByte(0xbe);
- DelayUs(35); //準備讀取
- a=ReadByte();
- b=ReadByte();
- b<<=4; //讀溫度的整數(shù)部分
- b+=(a&0xf0)>>4;
- return b;
-
- }
- void delay4(uint a)
- {
- for( ; a>0; a--);
- }
- void speakerr(uint a)
- {
- for(;a>0;a--)
- {
-
- beep=~beep;
- beep=~beep;
- }
- }
- /****************************外部中斷1************************************************************/
- void int_0() interrupt 0 using 2
- {
- key33++;
- if(key33==3)key33=0;
-
-
- beep=~beep;
- beep=~beep;
- }
復制代碼
|
|