沁恒蓝牙开发(CH585)5、I2C驱动温度传感器
CH585 I2C驱动温度传感器
基于沁恒CH585学习使用I2C驱动温度传感器,获取环境温度。
本文基于原厂EVK修改,路径:EVT\EXAM\I2C 例程。
1、I2C初始化
打开例程后可以看到“i2c_app_init”的初始化API
void i2c_app_init(uint8_t address)
{
i2c_state = I2C_READY;
i2c_send_stop = true;
i2c_in_repstart = false;
GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);
I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable,
I2C_AckAddr_7bit, address);
I2C_ITConfig(I2C_IT_BUF, ENABLE);
I2C_ITConfig(I2C_IT_EVT, ENABLE);
I2C_ITConfig(I2C_IT_ERR, ENABLE);
PFIC_EnableIRQ(I2C_IRQn);
}
初始化API
参数介绍如下:
1、I2C的模式,可配置为多种模式
2、时钟速率:100KHz和400KHz
3、快速模式时的时钟高电平时间的占空比: 1:36% 0:33.3%
4、使能应答与否
5、地址的格式:7bit 或 10nit
6、从机地址:需要填写 8bit地址>>1 位,因为在发送时会左移一位。
如想要发送0X70,需要填写0X70>>1。
I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9,I2C_Ack_Enable,I2C_AckAddr_7bit, address);
2、发送与读取数据
原厂提供的API,在“CH58x_i2c.c”中,只是对I2C相关寄存器做了简单的封装,需要参考I2C的逻辑去组合出完成的收发数据的API。
好处:灵活度相当高,遇到一些奇奇怪怪的非标准I2C协议,就可以自行改动,非常好用
坏处:标准I2C的用户需要自己对着协议文档 和 逻辑分析仪对照调整代码。
好在原厂提供了“app_i2c.c”了,有提供标准I2C的API。
收发数据API
参数介绍如下:
1、从机地址:同上
2、发送\接收数据的地址
3、数据长度
4、是否需要停止位
5、超时时间
i2c_write_to(SLAVE_ADDR >> 1, data_buf, len, true, true);
i2c_read_from(SLAVE_ADDR >> 1, data_buf, len, true, 1000);
3、驱动传感器
3.1、验证初始化传感器
#define SLAVE_ADDR 0x70
void i2c_write(uint8_t *data_buf,uint8_t len){
i2c_write_to(SLAVE_ADDR >> 1, data_buf, len, true, true);
}
void i2c_read(uint8_t *data_buf,uint8_t len){
i2c_read_from(SLAVE_ADDR >> 1, data_buf, len, true, 1000);
}
int main()
{
uint8_t i = 0;
HSECFG_Capacitance(HSECap_18p);
SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
GPIOA_SetBits(GPIO_Pin_14);
GPIOPinRemap(ENABLE, RB_PIN_UART0);
GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
UART0_DefInit();
GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);
PRINT("IIC Host mode\r\n");
i2c_app_init(SLAVE_ADDR >> 1);
uint8_t init_data[]={0xAC,0x33,0x00};
i2c_write(&init_data[0],3);
}
使用逻辑分析仪抓取数据,可见发送的数据正常 和 从机ACK正常
3.2 读取数据
按照传感器规格书,截取-拼接-整合数据
下图是温度传感器的规格书,温度数据在Read的数据的 第3位的高八位 第4位 第5位 组成的。
所以拼接的数据如:
((int32_t)(read_back_data[3]&0x0F)<<16) | ((int32_t)read_back_data[4]<<8) | ((int32_t)read_back_data[5]);
完整的初始化、获取温度、计算温度的代码如下:
int main()
{
uint8_t i = 0;
HSECFG_Capacitance(HSECap_18p);
SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);
GPIOA_SetBits(GPIO_Pin_14);
GPIOPinRemap(ENABLE, RB_PIN_UART0);
GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
UART0_DefInit();
GPIOB_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13, GPIO_ModeIN_PU);
PRINT("IIC Host mode\r\n");
//初始化数据,写
i2c_app_init(SLAVE_ADDR >> 1);
uint8_t init_data[]={0xAC,0x33,0x00};
i2c_write(&init_data[0],3);
DelayMs(80);
//读取温度数据,读
uint8_t read_back_data[7]={0x0};
i2c_read(read_back_data,sizeof(read_back_data));
PRINT("\rRAW DATA: ");
for(int i=0;i<7;i++){
PRINT(" 0x%02x",read_back_data[i]);
}
PRINT("\r");
float temp=0;
data32 = ((int32_t)(read_back_data[3]&0x0F) << 16) | ((int32_t)read_back_data[4] << 8) | ((int32_t)read_back_data[5]);
temp=(data32*200)/1048576-50;
PRINT("Temp %X %f ",data32,temp);
}
3.3 数据分析
运行之后的读取的原始数据 与 计算的数据打印如下:
IIC Host mode
RAW DATA: 0x1c 0x8d 0x1a 0x06 0x2d 0x6e 0xa7
Temp 62D6E 27.000000
温度换算:
404846(62D6E)*200=80969200/1048576=77-50=27
核算后,温度换算的公式正常计算值正确。
按照温度传感器规格书,这个传感器的温度分辨率是0.01℃,但是目前只能采集到整数的温度。
第一个字节是传感器的状态字(见上文LOG),打印的是 0x1C,即:0001 1100
对照后比特位后发现,bit[2] 为1是异常“校准后的电容数据超出CMP中断阈值范”,并且查阅规格书后,发现不能调整。
以上就是CH585 I2C驱动AHT30的完整流程,整理分享供大家参考。
更多推荐
所有评论(0)