找回密码
 立即注册

QQ登录

只需一步,快速开始

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

C51单片机单总线读AM2301系列温湿度传感器示例程序

[复制链接]
跳转到指定楼层
楼主
单片机 :AT89S52 或 STC89C52RC
典型传感器:AM2301
功能  :串口发送温湿度数据  波特率 9600
晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
编译环境:  Keil 4


单片机源程序如下:
  1. //****************************************************************//
  2. //               AM系列读单总线使用范例
  3. //单片机 :AT89S52 或 STC89C52RC
  4. // 功能  :串口发送温湿度数据  波特率 9600
  5. // 晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
  6. // 编译环境:  Keil3
  7. // 公司  :奥松电子   
  8. //****************************************************************//

  9. #include "reg52.h"
  10. #include <intrins.h>

  11. //用户根据自己的晶振修改相应值
  12. #define FOSC  12000000
  13. #define BAUD  9600

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

  17. // 变量定义
  18. unsigned char Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};
  19. unsigned char Sensor_Check;                  //校验和

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

  24. unsigned char *String;

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

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

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

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

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

  77.           EA=1;//开总中断
  78.   }  

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

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

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


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

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

  254.         //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行          
  255.         if(Sensor_SDA ==0)
  256.         {
  257.            Sensor_AnswerFlag = 1;//收到起始信号
  258.            Sys_CNT = 0;
  259.            //判断从机是否发出 80us 的低电平响应信号是否结束         
  260.            while((!Sensor_SDA))
  261.            {
  262.              if(++Sys_CNT>300) //防止进入死循环
  263.                  {
  264.                    Sensor_ErrorFlag = 1;
  265.                    return 0;
  266.                   }
  267.             }
  268.             Sys_CNT = 0;
  269.             //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  270.             while((Sensor_SDA))
  271. ……………………

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

所有资料51hei提供下载:
C51单总线读AM系列示例程序.rar (28.57 KB, 下载次数: 60)





评分

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

查看全部评分

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

使用道具 举报

沙发
ID:586498 发表于 2019-7-23 15:35 | 只看该作者
厉害,收藏了
回复

使用道具 举报

板凳
ID:616896 发表于 2019-12-12 21:45 | 只看该作者
感谢分享
回复

使用道具 举报

地板
ID:616896 发表于 2019-12-13 10:27 | 只看该作者
感谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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