【AT-START-F423测评】10.使用硬件I2C读取DHTC12温湿度数据

之前用模拟I2C的方式读取了BMP280的数据,这次换用硬件I2C实现对DHTC12温湿度的读取
在AT32 Work Bench中开启I2C1
 


默认使用PC0和PC1来通讯,参数设置参考DHTC12的手册

 


AT32已经提供了一个封装好的I2C操作库

 


不过还是想自己实现一下I2C通讯代码

复制

#define AT32I2C_TIMEOUT 0xFFFF



void yuyy_hard_iic_reset_ctrl2_register(i2c_type *iicx)

{

  iicx->ctrl2_bit.saddr     = 0;

  iicx->ctrl2_bit.readh10   = 0;

  iicx->ctrl2_bit.cnt       = 0;

  iicx->ctrl2_bit.rlden     = 0;

  iicx->ctrl2_bit.dir       = 0;

}



uint8_t yuyy_hard_iic_wait_flag(i2c_type *iicx,uint32_t flag,flag_status status)

{

    uint16_t timeout = AT32I2C_TIMEOUT;

    while(i2c_flag_get(iicx, flag) != status)

    {

        timeout -= 1;

        if(timeout == 0)

            return 1;

    }

    return 0;

}



uint8_t yuyy_hard_iic_master_sendstop(i2c_type *iicx)

{

    i2c_stop_generate(iicx);

    if(yuyy_hard_iic_wait_flag(iicx,I2C_STOPF_FLAG,SET))

        return 1;

    i2c_flag_clear(iicx, I2C_STOPF_FLAG);

    return 0;

}



uint8_t yuyy_hard_iic_master_sendstart(i2c_type *iicx,uint8_t devaddr,i2c_start_mode_type startmode,i2c_reload_stop_mode_type stopmode,uint8_t datalen)

{

    uint16_t timeout = AT32I2C_TIMEOUT;

    if(yuyy_hard_iic_wait_flag(iicx,I2C_BUSYF_FLAG,RESET))

        return 1;

    i2c_transmit_set(iicx, devaddr<<1, datalen, stopmode, startmode);

    return 0;

}



uint8_t yuyy_hard_iic_master_senddatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)

{

    uint8_t i=0;



    while(i<datalen)

    {

        if(yuyy_hard_iic_wait_flag(iicx,I2C_TDIS_FLAG,SET))

        {

            if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)

            {

                i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);

                return 3;

            }

            yuyy_hard_iic_master_sendstop(iicx);

            return 2;

        }

        if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)

        {

            i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);

            return 3;

        }

        i2c_data_send(iicx, datas[i]);

        i += 1;

    }

    return 0;

}



uint8_t yuyy_hard_iic_master_readdatas(i2c_type *iicx,uint8_t *datas,uint8_t datalen)

{

    uint8_t i=0;

    

    while(i<datalen)

    {

        if(yuyy_hard_iic_wait_flag(iicx,I2C_RDBF_FLAG,SET))

        {

            if(i2c_flag_get(iicx, I2C_ACKFAIL_FLAG) != RESET)

            {

                i2c_flag_clear(iicx, I2C_ACKFAIL_FLAG);

                return 3;

            }

            yuyy_hard_iic_master_sendstop(iicx);

            return 2;

        }

        datas[i] = i2c_data_receive(iicx);

        i += 1;

    }

    return 0;

}



uint8_t yuyy_hard_iic_master_sendregdatas(i2c_type *iicx,uint8_t devaddr,uint16_t regaddr,uint8_t regaddrlen,uint8_t *datas,uint8_t datalen)

{

    uint8_t err = 0,regdata[2];

    err = yuyy_hard_iic_master_sendstart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,regaddrlen+datalen);

    if(err == 0 && regaddrlen > 0)

    {

        regdata[0] = (regaddr >> 8)&0xFF;

        regdata[1] = regaddr&0xFF;

        if(regaddrlen == 1)

            regdata[0] = regaddr&0xFF;

        err = yuyy_hard_iic_master_senddatas(iicx,regdata,regaddrlen);

    }

    if(err == 0)

        err = yuyy_hard_iic_master_senddatas(iicx,datas,datalen);

    if(err == 0 && yuyy_hard_iic_wait_flag(iicx,I2C_TDC_FLAG,SET))

            err = 4;

    if(err == 0)

        err = yuyy_hard_iic_master_sendstop(iicx);

    if(err != 0)

        yuyy_hard_iic_reset_ctrl2_register(iicx);

    return err;

}

