传感器的接口可以自己修改定义,这里就不放图了。
单片机源程序如下:
- #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)
|