搜索

[AT32F403/403A] 在AT32F403A上使用模拟IIC时序和SHT31A通信读温湿度

[复制链接]
246|6
 楼主 | 2021-4-10 15:12 | 显示全部楼层 |阅读模式
本帖最后由 hejun96 于 2021-4-10 15:20 编辑

#申请原创# 在AT32F403A上使用模拟GPIO时序和SHT31A通信读温湿度

1.初始化GPIO
  1. #define SCL PBout(6)
  2. #define SDA_OUT PBout(7)
  3. #define SDA_IN PBin(7)

  4. //IO方向操作
  5. #define IIC_INPUT_MODE_SET()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0x40000000;}///GPIOB->CRL|=8<<28;}//IO设置输入模式
  6. #define IIC_OUTPUT_MODE_SET() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;}///GPIOB->CRL|=3<<28;}//IO设置输出模式

  7. float humiture[4];
  8. u8 Refresh_SHT30_Data=0;
  9. u8 humiture_buff1[20];
  10. u8 humiture_buff2[20];

  11. u8 Temperature_L=15;
  12. u8 Humidity_L=50;
  13. u8 Temperature_H=30;
  14. u8 Humidity_H=80;
  15. /*******************************************************************
  16. 函数:SHT30_Init
  17. 功能:
  18. ********************************************************************/
  19. void SHT30_Init(void)
  20. {
  21.    GPIO_InitTypeDef  GPIO_InitStructure;
  22.    
  23.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //使能PB端口时钟
  24.    
  25.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                 //SCL端口配置
  26.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
  27.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  28.    GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA

  29.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                 //SDA端口配置
  30.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
  31.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  32.    GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOA

  33.          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;                                 //SDA端口配置
  34.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //开漏输出
  35.    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
  36.    GPIO_Init(GPIOB, &GPIO_InitStructure);
  37.         
  38.    GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);//SDA/SCL拉高
  39.   GPIO_SetBits(GPIOB,GPIO_Pin_13);
  40.   GPIO_ResetBits(GPIOB,GPIO_Pin_15);
  41.   
  42. }        
  43. /*******************************************************************
  44. 函数:IIC_ACK
  45. 功能:
  46. ********************************************************************/
  47. void IIC_ACK(void)
  48. {
  49.   IIC_OUTPUT_MODE_SET();
  50.   SCL=0;
  51.   delay_us(2);
  52.   SDA_OUT=0;
  53.   delay_us(2);     
  54.   SCL=1;
  55.   delay_us(2);                  
  56.   SCL=0;                     
  57.   delay_us(1);   
  58. }

  59. /*******************************************************************
  60. 函数:IIC_NACK
  61. 功能:
  62. ********************************************************************/
  63. void IIC_NACK(void)
  64. {
  65.   IIC_OUTPUT_MODE_SET();
  66.   SCL=0;
  67.   delay_us(2);
  68.   SDA_OUT=1;
  69.   delay_us(2);      
  70.   SCL=1;
  71.   delay_us(2);                  
  72.   SCL=0;                     
  73.   delay_us(1);   
  74. }
  75. /*******************************************************************
  76. 函数:IIC_wait_ACK
  77. 功能:
  78. ********************************************************************/
  79. u8 IIC_wait_ACK(void)
  80. {
  81.     u8 t = 200;
  82.     IIC_OUTPUT_MODE_SET();
  83.     SDA_OUT=1;
  84.     delay_us(1);
  85.     SCL=0;
  86.     delay_us(1);
  87.     IIC_INPUT_MODE_SET();
  88.     delay_us(1);
  89.     while(SDA_IN)//
  90.     {
  91.         t--;
  92.         delay_us(1);
  93.         if(t==0)
  94.         {
  95.           SCL=0;
  96.           return 1;
  97.         }
  98.         delay_us(1);
  99.     }
  100.     delay_us(1);      
  101.     SCL=1;
  102.     delay_us(1);
  103.     SCL=0;            
  104.     delay_us(1);   
  105.     return 0;        
  106. }
  107. /*******************************************************************
  108. 函数:IIC_Start
  109. 功能:
  110. ********************************************************************/
  111. void IIC_Start(void)
  112. {
  113.   IIC_OUTPUT_MODE_SET();
  114.   SDA_OUT=1;
  115.   SCL=1;
  116.   delay_us(4);        
  117.   SDA_OUT=0;
  118.   delay_us(4);
  119.   SCL=0;
  120. }

  121. /*******************************************************************
  122. 函数:IIC_Stop
  123. 功能:
  124. ********************************************************************/
  125. void IIC_Stop(void)
  126. {
  127.         IIC_OUTPUT_MODE_SET();
  128.         SCL=0;
  129.         SDA_OUT=0;  
  130.         delay_us(4);        
  131.         SCL=1;
  132.         delay_us(4);
  133.         SDA_OUT=1;
  134.         delay_us(4);
  135. }

  136. /*******************************************************************
  137. 函数:IIC_SendByte
  138. 功能:发送字节
  139. ********************************************************************/
  140. void  IIC_SendByte(u8 byte)
  141. {
  142.         u8  BitCnt;
  143.         IIC_OUTPUT_MODE_SET();
  144.         SCL=0;
  145.         for(BitCnt=0;BitCnt<8;BitCnt++)
  146.         {
  147.                 if(byte&0x80) SDA_OUT=1;
  148.                 else SDA_OUT=0;
  149.                 byte<<=1;
  150.                 delay_us(2);
  151.                 SCL=1;
  152.                 delay_us(2);
  153.                 SCL=0;
  154.                 delay_us(2);
  155.         }
  156. }
  157. /*******************************************************************
  158. 函数:IIC_RcvByte
  159. 功能:接收字节
  160. ********************************************************************/
  161. u8 IIC_RcvByte(void)
  162. {
  163.   u8 retc;
  164.   u8 BitCnt;
  165.   retc=0;
  166.   IIC_INPUT_MODE_SET();
  167.   delay_us(1);                    
  168.   for(BitCnt=0;BitCnt<8;BitCnt++)
  169.   {  
  170.         SCL=0;
  171.         delay_us(2);               
  172.         SCL=1;               
  173.         retc=retc<<1;
  174.         if(SDA_IN) retc |=1;
  175.         delay_us(1);
  176.   }
  177.   SCL=0;   
  178.   return(retc);
  179. }
  180. /*******************************************************************
  181. 函数:SHT30_read_result
  182. 功能:温湿度读取
  183. ********************************************************************/
  184. void SHT30_read_result(u8 addr)
  185. {
  186.         u16 tem,hum;
  187.         u16 buff[6];
  188.         float Temperature=0;
  189.         float Humidity=0;
  190.         
  191.         IIC_Start();
  192.         IIC_SendByte(addr<<1 | write);
  193.         IIC_wait_ACK();
  194.         IIC_SendByte(0x2C);
  195.         IIC_wait_ACK();
  196.         IIC_SendByte(0x06);
  197.         IIC_wait_ACK();
  198.         IIC_Stop();
  199.         delay_ms(50);
  200.         IIC_Start();
  201.         IIC_SendByte(addr<<1 | read);
  202.         if(IIC_wait_ACK()==0)
  203.         {
  204.                 buff[0]=IIC_RcvByte();
  205.                 IIC_ACK();
  206.                 buff[1]=IIC_RcvByte();
  207.                 IIC_ACK();
  208.                 buff[2]=IIC_RcvByte();
  209.                 IIC_ACK();
  210.                 buff[3]=IIC_RcvByte();
  211.                 IIC_ACK();
  212.                 buff[4]=IIC_RcvByte();
  213.                 IIC_ACK();
  214.                 buff[5]=IIC_RcvByte();
  215.                 IIC_NACK();
  216.                 IIC_Stop();
  217.         }
  218.         tem = ((buff[0]<<8) | buff[1]);
  219.         hum = ((buff[3]<<8) | buff[4]);
  220.         
  221.         Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)
  222.         Humidity= (100.0*(float)hum/65535.0);// RH = hum*100 / (2^16-1)
  223.   
  224.         
  225.         if((Temperature>=-20)&&(Temperature<=125)&&(Humidity>=0)&&(Humidity<=100))
  226.         {
  227.                 humiture[0]=Temperature;
  228.                 humiture[2]=Humidity;

  229.         }
  230.         hum=0;
  231.         tem=0;

  232.    HMI1_SendNumber("x0.val=",7,Temperature*100,4);//温度,串口屏浮点型数据处理
  233.    HMI1_SendNumber("x1.val=",7,Humidity*100,4);//湿度,串口屏浮点型数据处理
  234.   
  235.     currentDataPoint.valueTemperature =Temperature ;//Add Sensor Data Collection
  236.     currentDataPoint.valueHumidity = Humidity ;//Add Sensor Data Collection
  237.   

  238. }