uint8_t yuyy_hard_iic_master_readregdatas(i2c_type *iicx,uint8_t devaddr,uint16_t regaddr,uint8_t regaddrlen,uint8_t *datas,uint8_t datalen)

{

    uint8_t err = 0,regdata[2];

    if(regaddrlen > 0)

    {

        regdata[0] = (regaddr >> 8)&0xFF;

        regdata[1] = regaddr&0xFF;

        if(regaddrlen == 1)

            regdata[0] = regaddr&0xFF;

        err = yuyy_hard_iic_master_sendstart(iicx,devaddr,I2C_GEN_START_WRITE,I2C_SOFT_STOP_MODE,regaddrlen);

        if(err == 0)

            err = yuyy_hard_iic_master_senddatas(iicx,regdata,regaddrlen);

        if(err == 0 && yuyy_hard_iic_wait_flag(iicx,I2C_TDC_FLAG,SET))

            err = 4;

    }

    if(err == 0)

        i2c_transmit_set(iicx, devaddr<<1, datalen, I2C_SOFT_STOP_MODE, I2C_GEN_START_READ);

    if(err == 0)

        err = yuyy_hard_iic_master_readdatas(iicx,datas,datalen);

    if(err == 0)

        err = yuyy_hard_iic_master_sendstop(iicx);

    if(err != 0)

        yuyy_hard_iic_reset_ctrl2_register(iicx);

    return err;

}

DHTC12通讯代码

复制

#define DHTC12_I2C_ADDR 0x44



static uint16_t HumA,HumB;



uint8_t yuyy_dhtc12_writecmd(YUYY_DHTC12_DEV_t *dhtc12_dev,uint16_t cmd)

{

        return dhtc12_dev->iic_senddatas_func(dhtc12_dev->iicx,DHTC12_I2C_ADDR,cmd,2,NULL,0);

}



uint8_t yuyy_dhtc12_readdatas(YUYY_DHTC12_DEV_t *dhtc12_dev,uint8_t *rdatas,uint8_t rlen)

{

        return dhtc12_dev->iic_readdatas_func(dhtc12_dev->iicx,DHTC12_I2C_ADDR,0,0,rdatas,rlen);

}



uint8_t yuyy_dhtc12_readcmd(YUYY_DHTC12_DEV_t *dhtc12_dev,uint16_t cmd,uint8_t *rdatas,uint8_t rlen)

{

        return dhtc12_dev->iic_readdatas_func(dhtc12_dev->iicx,DHTC12_I2C_ADDR,cmd,2,rdatas,rlen);

}



//初始化,获取湿度运算系数

void yuyy_dhtc12_init(YUYY_DHTC12_DEV_t *dhtc12_dev)

{

    uint8_t x;

    if(!dhtc12_dev->delayms_func)

        dhtc12_dev->delayms_func = yuyy_delay_ms;

    //复位传感器

    yuyy_dhtc12_writecmd(dhtc12_dev,0x30A2);

    yuyy_dhtc12_readcmd(dhtc12_dev,0xD208,&x,1);

    HumA = (x<<8)&0xFF00;

    yuyy_dhtc12_readcmd(dhtc12_dev,0xD209,&x,1);

    HumA |= x;

    

    yuyy_dhtc12_readcmd(dhtc12_dev,0xD20A,&x,1);

    HumB = (x<<8)&0xFF00;

    yuyy_dhtc12_readcmd(dhtc12_dev,0xD20B,&x,1);

    HumB |= x;

    //HumA=0x7168;  HumB=0x2D73;

    //ReadDatSH[6]={0xF3, 0xA9, 0xC0, 0x41, 0xB4, 0x87}

    //27.6 48.4%

}



