傳感器的接口可以自己修改定義,這里就不放圖了。
單片機源程序如下:
- #include "stc8.h"
- #include "spi.h"
- #include "uart.h"
- #include "delay.h"
- #include "18b20.h"
- #include "stdio.h"
- #define uchar unsigned char
- #define uint unsigned int
- /*********** DHT11定義 *******************/
- sbit dht_dat=P4^1; //dht11的IO口
- uchar dht_num=0; //用于while 循環中計數,超時則跳出循環
- uchar dht_d1=0,dht_d2=0; //依次為濕度整數部分和濕度小數部分
- uchar dht_t1=0,dht_t2=0; //依次為溫度整數部和小數部分
- uchar dht_j=0; //和校驗,可以選擇是否使用,具體參照數據手冊
- /************ DS1302定義 ********/
- //---定義ds1302使用的IO口---//
- sbit SCLK=P2^5;
- sbit DSIO=P2^4;
- sbit rst=P2^3;
- //---定義全局函數---//
- void Ds1302Write(u8 addr, u8 dat);
- u8 Ds1302Read(u8 addr);
- void Ds1302Init();
- void Ds1302ReadTime();
- //---加入全局變量--//
- extern u8 TIME[7]; //加入全局變量
- u8 code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
- u8 code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
- //---DS1302時鐘初始化2017年2月17日星期五20點16分00秒。---//
- //---存儲順序是秒分時日月周年,存儲格式是用BCD碼---//
- u8 TIME[7] = {0x00,0x16, 0x11, 0x20, 0x03, 0x03, 0x19};
- u8 sec,min,hour,sec1,min1,hour1,ri,ri1,yue,yue1,nian,nian1,zhou,zhou1;
- /********* 函數聲明 ************/
- void dht_init();
- uchar read_date();
- void get_temp();
- void Ds1302Write(u8 addr, u8 dat);
- u8 Ds1302Read(u8 addr);
- void Ds1302Init();
- void Ds1302ReadTime();
- void pors(void);
- void display();//顯示函數
- /******** 主函數 ********/
- int main()
- {
- double temp;
- char displaytemp[16];
- dht_init(); //dht11初始化
- uart_init(); //串口初始化
- Lcd_Init(); //初始化OLED
- Ds1302Init(); //ds1302初始化
-
- LCD_Clear(WHITE);
- BACK_COLOR=WHITE;
-
- display();
- while(1)
- {
- /*******ds18b20*****/
-
- temp=readtemp();//讀取溫度
- LCD_ShowChinese(20,150,14,16,BLACK); //水
- LCD_ShowChinese(35,150,0,16,BLACK); //溫
- LCD_ShowString(50,150,":",BLACK); //:
- sprintf(displaytemp,"%7.3f",temp);//打印溫度值
- LCD_ShowString(65,150,displaytemp,RED); //
- LCD_ShowChinese(130,150,8,16,RED); //℃
- /*******ds1302*******/
- pors();
- Ds1302ReadTime();
- LCD_ShowString(20,45,"20",RED); //
- LCD_ShowNum(35,45,nian1,1,RED); //
- LCD_ShowNum(40,45,nian,1,RED); //顯示年
-
- LCD_ShowNum(75,45,yue1,1,RED); //
- LCD_ShowNum(85,45,yue,1,RED); //顯示月
-
- LCD_ShowNum(115,45,ri1,1,RED); //
- LCD_ShowNum(125,45,ri,1,RED); //顯示日
-
- LCD_ShowNum(205,45,zhou,1,RED); //顯示周
-
- LCD_ShowNum(75,80,hour1,1,RED);
- LCD_ShowNum(85,80,hour,1,RED); //時
-
- LCD_ShowNum(115,80,min1,1,RED);
- LCD_ShowNum(125,80,min,1,RED); //分
-
- LCD_ShowNum(155,80,sec1,1,RED);
- LCD_ShowNum(165,80,sec,1,RED); //秒
-
- /*******dht11******/
- get_temp();//讀取溫濕度
- LCD_ShowNum(80,115,dht_t1,2,RED); //顯示溫度整數
- LCD_ShowNum(100,115,dht_t2,1,RED); //顯示濕度小數
- LCD_ShowNum(180,115,dht_d1,2,RED); //顯示濕度整數
- LCD_ShowNum(200,115,dht_d2,1,RED); //顯示濕度小數
- }
- }
-
- /*********************************************************
- DS1302
- **********************************************************/
- /*******************************************************************************
- * 函 數 名 : Ds1302Write
- * 函數功能 : 向DS1302命令(地址+數據)
- * 輸 入 : addr,dat
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302Write(u8 addr, u8 dat)
- {
- u8 n;
- rst = 0;
- _nop_();
- SCLK = 0;//先將SCLK置低電平。
- _nop_();
- rst = 1; //然后將RST(CE)置高電平。
- _nop_();
- for (n=0; n<8; n++)//開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數據從低位開始傳送
- addr >>= 1;
- SCLK = 1;//數據在上升沿時,DS1302讀取數據
- _nop_();
- SCLK = 0;
- _nop_();
- }
- for (n=0; n<8; n++)//寫入8位數據
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1;//數據在上升沿時,DS1302讀取數據
- _nop_();
- SCLK = 0;
- _nop_();
- }
-
- rst = 0;//傳送數據結束
- _nop_();
- }
- /*******************************************************************************
- * 函 數 名 : Ds1302Read
- * 函數功能 : 讀取一個地址的數據
- * 輸 入 : addr
- * 輸 出 : dat
- *******************************************************************************/
- u8 Ds1302Read(u8 addr)
- {
- u8 n,dat,dat1;
- rst = 0;
- _nop_();
- SCLK = 0;//先將SCLK置低電平。
- _nop_();
- rst = 1;//然后將RST(CE)置高電平。
- _nop_();
- for(n=0; n<8; n++)//開始傳送八位地址命令
- {
- DSIO = addr & 0x01;//數據從低位開始傳送
- addr >>= 1;
- SCLK = 1;//數據在上升沿時,DS1302讀取數據
- _nop_();
- SCLK = 0;//DS1302下降沿時,放置數據
- _nop_();
- }
- _nop_();
- for(n=0; n<8; n++)//讀取8位數據
- {
- dat1 = DSIO;//從最低位開始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿時,放置數據
- _nop_();
- }
- rst = 0;
- _nop_(); //以下為DS1302復位的穩定時間,必須的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*******************************************************************************
- * 函 數 名 : Ds1302Init
- * 函數功能 : 初始化DS1302.
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302Init()
- {
- u8 n;
- Ds1302Write(0x8E,0X00); //禁止寫保護,就是關閉寫保護功能
- for (n=0; n<7; n++)//寫入7個字節的時鐘信號:分秒時日月周年
- {
- Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
- }
- Ds1302Write(0x8E,0x80); //打開寫保護功能
- }
- /*******************************************************************************
- * 函 數 名 : Ds1302ReadTime
- * 函數功能 : 讀取時鐘信息
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void Ds1302ReadTime()
- {
- u8 n;
- for (n=0; n<7; n++)//讀取7個字節的時鐘信號:分秒時日月周年
- {
- TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
- }
-
- }
- /***********數據處理***********************/
- void pors(void)
- {
- u8 dat1,dat2;
- Ds1302ReadTime();
-
- dat1=TIME[0]/16; //對秒做進制處理
- dat2=TIME[0]%16;
- sec=(((TIME[0]/16*10)+(TIME[0]%16)))%10;
- sec1=(((TIME[0]/16*10)+(TIME[0]%16)))/10;
-
-
- dat1=TIME[1]/16; //對分做進制處理
- dat2=TIME[1]%16;
- min=(((TIME[1]/16*10)+(TIME[1]%16)))%10;
- min1=(((TIME[1]/16*10)+(TIME[1]%16)))/10;
-
-
- dat1=TIME[2]/16; //對小時做進制處理
- dat2=TIME[2]%16;
- hour=(((TIME[2]/16*10)+(TIME[2]%16)))%10;
- hour1=(((TIME[2]/16*10)+(TIME[2]%16)))/10;
-
- dat1=TIME[3]/16; //對日做進制處理
- dat2=TIME[3]%16;
- ri=(((TIME[3]/16*10)+(TIME[3]%16)))%10;
- ri1=(((TIME[3]/16*10)+(TIME[3]%16)))/10;
-
- dat1=TIME[4]/16; //對月做進制處理
- dat2=TIME[4]%16;
- yue=(((TIME[4]/16*10)+(TIME[4]%16)))%10;
- yue1=(((TIME[4]/16*10)+(TIME[4]%16)))/10;
-
- dat1=TIME[6]/16; //對年做進制處理
- dat2=TIME[6]%16;
- nian=(((TIME[6]/16*10)+(TIME[6]%16)))%10;
- nian1=(((TIME[6]/16*10)+(TIME[6]%16)))/10;
-
- dat1=TIME[5]/16; //對周做進制處理
- dat2=TIME[5]%16;
- zhou=(((TIME[5]/16*10)+(TIME[5]%16)))%10;
- zhou1=(((TIME[5]/16*10)+(TIME[5]%16)))/10;
- }
-
- /*********************************************************
- DHT11
- **********************************************************/
- /*****************************************/
- void dht_init()
- {
- int a;
- for(a=0;a<1000;a++)
- {
- Delay1ms();
- } //DHT11上電前準備時間,大概1s
- dht_dat=1; // 總線準備
- }
- uchar read_date() //接收一個8位數據,先高位后低位
- {
- uchar i,dat;
- for(i=0;i<8;i++) //循環8次,把判斷有“1”輸入到dat中,然后輸出一個八位的數據
- {
- dht_num=2;
- while((dht_dat==0)&&(dht_num++)); //dht_dat 數據線由DH11拉低準備發送數據
- delay_10us();
- delay_10us();
- delay_10us();
- delay_10us();
- dat=dat<<1;
- if(dht_dat==1)
- {
- dht_num=2;
- dat=dat|0x01; //如果DQ的數據是高電平1,則把1放到dat的最低位
- while((dht_dat==1)&&(dht_num++));
- }
- }
- return dat;
- }
- void get_temp() //給DHT11一個開始信號,然后讀取一次數據,共五個8位字節
- { int a;
-
- dht_dat=0;
- for(a=0;a<25;a++)
- {
- Delay1ms();
- }
- dht_dat=1; //單片機給起始脈沖信號
- delay_10us();
- delay_10us();
- delay_10us();
- delay_10us();
- dht_dat=1; //稍作延時,等待DHT11返回響應(響應為低電平)
- if(dht_dat==0) //有響應才接收數據,否則不處理
- {
- dht_num=2;
- while((dht_dat==0)&&(dht_num++));
- dht_num=2;
- while((dht_dat==1)&&(dht_num++));
- dht_d1=read_date();
- dht_d2=read_date();
- dht_t1=read_date();
- dht_t2=read_date();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
STC8A8K dht11 ds1302 ds18b20.zip
(207.17 KB, 下載次數: 111)
2020-5-8 23:14 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|