萬年歷的簡易設計與仿真
電路原理圖如下:
捕獲.JPG (238.28 KB, 下載次數: 85)
下載附件
仿真結果
2018-8-24 10:47 上傳
0.png (11.9 KB, 下載次數: 76)
下載附件
2018-8-24 17:34 上傳
單片機源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /***********定義LCD功能管腳************************************/
- sbit rs=P2^0; //控制LCD數據或命令的讀寫
- sbit rw=P2^1; //控制LCD讀寫信號
- sbit e=P2^2; //使能LCD
- /***********定義DS1302功能管腳*********************************/
- sbit DSRST = P1^0; //DS1302復位管腳
- sbit DSCLK = P1^1; //DS1302時鐘
- sbit DSIO = P1^2; //控制DS1302數據傳輸
- sbit dq=P3^7; //溫度傳感器I/O口定義
- uint numh=110,numl=50; //上下限溫度
- uchar bai,shi,ge,xiaoshu,fuhao;
- uchar th_temp,tl_temp;
- uchar secondh,secondl,minuteh,minutel,hourh,hourl,second,minute,hour;
- uint monthl,monthh,month,day,datel,dateh,date,year,yearl,yearh;
- void delay_ms(uint z);
- void delay_us(uchar z);
- void lcd1602_init();
- bit judge_lcd();
- void write_com(uchar com);
- void write_date(uchar date);
- void HELLO_lcd();
- void ds18b20_init();
- void write_byte(uchar dat);
- uchar read_byte();
- void display();
- void convert_temp();
- void beyond();
- void ds1302_init();
- uchar read_ds1302();
- void init_ds1302();
- void write_ds1302() ;
- void read1302_write1602 ();
- void HELLO();
- /*********************延時函數*****************/
- void delay_us(uchar z)
- {
- while(z--);
- }
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /********************lcd1602初始化***************************/
- void lcd1602_init()
- {
- write_com(0x01);
- delay_ms(50);
- write_com(0x38);
- delay_ms(50);
- write_com(0x0c);
- delay_ms(50);
- write_com(0x06);
- delay_ms(50);
- }
- /***********************lcd1602忙碌判斷子程序*******************/
- bit judge_lcd()
- {
- bit flag;
- e = 0;
- rs = 0;
- rw = 1;
- e = 1;
- delay_ms(1);
- flag=(bit)(P0&0x80); //狀態位第7位為1時禁止讀寫,為0時可讀寫
- e = 0;
- return flag;
- }
- /**********************lcd1602寫指令子程序*******************/
- void write_com(uchar addr)
- {
-
- while(judge_lcd()); //檢測LCD是否為忙碌狀態
- rs=0;
- rw=0;
- P0=addr;
- delay_us(5);
- e=0;
- delay_us(5);
- e=1;
- delay_us(5);
- e=0;
- }
- /***********************lcd寫數據子程序*******************/
- void write_date(uchar date)
- {
- while(judge_lcd()); //檢測LCD是否為忙碌狀態
- rs=1;
- rw=0;
- P0=date;
- delay_us(5);
- e=0;
- delay_us(5);
- e=1;
- delay_us(5);
- e=0;
- }
- /***********lcd1602寫指令及數據********************************/
- void write_com_date(uint addr,uint date)
- {
- write_com(addr);
- delay_ms(1);
- write_date(date);
- }
- /************************DS18B20初始化************************/
- void ds18b20_init()
- {
- dq=1;
- delay_us(2);
- dq=0;
- delay_us(80);
- dq=1;
- delay_us(2);
- delay_us(40);
- }
- /************************ds18b20寫數據子程序**********************/
- void write_byte(uchar dat)
- {
- uchar i,value;
- dq=1;
- for(i=0;i<8;i++)
- {
- dq=0;
- value=dat&0x01;
- if(value==0)
- {
- dq=0;
- delay_us(10);
- }
- else
- {
- dq=1;
- delay_us(10);
- }
- dq=1;
- dat=dat>>1;
- }
- }
- /************************ds18b20讀數據子程序*********************/
- uchar read_byte()
- {
- uchar i, value;
- dq=1;
- for(i=0;i<8;i++)
- {
- dq=0;
- value=value>>1;
- dq=1;
- delay_us(1);
- if(dq==1)
- value=value|0x80;
- delay_us(10);
- }
- return value;
- }
- /**********************DS1302讀數據子程序********************************/
- uchar read_ds1302(uchar addr)
- {
- uchar i,temp=0x00;
- DSRST=0;
- DSIO=1;
- DSCLK=0;
- DSRST=1;
- for (i=0;i<8;i++) //循環8次 寫入地址數據
- {
- DSCLK=0;
- DSIO=addr&0x01; //每次傳輸低字節
- addr>>=1; //右移一位
- DSCLK=1;
- }
- delay_ms(1);
- if(DSIO)
- temp|=0x80; //每次傳輸低字節
- DSCLK=0;
- temp>>=1;
- for (i=0;i<7;i++) //循環8次 讀取數據
- {
- DSCLK=0;
- if(DSIO)
- temp|=0x80; //每次傳輸低字節
- DSCLK=1;
- temp>>=1; //右移一位
- }
- DSCLK=1;
- DSRST=0;
- DSIO=0;
- return temp; //返回
- }
- /******************ds1302寫指令子程序**********************************/
- void write_ds1302(uchar addr, uchar date)
- {
- uchar i;
- DSRST=0;
- DSCLK=0;
- DSRST=1;
- for (i=0;i<8;i++) //循環8次 寫入地址數據
- {
- DSCLK=0;
- _nop_();
- DSIO=addr&0x01; //每次傳輸低字節
- addr>>=1; //右移一位
- DSCLK=1;
- _nop_();
- }
- for (i=0;i<8;i++) //循環8次 寫入數據
- {
- DSCLK=0;
- _nop_();
- DSIO=date&0x01; //每次傳輸低字節
- date>>=1; //右移一位 DSCLK=1
- DSCLK=1;
- _nop_();
- }
- DSRST=0;
- delay_ms(1);
- }
- /*****************ds1302初始化子程序********************************/
- void ds1302_init()
- {
- if((((second=read_ds1302(0x81))>>7)&&0x01)==1) //讀秒
- {
- write_ds1302(0x8e,0x00); //關閉寫保護
- write_ds1302(0x80,0x00); //00秒
- write_ds1302(0x82,0x54); //54分
- write_ds1302(0x84,0x17); //17點
- write_ds1302(0x86,0x08); //8日
- write_ds1302(0x88,0x06); //6月
- write_ds1302(0x8a,0x05); //星期五
- write_ds1302(0x8c,0x12); //2012年
- write_ds1302(0x8e,0x80); //允許寫保護
- }
- }
- /*****************************溫度轉化與LCD顯示部分****************************/
- void convert_temp()
- {
- uint temp_zhen;
- uchar temp_fu;
- ds18b20_init();
- write_byte(0xcc);
- write_byte(0x44);
- delay_ms(300);
- ds18b20_init();
- write_byte(0xcc);
- write_byte(0xbe);
- tl_temp=read_byte();
- th_temp=read_byte();
- if((th_temp&0xf0)!=0xf0)
- {
- fuhao=0x2b; //正數處理
- temp_zhen=th_temp*256+tl_temp;
- temp_zhen=temp_zhen/16;
- temp_zhen=((tl_temp&0xf0)>>4)|(th_temp<<4);
- bai=temp_zhen/100; //將十進制的每一位都拆開
- shi=temp_zhen/10%10;
- ge=temp_zhen%10;
- xiaoshu=(tl_temp&0x0f)*10*0.0625;
- }
- else
- {
- fuhao=0x2d; //負數處理
- temp_fu=((tl_temp&0xf0)>>4)|(th_temp<<4);
- temp_fu=~temp_fu;
- if((tl_temp&0x0f)==0x00)
- {
- temp_fu=temp_fu+1;
- }
- bai=temp_fu/100;
- shi=temp_fu/10%10;
- ge=temp_fu%10;
- xiaoshu=((~(tl_temp&0x0f)&0x0f)+1)*10*0.0625;
- xiaoshu=xiaoshu%10; //精確到小數點后一位
- }
- if(temp_zhen>numh|temp_fu>numl)
- {
- beyond();
- }
- }
- /**********************lcd1602溫度顯示子程序*********************/
- void display()
- {
- write_com(0xCa);
- write_date(fuhao);
- if(bai!=0) //百位為0不顯示
- {
- write_date(bai+0x30);
- write_date(shi+0x30);
- }
- else if(bai==0&&shi!=0)
- {
- write_date(shi+0x30);
- }
- write_date(ge+0x30);
- write_date(0x2e);
- write_date(xiaoshu+0x30);
- write_date(0x43);
- write_date(0x20);
- }
- /**********************初始歡迎界面函數************************/
- void HELLO()
- {
-
- write_com_date(0x85,'H');
- write_com_date(0x86,'E');
- write_com_date(0x87,'L');
- write_com_date(0x88,'L');
- write_com_date(0x89,'O');
- write_com_date(0xc4,'E');
- write_com_date(0xc5,'V');
- write_com_date(0xc6,'E');
- write_com_date(0xc7,'R');
- write_com_date(0xc8,'Y');
- write_com_date(0xc9,'O');
- write_com_date(0xca,'N');
- write_com_date(0xcb,'E');
- delay_ms(1500);
- }
- /********************超過溫度上下限子程序***********************/
- void beyond()
- {
- uint temp_zhen;
- uchar temp_fu;
- while(1)
- {
- write_com(0xCA);
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- write_date('0');
- read1302_write1602();
- if(temp_zhen<=numh||temp_fu<=numl)
- break;
- }
- }
- /************************從ds1302中讀時間并在LCD1602上顯示***************************/
- void read1302_write1602 ()
- {
- second=read_ds1302(0x81);
- secondl=second&0x0f;
- secondh=second>>4;
- minute=read_ds1302(0x83);
- minutel=minute&0x0f;
- minuteh=minute>>4;
- hour=read_ds1302(0x85);
- hourl=hour&0x0f;
- hourh=hour>>4;
- month=read_ds1302(0x89);
- monthl=month&0x0f;
- monthh=month>>4;
- year=read_ds1302(0x8d);
- yearl=year&0x0f;
- yearh=year>>4;
- date=read_ds1302(0x87);
- datel=date&0x0f;
- dateh=date>>4;
- day=read_ds1302(0x8b);
- day=day&0x0f;
- delay_ms(5);
- write_com_date(0xc7,0x30+secondl);
- write_com_date(0xc6,0x30+secondh);
- write_com_date(0xc5,'-');
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
rl.zip
(123 KB, 下載次數: 44)
2018-8-24 10:44 上傳
點擊文件名下載附件
萬年歷全部程序與電路圖 下載積分: 黑幣 -5
|