const uint16_t POLYNOMIAL = 0x131; //P(x)=x^8+x^5+x^4+1 = 100110001



uint8_t yuyy_dhtc12_checkcrc(uint8_t Data[], uint8_t nbrOfBytes) 

{

    uint8_t crc = 0xff; //0

    uint8_t byteCtr,Bit;

    //calculates 8-Bit checksum with given polynomial

    for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)

    { 

        crc ^= (Data[byteCtr]);

        for (Bit = 8; Bit > 0; --Bit)

        { 

            if (crc & 0x80) 

                crc = (crc << 1) ^ POLYNOMIAL;

            else 

                crc = (crc << 1);

        }

    }

    if (crc != Data[nbrOfBytes])

    {

        Data[nbrOfBytes] = crc;

        return 0x01;

    }

    else 

        return 0;

}



//单次触发温湿度测量

uint8_t yuyy_dhtc12_readHT(YUYY_DHTC12_DEV_t *dhtc12_dev,float *tem,float *hum)

{

    uint8_t i=0,errRe,ReadDatSH[6],CalCRC[3],errorflag=0;

    int16_t TemBuf;

    uint16_t CapBuf;

    errRe = yuyy_dhtc12_writecmd(dhtc12_dev,0x2C10);

    if(errRe)

        errRe = yuyy_dhtc12_writecmd(dhtc12_dev,0x2C10);

    if(errRe)

    {

        return 0x10|errRe; //发送命令失败

    }

    

    dhtc12_dev->delayms_func(100);

    errRe = yuyy_dhtc12_readdatas(dhtc12_dev,ReadDatSH,6);



    if(errRe)

    {

        return 0x20|errRe; //接收数据失败

    }

    CalCRC[0] = ReadDatSH[0];

    CalCRC[1] = ReadDatSH[1];

    CalCRC[2] = ReadDatSH[2];

    errorflag = yuyy_dhtc12_checkcrc(CalCRC,2);

    if(errorflag==0)

    {

        TemBuf = (int16_t)(((ReadDatSH[0]<<8)&0xFF00)|ReadDatSH[1]);

        *tem = 40+(float)TemBuf/256.0;

    }

    CalCRC[0] = ReadDatSH[3];

    CalCRC[1] = ReadDatSH[4];

    CalCRC[2] = ReadDatSH[5];

    errorflag <<= 1;

    errorflag |= yuyy_dhtc12_checkcrc(CalCRC,2);

    if(errorflag==0)

    {

        CapBuf = (uint16_t)(((ReadDatSH[3]<<8)&0xFF00)|ReadDatSH[4]);

        *hum = (float)(CapBuf-HumB)*60.0/(float)(HumA-HumB)+30;

        //20℃为5个湿度点  即1℃为0.25个湿度点  0.1℃为0.025

        *hum = *hum+ 0.25*(*tem-25);

        if(*hum>100)

            *hum = 99.9;

        else if(*hum<0)

            *hum = 0;

    }

    return errorflag;        

}

初始化和读取温湿度并打印出来

复制

YUYY_DHTC12_DEV_t dhtc12_dev;

void dhtc12_init()

{

    dhtc12_dev.iicx = I2C1;

    dhtc12_dev.iic_readdatas_func = (yuyy_iic_master_readdatas_func_t)yuyy_hard_iic_master_readregdatas;

    dhtc12_dev.iic_senddatas_func = (yuyy_iic_master_senddatas_func_t)yuyy_hard_iic_master_sendregdatas;

    yuyy_dhtc12_init(&dhtc12_dev);

}



void dhtc12_readTH()

{

    float humi,temp;

    uint8_t result = yuyy_dhtc12_readHT(&dhtc12_dev,&temp,&humi);

    if(YUYY_DHT11_OK == result)

    {

        printf("DHTC12 读取温度:%.1f℃ 湿度:%.1f%%\r\n",temp,humi);

    }

    else

    {

        printf("DHTC12 读取温度错误:%d\r\n",result);

    }

}

运行效果

1
---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3338286-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值