复制代码
  1. void delay_us(u16 time)
  2. {   
  3.    u16 i=0;  
  4.    while(time--)
  5.    {
  6.       i=10;  //
  7.       while(i--) ;   
  8.    }
  9. }
  10. //
  11. void delay_ms(u16 time)
  12. {   
  13.    u16 i=0;  
  14.    while(time--)
  15.    {
  16.       i=10200;  //
  17.       while(i--) ;   
  18.    }
  19. }
复制代码
延时函数可以用示波器抓,SHT31A发送完字节后在读字节前要延时久一点,我用了delay_ms(50);
建议在主循环中每2s调用SHT30_read_result,可用一个通用定时器的中断做2s中断一次

使用特权

评论回复

评论

weict125 2021-4-13 22:25 回复TA
厉害 
| 2021-4-10 18:37 | 显示全部楼层
这个帖子的含金量确实很高的,不错的帖子,感谢楼主的分享。

使用特权

评论回复
| 2021-4-13 23:11 | 显示全部楼层
感谢楼主的分享,不错的,很棒的。

使用特权

评论回复
| 2021-4-14 20:09 | 显示全部楼层
厉害了

使用特权

评论回复
| 2021-4-17 08:33 | 显示全部楼层
好像有灵感了,I2C循环读取函数

使用特权

评论回复
| 2021-4-17 23:42 | 显示全部楼层
谢谢分享,不过有没有18B20的例子?

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表