找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机读取单总线AM2301温湿度源程序

[复制链接]
跳转到指定楼层
楼主
ID:154876 发表于 2018-12-3 13:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    单片机读取AM2301程序

单片机源程序如下:
  1. //****************************************************************//
  2. //单片机 :AT89S52 或 STC89C52RC
  3. // 功能  :串口发送温湿度数据  波特率 9600
  4. // 晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
  5. //****************************************************************//

  6. #include "reg52.h"
  7. #include <intrins.h>

  8. //用户根据自己的晶振修改相应值
  9. #define FOSC  12000000
  10. #define BAUD  9600

  11. //读传感器 端口位定义,可修改
  12. sbit Sensor_SDA = P1^0;
  13. //sbit Sensor_SCL = P1^1;

  14. // 变量定义
  15. unsigned char Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};
  16. unsigned char Sensor_Check;                  //校验和

  17. unsigned char Sensor_AnswerFlag;  //收到起始标志位
  18. unsigned char Sensor_ErrorFlag;   //读取传感器错误标志
  19. unsigned int  Sys_CNT;
  20. unsigned int  Tmp;

  21. unsigned char *String;

  22. //字符串定义
  23. #define S_Temp "Temp:"
  24. #define S_RH   "RH:"
  25. #define S_CRCT "Check: True"
  26. #define S_CRCF "Check: Wrong"
  27. #define S_Data "Data: "
  28. #define S_NotS "Sensor Not Connected"

  29. /********************************************\
  30. |* 功能: 延时        晶振为12M时                                    *|
  31. |*  t = 1 为 20us  然后成倍增加10us左右                *|
  32. \********************************************/
  33. void Delay_N10us(unsigned char t)
  34. {
  35.     while(t--)
  36.    {
  37.             _nop_();
  38.    }
  39. }
  40. /********************************************\
  41. |* 功能: 延时        晶振为12M时                                        *|
  42. |* 延时大约 1ms                                                            *|
  43. \********************************************/
  44. void Delay_N1ms(unsigned int t)
  45. {
  46.   unsigned int i;
  47.   unsigned int j;
  48.   for(j=t;j>0;j--)
  49.      for(i=124;i>0;i--);  //延时大约 1ms
  50. }
  51. /********************************************\
  52. |* 功能: 初始化串口                                            *|
  53. \********************************************/
  54. void InitUART(void)
  55.   {
  56.     unsigned int iTmpBaud;
  57.     unsigned long lTmpBaud;
  58.     iTmpBaud = 0;
  59.     //首先选定定时器2作为波特率发生器,16位定时器,自动装载
  60.     SCON = 0x50;        //SM0 SM1 SM2 REN TB8 RB8 TI RI                //0   1   0   1   0   0   0  0       
  61.           PCON = 0x00;        //PCON的地址是87H,这里SMOD =0

  62.           T2CON = 0x30;        //TF2 EXF2 RCLK TCLK EXEN2 TR2 C(/T2) CP(/RL2) //0 0 1 1 0 0 0 0
  63.           T2MOD = 0x00;        // /        /        /        /                /        /        T2OE        DCEN   //0 0 0 0 0 0 0 0

  64.           lTmpBaud = FOSC/BAUD;
  65.           lTmpBaud /= 32;                                                //12T-mode
  66.           iTmpBaud = lTmpBaud & 0xFFFF;               
  67.           iTmpBaud = 65536 - iTmpBaud;
  68.           RCAP2H = (iTmpBaud>>8) & 0x0FF;
  69.           RCAP2L = iTmpBaud & 0x0FF;

  70.           RI = 0;                        //清除接收中断标志
  71.           REN = 1;                //允许串行接收
  72.           ES = 1;                        //允许串行中断
  73.           TR2 = 1;                //启动定时器1

  74.           EA=1;//开总中断
  75.   }  

  76. /********************************************\
  77. |* 功能: 串口发送函数                                     *|
  78. \********************************************/
  79. void UARTSend(char UCHAR)
  80.   {
  81.     SBUF=UCHAR;
  82.     while(TI==0);
  83.     TI=0;
  84.   }
  85. /********************************************\
  86. |* 功能: 串口中断函数                                     *|
  87. \********************************************/
  88. void UARTRead(void) interrupt 4
  89.   {
  90.     char temp;
  91.     if(RI)
  92.     {
  93.       RI=0;
  94.       temp = SBUF;
  95.     }
  96.   }
  97. /********************************************\
  98. |* 功能: 串口发送子函数                                 *|
  99. \********************************************/
  100. void UART_PutString(unsigned char *buf)
  101.   {
  102.         while(*buf)
  103.       UARTSend(*buf++);
  104.   }
  105. void UART_PutStringAndNum(unsigned char *buf ,unsigned int num)
  106.   {
  107.         unsigned char a[3],i;
  108.         a[3] = '0'+num%10;
  109.         a[2] = '.';
  110.         a[1] = '0'+num/10%10;
  111.         a[0] = '0'+num/100%10;
  112.         while(*buf)
  113.       UARTSend(*buf++);
  114.         UARTSend(' ');
  115.          for(i=0;i<4;i++)
  116.         {
  117.                 UARTSend(a[i]);
  118.         }
  119.   }
  120. void UART_PutStringAnd_Data(unsigned char *buf ,unsigned char *bufdata)
  121.   {
  122.         unsigned char a[2],i,j;
  123.         while(*buf)
  124.       UARTSend(*buf++);
  125.         UARTSend(' ');
  126.         for(i=0;i<5;i++)
  127.         {
  128.                 a[0] = bufdata[i]/16;
  129.                 a[1] = bufdata[i]%16;
  130.                 for(j=0;j<2;j++)
  131.                 {
  132.                   if(a[j]>9)
  133.                   {
  134.                     a[j] = (a[j]-10)+'A';
  135.                   }
  136.                   else
  137.                   {
  138.                     a[j] = a[j]+'0';
  139.                   }
  140.                   UARTSend(a[j]);
  141.                 }
  142.                 UARTSend(' ');
  143.         }
  144.   }
  145. /********************************************\
  146. |* 功能: 串口发送传感器数据函数                         *|
  147. \********************************************/
  148. void UARTSend_Nbyte(void)
  149.   {
  150.            if(Sensor_AnswerFlag == 1)
  151.            {
  152.               Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];
  153.                   //校验成功
  154.                   if(Sensor_Check ==Sensor_Data[4])       
  155.                   {
  156.                      String = S_RH;//"RH:";          
  157.                  Tmp = Sensor_Data[0]*256+Sensor_Data[1];          
  158.                  UART_PutStringAndNum(String,Tmp);
  159.                             UARTSend(' ');
  160.                  UARTSend(' ');
  161.                 
  162.                          String = S_Temp;// "Temp:";          
  163.                         Tmp = Sensor_Data[2]*256+Sensor_Data[3];          
  164.                  UART_PutStringAndNum(String,Tmp);
  165.                             UARTSend(' ');
  166.                  UARTSend(' ');

  167.                      String = S_CRCT;//"Check: True";
  168.                      UART_PutString(String);
  169.                   }else        //校验失败 送上读到数据
  170.                   {
  171.              String = S_Data;//"Data: ";
  172.                      UART_PutStringAnd_Data(String,Sensor_Data);
  173.                          UARTSend(' ');       
  174.                          UARTSend(' ');
  175.                          String = S_CRCF;//"Check: Wrong";
  176.                      UART_PutString(String);
  177.                   }
  178.                 }// 传感器未连接
  179.                 else
  180.                 {
  181.                    String = S_NotS; //"Sensor Not Connected";
  182.                    UART_PutString(String);
  183.                 }            
  184.             UARTSend(0x0A);

  185.   }  
  186. void Clear_Data (void)
  187.   {
  188.         int i;
  189.         for(i=0;i<5;i++)
  190.         {
  191.            Sensor_Data[i] = 0x00;
  192.          }//接收数据清零
  193.   }


  194. /********************************************\
  195. |* 功能: 读传感器发送的单个字节                *|
  196. \********************************************/
  197. unsigned char Read_SensorData(void)
  198.   {
  199.         unsigned char i,cnt;
  200.         unsigned char buffer,tmp;
  201.         buffer = 0;
  202.         for(i=0;i<8;i++)
  203.         {
  204.                 cnt=0;
  205.                 while(!Sensor_SDA)        //检测上次低电平是否结束
  206.                 {
  207.                   if(++cnt >= 300)
  208.                    {
  209.                           break;
  210.                    }
  211.                 }
  212.                 //延时Min=26us Max50us 跳过数据"0" 的高电平
  213.                 Delay_N10us(2);         //延时30us   
  214.                
  215.                 //判断传感器发送数据位
  216.                 tmp =0;
  217.                 if(Sensor_SDA)         
  218.                 {
  219.                   tmp = 1;
  220.                 }  
  221.                 cnt =0;
  222.                 while(Sensor_SDA)                //等待高电平 结束
  223.                 {
  224.                            if(++cnt >= 200)
  225.                         {
  226.                           break;
  227.                         }
  228.                 }
  229.                 buffer <<=1;
  230.                 buffer |= tmp;       
  231.         }
  232.         return buffer;
  233.   }

  234. /********************************************\
  235. |* 功能: 读传感器                              *|
  236. \********************************************/
  237. unsigned char Read_Sensor(void)
  238.   {
  239.         unsigned char i;
  240.         //主机拉低(Min=800US Max=20Ms)
  241.     Sensor_SDA = 0;
  242.         Delay_N1ms(2);  //延时2Ms
  243.           
  244.         //释放总线 延时(Min=30us Max=50us)
  245.         Sensor_SDA = 1;        
  246.         Delay_N10us(1);//延时30us
  247.         //主机设为输入 判断传感器响应信号
  248.         Sensor_SDA = 1;
  249.                
  250.         Sensor_AnswerFlag = 0;  // 传感器响应标志         

  251.         //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行          
  252.         if(Sensor_SDA ==0)
  253.         {
  254.            Sensor_AnswerFlag = 1;//收到起始信号
  255.            Sys_CNT = 0;
  256.            //判断从机是否发出 80us 的低电平响应信号是否结束         
  257.            while((!Sensor_SDA))
  258.            {
  259.              if(++Sys_CNT>300) //防止进入死循环
  260.                  {
  261.                    Sensor_ErrorFlag = 1;
  262.                    return 0;
  263.                   }
  264.             }
  265.             Sys_CNT = 0;
  266.             //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  267.             while((Sensor_SDA))
  268.             {
  269.                if(++Sys_CNT>300) //防止进入死循环
  270.                    {
  271.                      Sensor_ErrorFlag = 1;
  272.                      return 0;
  273.                    }
  274.             }                  
  275.             // 数据接收        传感器共发送40位数据
  276.             // 即5个字节 高位先送  5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和
  277.             // 校验和为:湿度高位+湿度低位+温度高位+温度低位
  278.             for(i=0;i<5;i++)
  279.             {
  280.               Sensor_Data[i] = Read_SensorData();
  281.             }
  282.           }
  283.           else
  284.           {
  285.             Sensor_AnswerFlag = 0;          // 未收到传感器响应       
  286.           }
  287.           return 1;
  288.   }   

  289. void main(void)
  290. {
  291.   //Sensor_SCL = 0;
  292.   InitUART();  //初始串口发送函数
  293.   while(1)
  294.   {
  295.         Clear_Data();         // 清除收到数据
  296.         Read_Sensor();                  // 读取传感器数据
  297.         UARTSend_Nbyte();          // 串口发送读到传感器数据
  298.     Delay_N1ms(2000);          // 延时 2S(两次读取间隔至少2S)
  299.   }
  300. }
复制代码

所有资料51hei提供下载:
读AM2301程序.zip (35.47 KB, 下载次数: 20)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:466108 发表于 2019-1-10 21:38 | 只看该作者
湿度传感器怎么连接单片机啊?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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