找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2891|回复: 2
打印 上一主题 下一主题
收起左侧

STC8A8K单片机+DHT11+DS1302+DS18B20源程序

[复制链接]
跳转到指定楼层
楼主
ID:335397 发表于 2020-5-8 23:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
传感器的接口可以自己修改定义,这里就不放图了。

单片机源程序如下:
  1. #include "stc8.h"
  2. #include "spi.h"
  3. #include "uart.h"
  4. #include "delay.h"
  5. #include "18b20.h"
  6. #include "stdio.h"


  7. #define uchar unsigned char
  8. #define uint unsigned int



  9. /***********                DHT11定义                *******************/

  10. sbit dht_dat=P4^1; //dht11的IO口
  11. uchar dht_num=0; //用于while 循环中计数,超时则跳出循环
  12. uchar dht_d1=0,dht_d2=0;        //依次为湿度整数部分和湿度小数部分
  13. uchar dht_t1=0,dht_t2=0;  //依次为温度整数部和小数部分
  14. uchar dht_j=0;        //和校验,可以选择是否使用,具体参照数据手册


  15. /************        DS1302定义        ********/

  16. //---定义ds1302使用的IO口---//
  17. sbit SCLK=P2^5;
  18. sbit DSIO=P2^4;
  19. sbit rst=P2^3;

  20. //---定义全局函数---//
  21. void Ds1302Write(u8 addr, u8 dat);
  22. u8 Ds1302Read(u8 addr);
  23. void Ds1302Init();
  24. void Ds1302ReadTime();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  25. //---加入全局变量--//
  26. extern u8 TIME[7];        //加入全局变量

  27. u8 code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
  28. u8 code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

  29. //---DS1302时钟初始化2017年2月17日星期五20点16分00秒。---//
  30. //---存储顺序是秒分时日月周年,存储格式是用BCD码---//

  31. u8 TIME[7] = {0x00,0x16, 0x11, 0x20, 0x03, 0x03, 0x19};
  32. u8 sec,min,hour,sec1,min1,hour1,ri,ri1,yue,yue1,nian,nian1,zhou,zhou1;

  33. /*********        函数声明        ************/
  34. void dht_init();
  35. uchar read_date();
  36. void get_temp();
  37. void Ds1302Write(u8 addr, u8 dat);
  38. u8 Ds1302Read(u8 addr);
  39. void Ds1302Init();
  40. void Ds1302ReadTime();
  41. void pors(void);
  42. void display();//显示函数

  43. /********                主函数                ********/
  44. int main()
  45. {        
  46.          double temp;
  47.          char displaytemp[16];

  48.          dht_init();                                                //dht11初始化        
  49.          uart_init();                                                //串口初始化
  50.          Lcd_Init();                             //初始化OLED  
  51.    Ds1302Init();                                        //ds1302初始化        
  52.          
  53.          LCD_Clear(WHITE);
  54.          BACK_COLOR=WHITE;
  55.          
  56.          display();

  57.          while(1)
  58.          {
  59.                  /*******ds18b20*****/
  60.                                 
  61.                  temp=readtemp();//读取温度
  62.                  LCD_ShowChinese(20,150,14,16,BLACK);   //水
  63.                  LCD_ShowChinese(35,150,0,16,BLACK);   //温
  64.                  LCD_ShowString(50,150,":",BLACK);                        //:
  65.                  sprintf(displaytemp,"%7.3f",temp);//打印温度值
  66.                  LCD_ShowString(65,150,displaytemp,RED);        //
  67.                  LCD_ShowChinese(130,150,8,16,RED);   //℃
  68.                 /*******ds1302*******/                 
  69.                  pors();
  70.                  Ds1302ReadTime();
  71.                  LCD_ShowString(20,45,"20",RED);        //
  72.                  LCD_ShowNum(35,45,nian1,1,RED);        //
  73.                  LCD_ShowNum(40,45,nian,1,RED);        //显示年
  74.                  
  75.                  LCD_ShowNum(75,45,yue1,1,RED);        //
  76.                  LCD_ShowNum(85,45,yue,1,RED);        //显示月
  77.                  
  78.                  LCD_ShowNum(115,45,ri1,1,RED);        //
  79.                  LCD_ShowNum(125,45,ri,1,RED);        //显示日
  80.                  
  81.                  LCD_ShowNum(205,45,zhou,1,RED);        //显示周
  82.                  
  83.                  LCD_ShowNum(75,80,hour1,1,RED);        
  84.                  LCD_ShowNum(85,80,hour,1,RED);        //时
  85.                  
  86.                  LCD_ShowNum(115,80,min1,1,RED);        
  87.                  LCD_ShowNum(125,80,min,1,RED);        //分
  88.                  
  89.                  LCD_ShowNum(155,80,sec1,1,RED);        
  90.                  LCD_ShowNum(165,80,sec,1,RED);        //秒
  91.                         
  92.                  /*******dht11******/
  93.                  get_temp();//读取温湿度
  94.                  LCD_ShowNum(80,115,dht_t1,2,RED);        //显示温度整数
  95.                  LCD_ShowNum(100,115,dht_t2,1,RED);        //显示湿度小数
  96.                   LCD_ShowNum(180,115,dht_d1,2,RED);        //显示湿度整数
  97.                  LCD_ShowNum(200,115,dht_d2,1,RED);        //显示湿度小数
  98.    }
  99. }


  100. /*********************************************************


  101.                                                                         DS1302

  102. **********************************************************/
  103. /*******************************************************************************
  104. * 函 数 名         : Ds1302Write
  105. * 函数功能                   : 向DS1302命令(地址+数据)
  106. * 输    入         : addr,dat
  107. * 输    出         : 无
  108. *******************************************************************************/

  109. void Ds1302Write(u8 addr, u8 dat)
  110. {
  111.         u8 n;
  112.         rst = 0;
  113.         _nop_();

  114.         SCLK = 0;//先将SCLK置低电平。
  115.         _nop_();
  116.         rst = 1; //然后将RST(CE)置高电平。
  117.         _nop_();

  118.         for (n=0; n<8; n++)//开始传送八位地址命令
  119.         {
  120.                 DSIO = addr & 0x01;//数据从低位开始传送
  121.                 addr >>= 1;
  122.                 SCLK = 1;//数据在上升沿时,DS1302读取数据
  123.                 _nop_();
  124.                 SCLK = 0;
  125.                 _nop_();
  126.         }
  127.         for (n=0; n<8; n++)//写入8位数据
  128.         {
  129.                 DSIO = dat & 0x01;
  130.                 dat >>= 1;
  131.                 SCLK = 1;//数据在上升沿时,DS1302读取数据
  132.                 _nop_();
  133.                 SCLK = 0;
  134.                 _nop_();        
  135.         }        
  136.                  
  137.         rst = 0;//传送数据结束
  138.         _nop_();
  139. }

  140. /*******************************************************************************
  141. * 函 数 名         : Ds1302Read
  142. * 函数功能                   : 读取一个地址的数据
  143. * 输    入         : addr
  144. * 输    出         : dat
  145. *******************************************************************************/

  146. u8 Ds1302Read(u8 addr)
  147. {
  148.         u8 n,dat,dat1;
  149.         rst = 0;
  150.         _nop_();

  151.         SCLK = 0;//先将SCLK置低电平。
  152.         _nop_();
  153.         rst = 1;//然后将RST(CE)置高电平。
  154.         _nop_();

  155.         for(n=0; n<8; n++)//开始传送八位地址命令
  156.         {
  157.                 DSIO = addr & 0x01;//数据从低位开始传送
  158.                 addr >>= 1;
  159.                 SCLK = 1;//数据在上升沿时,DS1302读取数据
  160.                 _nop_();
  161.                 SCLK = 0;//DS1302下降沿时,放置数据
  162.                 _nop_();
  163.         }
  164.         _nop_();
  165.         for(n=0; n<8; n++)//读取8位数据
  166.         {
  167.                 dat1 = DSIO;//从最低位开始接收
  168.                 dat = (dat>>1) | (dat1<<7);
  169.                 SCLK = 1;
  170.                 _nop_();
  171.                 SCLK = 0;//DS1302下降沿时,放置数据
  172.                 _nop_();
  173.         }

  174.         rst = 0;
  175.         _nop_();        //以下为DS1302复位的稳定时间,必须的。
  176.         SCLK = 1;
  177.         _nop_();
  178.         DSIO = 0;
  179.         _nop_();
  180.         DSIO = 1;
  181.         _nop_();
  182.         return dat;        
  183. }

  184. /*******************************************************************************
  185. * 函 数 名         : Ds1302Init
  186. * 函数功能                   : 初始化DS1302.
  187. * 输    入         : 无
  188. * 输    出         : 无
  189. *******************************************************************************/

  190. void Ds1302Init()
  191. {
  192.         u8 n;
  193.         Ds1302Write(0x8E,0X00);                 //禁止写保护,就是关闭写保护功能
  194.         for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
  195.         {
  196.                 Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);        
  197.         }
  198.         Ds1302Write(0x8E,0x80);                 //打开写保护功能
  199. }

  200. /*******************************************************************************
  201. * 函 数 名         : Ds1302ReadTime
  202. * 函数功能                   : 读取时钟信息
  203. * 输    入         : 无
  204. * 输    出         : 无
  205. *******************************************************************************/

  206. void Ds1302ReadTime()
  207. {
  208.         u8 n;
  209.         for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
  210.         {
  211.                 TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
  212.         }
  213.                
  214. }

  215. /***********数据处理***********************/
  216. void pors(void)
  217. {
  218.                 u8 dat1,dat2;
  219.           Ds1302ReadTime();
  220.         
  221.     dat1=TIME[0]/16;   //对秒做进制处理
  222.     dat2=TIME[0]%16;
  223.     sec=(((TIME[0]/16*10)+(TIME[0]%16)))%10;
  224.                 sec1=(((TIME[0]/16*10)+(TIME[0]%16)))/10;
  225.    
  226.         
  227.           dat1=TIME[1]/16;   //对分做进制处理
  228.     dat2=TIME[1]%16;
  229.     min=(((TIME[1]/16*10)+(TIME[1]%16)))%10;
  230.                 min1=(((TIME[1]/16*10)+(TIME[1]%16)))/10;
  231.    
  232.         
  233.           dat1=TIME[2]/16;   //对小时做进制处理
  234.     dat2=TIME[2]%16;
  235.     hour=(((TIME[2]/16*10)+(TIME[2]%16)))%10;
  236.     hour1=(((TIME[2]/16*10)+(TIME[2]%16)))/10;
  237.                
  238.                 dat1=TIME[3]/16;   //对日做进制处理
  239.     dat2=TIME[3]%16;
  240.     ri=(((TIME[3]/16*10)+(TIME[3]%16)))%10;
  241.     ri1=(((TIME[3]/16*10)+(TIME[3]%16)))/10;
  242.                
  243.                 dat1=TIME[4]/16;   //对月做进制处理
  244.     dat2=TIME[4]%16;
  245.     yue=(((TIME[4]/16*10)+(TIME[4]%16)))%10;
  246.     yue1=(((TIME[4]/16*10)+(TIME[4]%16)))/10;
  247.                
  248.                 dat1=TIME[6]/16;   //对年做进制处理
  249.     dat2=TIME[6]%16;
  250.     nian=(((TIME[6]/16*10)+(TIME[6]%16)))%10;
  251.     nian1=(((TIME[6]/16*10)+(TIME[6]%16)))/10;
  252.                
  253.                 dat1=TIME[5]/16;   //对周做进制处理
  254.     dat2=TIME[5]%16;
  255.     zhou=(((TIME[5]/16*10)+(TIME[5]%16)))%10;
  256.     zhou1=(((TIME[5]/16*10)+(TIME[5]%16)))/10;
  257. }
  258.         
  259. /*********************************************************


  260.                                                                         DHT11

  261. **********************************************************/
  262. /*****************************************/
  263. void dht_init()
  264. {
  265.                 int a;
  266.                 for(a=0;a<1000;a++)
  267.                 {
  268.                         Delay1ms();
  269.                 }                                                                                                //DHT11上电前准备时间,大概1s
  270.    dht_dat=1;             //  总线准备
  271. }
  272. uchar read_date()        //接收一个8位数据,先高位后低位
  273. {
  274.         uchar i,dat;
  275.         for(i=0;i<8;i++)   //循环8次,把判断有“1”输入到dat中,然后输出一个八位的数据
  276.         {
  277.                 dht_num=2;
  278.                 while((dht_dat==0)&&(dht_num++)); //dht_dat 数据线由DH11拉低准备发送数据
  279.                 delay_10us();
  280.                 delay_10us();
  281.                 delay_10us();
  282.                 delay_10us();
  283.                 dat=dat<<1;
  284.                 if(dht_dat==1)
  285.                 {
  286.                         dht_num=2;
  287.                         dat=dat|0x01;  //如果DQ的数据是高电平1,则把1放到dat的最低位
  288.                         while((dht_dat==1)&&(dht_num++));
  289.                 }
  290.         }
  291.         return dat;        
  292. }

  293. void get_temp()        //给DHT11一个开始信号,然后读取一次数据,共五个8位字节
  294. {                int a;
  295.                
  296.                 dht_dat=0;
  297.                 for(a=0;a<25;a++)
  298.                 {
  299.                         Delay1ms();
  300.                 }        
  301.                 dht_dat=1;        //单片机给起始脉冲信号

  302.                 delay_10us();
  303.                 delay_10us();
  304.                 delay_10us();
  305.                 delay_10us();
  306.                 dht_dat=1;         //稍作延时,等待DHT11返回响应(响应为低电平)
  307.                 if(dht_dat==0)         //有响应才接收数据,否则不处理
  308.                 {
  309.                                                 dht_num=2;
  310.                                                 while((dht_dat==0)&&(dht_num++));
  311.                                                 dht_num=2;
  312.                                                 while((dht_dat==1)&&(dht_num++));
  313.                                                 dht_d1=read_date();
  314.                                                 dht_d2=read_date();
  315.                                                 dht_t1=read_date();
  316.                                                 dht_t2=read_date();
  317. ……………………

  318. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
STC8A8K dht11 ds1302 ds18b20.zip (207.17 KB, 下载次数: 105)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:314894 发表于 2020-11-15 16:05 | 只看该作者
程序太垃圾了,
回复

使用道具 举报

板凳
ID:151348 发表于 2023-1-31 20:14 | 只看该作者
借用了delay、DS18B20和DHT11的程序,把DHT11.c文件里面的delay(1000)函数用delay.c文件中的Delay800ms()代替,delay(25)用3个Delay10ms()代替,delay(10)用户Delay10ms()代替即可,其余的没问题,good job!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表