打印
[APM32F0]

APM32F072硬件IIC读取温湿度传感器

[复制链接]
908|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Alden|  楼主 | 2023-3-22 11:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Alden 于 2023-3-22 11:39 编辑

#技术资源#
APM32F072的硬件IIC例程中只有双板通讯和EEPROM的例程.
但无法直接用来用来跟其他IIC设备通讯,因此参考极海Eval板的硬件IIC例程和网上资料,改写了一个读写温湿度传感器HTU21D的例程。首先是IIC的初始化部分,与EEPROM的相同
#define HTU_I2C                          I2C2
#define HTU_I2C_CLK                      RCM_APB1_PERIPH_I2C2

#define HTU_I2C_SCL_PIN                  GPIO_PIN_10
#define HTU_I2C_SCL_GPIO_PORT            GPIOB
#define HTU_I2C_SCL_GPIO_CLK             RCM_AHB_PERIPH_GPIOB
#define HTU_I2C_SCL_SOURCE               GPIO_PIN_SOURCE_10
#define HTU_I2C_SCL_AF                   GPIO_AF_PIN1

#define HTU_I2C_SDA_PIN                  GPIO_PIN_11
#define HTU_I2C_SDA_GPIO_PORT            GPIOB
#define HTU_I2C_SDA_GPIO_CLK             RCM_AHB_PERIPH_GPIOB
#define HTU_I2C_SDA_SOURCE               GPIO_PIN_SOURCE_11
#define HTU_I2C_SDA_AF                   GPIO_AF_PIN1

void APM_I2C_Init(void)
{
    GPIO_Config_T gpioConfigStruct;
    I2C_Config_T i2cConfigStruct;
   
    /* Enable I2C related Clock */
    RCM_EnableAHBPeriphClock(HTU_I2C_SCL_GPIO_CLK | HTU_I2C_SDA_GPIO_CLK);
    RCM_EnableAPB1PeriphClock(HTU_I2C_CLK);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);

    /* Connect I2C to SCL */
    GPIO_ConfigPinAF(HTU_I2C_SCL_GPIO_PORT, HTU_I2C_SCL_SOURCE, HTU_I2C_SCL_AF);
    /* Connect I2C to SDA */
    GPIO_ConfigPinAF(HTU_I2C_SDA_GPIO_PORT, HTU_I2C_SDA_SOURCE, HTU_I2C_SDA_AF);
    /* Config I2C GPIO */
    gpioConfigStruct.mode = GPIO_MODE_AF;
    gpioConfigStruct.speed = GPIO_SPEED_50MHz;
    gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;
    gpioConfigStruct.pupd = GPIO_PUPD_NO;
    gpioConfigStruct.pin = HTU_I2C_SCL_PIN;
    GPIO_Config(HTU_I2C_SCL_GPIO_PORT, &gpioConfigStruct);

    gpioConfigStruct.pin = HTU_I2C_SDA_PIN;
    GPIO_Config(HTU_I2C_SDA_GPIO_PORT, &gpioConfigStruct);

    /*  Config I2C2 */
    I2C_Reset(HTU_I2C);

    i2cConfigStruct.ack = I2C_ACK_ENABLE;
    i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;
    i2cConfigStruct.address1 = 0x00;
    i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;
    i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;
    i2cConfigStruct.mode = I2C_MODE_I2C;
    i2cConfigStruct.timing = 0xB0420F13;
    I2C_Config(HTU_I2C,&i2cConfigStruct);

    /* Enable I2Cx */
    I2C_Enable(HTU_I2C);
   
    I2CInfo.address = HTU_ADDR_WR;
   
                I2CInfo.addrNum = 1;
               
}
由HTU21D的手册可以看到设备地址和温湿度数据对应的寄存器地址。

进行宏定义
#define HTU_ADDR                0x80
#define HTU_ADDR_WR (HTU_ADDR & 0xFE)
#define HTU_ADDR_RD (HTU_ADDR | 0x01)

