网上很多读写AHT10 /AHT20的代码,但大多都是用IO口模拟实现,这种方式对理解IIC的工作原理及时序很有益处,但在一些对时间要求比较严格的场合下,比如一些带RTOS的软件,可能就不是很合适。
CH582/CH592单片机主攻蓝牙相关的功能,也带有硬件IIC模块。考虑到低功耗蓝牙对时间的把控比较严格,相比软件模拟IIC,硬件IIC能够节省模拟时序代码中“无意义”的等待,且时序更精准,达到更高的通信速率,更适合需要保留BLE功能的场合。
以下代码以aht10 / aht20外设为例,简要描述硬件IIC的代码实现。
首先我们通过aht10 / aht20的规格书,获取读写控制aht10 / aht20的命令:


以及读取到的数据如何转换成我们直观的温湿度值:

根据aht10 / aht20的规格书,我们知道,aht10 / aht20的读写控制主要有4个阶段:初始化、软复位、开始测量温湿度、读取测量数据,接下来我们分别介绍一下各个阶段的代码。
#define AHT10_20_RdAddr 0x71
#define AHT10_20_WrAddr 0x70
#define AHT10_20_InitCmd 0xE1
#define AHT10_20_InitDat1 0x08
#define AHT10_20_InitDat2 0x00
#define AHT10_20_MeasureCmd 0xAC
#define AHT10_20_MeasureDat1 0x33
#define AHT10_20_MeasureDat2 0x00
#define AHT10_20_RESETCmd 0xBA
1、初始化:
void InitAHT10_20(void)
{
GPIOB_ModeCfg(GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_PU); //PB14:SDA,PB15:SCL 内部上拉较弱,可能需要外部上拉
I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, MASTER_ADDR);
//择IIC模式,400k速率,选择占空比,默认开启ACK(接收模式必须开启),作从机时使用地址位数为7位,作从机时的地址(本测试中单片机为主机模式,后面两个参数不起作用)
IIC_Send_Cmd_2Data(AHT10_20_WrAddr,AHT10_20_InitCmd,AHT10_20_InitDat1,AHT10_20_InitDat2);
}
需要注意的是,CH582的IIC接口使用的是PB12及PB13,而CH592使用的是PB14及PB15。
另外,在规格书中,没有找到初始化的命令后面需要接0x08,0x00这两个数据的说明,但网上很多初始化的代码都有发送这两个数据,这里选择保留了这两个数据。不过我试着不发过这两个数据,好象也能正常测量温湿度。
void InitAHT10_20(void)
{
GPIOB_ModeCfg(GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_PU); //PB14:SDA,PB15:SCL 内部上拉较弱,可能需要外部上拉
I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, MASTER_ADDR);
//择IIC模式,400k速率,选择占空比,默认开启ACK(接收模式必须开启),作从机时使用地址位数为7位,作从机时的地址(本测试中单片机为主机模式,后面两个参数不起作用)
// IIC_Send_Cmd_2Data(AHT10_20_WrAddr,AHT10_20_InitCmd,AHT10_20_InitDat1,AHT10_20_InitDat2);
IIC_Send_Cmd(AHT10_20_WrAddr,AHT10_20_InitCmd);
}
发送命令给aht10 / aht20时,我们需要区分命令是几个字节,所以我们有以下代码:
void IIC_Send_Cmd(uint8_t addr,uint8_t cmd)
{
while(I2C_GetFlagStatus(I2C_FLAG_BUSY)); //IIC主机判忙
I2C_GenerateSTART(ENABLE); //起始信号
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));

最低0.47元/天 解锁文章
3396

被折叠的 条评论
为什么被折叠?