//非主机模式
#define HTU_TEMP    0xE3
#define HTU_HUMI    0XE5
然后编写对应的读写函数,根据HTU21D的手册,读数据需要有一个等待转换的时间,最大需要50ms,这个等待需要加入读函数中。
I2C_ERROR_T I2C_HTU_Read(uint8_t* buffer, uint16_t writeAddr, uint8_t number)
{
    I2C_ERROR_T errSta = I2C_OK;
    uint32_t temp = number;
     uint8_t read_Num;


       
    I2C_HandlingTransfer(HTU_I2C, I2CInfo.address, I2CInfo.addrNum, I2C_RELOAD_MODE_SOFTEND, I2C_GENERATE_START_WRITE);
   
    I2CInfo.timeout = I2C_LONG_TIMEOUT;
    while(I2C_ReadStatusFlag(HTU_I2C, I2C_FLAG_TXINT) == RESET)
    {
        if((I2CInfo.timeout--) == 0)
        {
            errSta = I2C_TIMEOUT;
            return I2C_Callback(10);
        }
    }


    I2C_TxData(HTU_I2C, (uint8_t)(writeAddr & 0x00FF));
   
    I2CInfo.timeout = I2C_LONG_TIMEOUT;
    while(I2C_ReadStatusFlag(HTU_I2C, I2C_FLAG_TXCF) == RESET)
    {
        if((I2CInfo.timeout--) == 0)
        {
            errSta = I2C_TIMEOUT;
            return I2C_Callback(13);
        }
    }
        APM_EVAL_DelayMs(50);//等待转化完成
    /* I2Cx send the number of byte to write to eeprom */
    I2C_HandlingTransfer(HTU_I2C, I2CInfo.address, (uint8_t)(number), I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_READ);
   

    for(read_Num = 0; read_Num < temp; read_Num++)
  {
    I2CInfo.timeout = I2C_LONG_TIMEOUT;
    while(I2C_ReadStatusFlag(HTU_I2C, I2C_FLAG_RXBNE) == RESET)
    {
      if((I2CInfo.timeout--) == 0)
      {
        errSta = I2C_TIMEOUT;
                                 return I2C_Callback(14);
      }
    }

    buffer[read_Num] = I2C_RxData(HTU_I2C);
  }
    I2CInfo.timeout = I2C_LONG_TIMEOUT;
    while(I2C_ReadStatusFlag(HTU_I2C, I2C_FLAG_STOP) == RESET)
    {
        if((I2CInfo.timeout--) == 0)
        {
            errSta = I2C_TIMEOUT;
            return I2C_Callback(15);
        }
    }
   
   I2C_ClearStatusFlag(HTU_I2C, I2C_FLAG_STOP);
   
    return errSta;
}
然后配置对应的读数据函数和数据转换函数。
float Htu_Measure(uint8_t _ucOrder)
{
        uint8_t ucaRecvBuf[2] = {0};
        uint8_t ucTmpVal = _ucOrder;
        volatile float fTemp = 0.0;
        volatile float fHumi = 0.0;
        volatile float fRetVal = 0.0;


        I2C_HTU_Read(ucaRecvBuf,ucTmpVal,2);

        ucaRecvBuf[1] &= 0xFC;                //设置分辨率,最低两位为0,温度:14位;湿度:12位        
        fRetVal = (ucaRecvBuf[0] << 8) | ucaRecvBuf[1];        // MSB=(MSB<<=8)+LSB;即将MSB移位到高8位

        if(_ucOrder == HTU_TEMP)
        {
                 fTemp = (175.72) * fRetVal / 65536 - 46.85;//温度:T= -46.85 + 175.72 * ST/2^16
                 
                 return fTemp;
        }
        else if(_ucOrder == HTU_HUMI)
        {
                 fHumi = (fRetVal * 125) / 65536 - 6.00;//湿度: RH%= -6 + 125 * SRH/2^16

                 return fHumi;
        }
        else
        {
                return 0;
        }
}
用串口输出,就得到了当前的温湿度值


HTU21D数据手册.pdf (983.58 KB) APM32F072_EVAL_SDK_v1.0 .zip (1.46 MB)


使用特权

评论回复
评论
forgot 2023-3-31 15:46 回复TA
学习一下 
沙发
averyleigh| | 2023-4-8 22:01 | 只看该作者
软件模拟IIC还是使用硬件IIC,哪个更好

使用特权

评论回复
板凳
usysm| | 2023-4-8 22:08 | 只看该作者
硬件I2C 到底是不是个坑               

使用特权

评论回复
地板
youtome| | 2023-4-9 14:08 | 只看该作者
硬件I2C能与软件I2C一起用一个I2C通道么

使用特权

评论回复
5
lzbf| | 2023-4-9 14:23 | 只看该作者
这个读写的速度可以到多少呢?              

使用特权

评论回复
6
hilahope| | 2023-4-9 15:16 | 只看该作者
硬件II2C和软件I2C有什么区别

使用特权

评论回复
7
backlugin| | 2023-4-9 15:25 | 只看该作者
APM32F072的硬件I2C稳定吗

使用特权

评论回复
8
dspmana| | 2023-4-9 15:32 | 只看该作者
硬件iic应答失败如何自动恢复

使用特权

评论回复
9
chenci2013| | 2023-4-9 15:39 | 只看该作者
有硬件IIC,为什么很多应用,还要模拟IIC

使用特权

评论回复
10
Alden|  楼主 | 2023-5-6 17:14 | 只看该作者
averyleigh 发表于 2023-4-8 22:01
软件模拟IIC还是使用硬件IIC,哪个更好

硬件IIC速度更快,不占用CPU资源。模拟IIC更灵活,更方便移植。

使用特权

评论回复
11
Alden|  楼主 | 2023-5-6 17:15 | 只看该作者
backlugin 发表于 2023-4-9 15:25
APM32F072的硬件I2C稳定吗

测试还挺稳定的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

83

帖子

1

粉丝