使用MSPM0L1306的I2C驱动SHT30温湿度传感器,SHT30的I2C从机地址是0x44,发送指令0x2C06启动单次数据转换,然后读取6个字节的数据获取当前的温湿度。
一、MSPM0L1306片内的I2C的特点:
- MSPM0L1306可以作为I2C的主机,也可以作为从机
- 支持100kbps, 400kbps和1Mbps的通信速率
- 内部包含8字节的接受FIFO和8字节的发送FIFO
- 支持DMA的发送和接收
- 支持SMBus和PMBus
二、编写代码
初始化
在它的文档中,主机称为controller,从机称为target。因此驱动温度传感器的时候,MCU是作为controller的。这里还是要使用CCS里的syscfg模块自动生成初始化代码,将I2C配置成controller,也就是主机模式,使用100kbps的速率,并且使能时钟延长模式,引脚使用PA10作为SDA,PA1作为SCL,见下图
驱动代码
发送和接收数据的步骤:
1. 使用函数DL_I2C_fillControllerTXFIFO()将要发送的数据填充TX的数据FIFO中
2. 使用下面的函数,等待I2C总线空闲
DL_I2C_getControllerStatus(I2C_0_INST) &DL_I2C_CONTROLLER_STATUS_IDLE));
3. 当I2C总线空闲后,可以使用函数DL_I2C_startControllerTransfer()启动发送
4. 等待发送完成
DL_I2C_getControllerStatus(I2C_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) ;
5. 再次等待总线空闲
6. 当I2C总线空闲后,可以使用函数DL_I2C_startControllerTransfer()启动读取
7. 从FIFO中读取数据
while (DL_I2C_isControllerRXFIFOEmpty(I2C_INST));
gRxPacket = DL_I2C_receiveControllerData(I2C_INST);
读取SHT30温湿度传感器的代码如下:
void send_multi_data_by_uart(uint8_t *data,uint16_t len)
{
for(uint16_t i=0;i<len;i++){
DL_UART_transmitDataBlocking(UART_0_INST,data[i]);
}
}
#define I2C_TARGET_ADDRESS (0x44)
uint8_t recv_buf[10];
uint8_t send_buf[2] = {0x2c,0x06};
void read_sensor_data()
{
DL_I2C_fillControllerTXFIFO(I2C_0_INST, &send_buf[0], 2);
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
DL_I2C_startControllerTransfer(I2C_0_INST, I2C_TARGET_ADDRESS,
DL_I2C_CONTROLLER_DIRECTION_TX, 2);
while (DL_I2C_getControllerStatus(I2C_0_INST) &DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
delay_cycles(1000);
DL_I2C_startControllerTransfer(I2C_0_INST, I2C_TARGET_ADDRESS,
DL_I2C_CONTROLLER_DIRECTION_RX, 6);
for (uint8_t i = 0; i < 6; i++) {
while (DL_I2C_isControllerRXFIFOEmpty(I2C_0_INST));
recv_buf[i] = DL_I2C_receiveControllerData(I2C_0_INST);
}
uint16_t temp,humi;
float f_temp,f_humi;
temp = recv_buf[0] << 8;
temp |= recv_buf[1];
f_temp = (temp/65535.0)*175-45;
humi = recv_buf[3] << 8;
humi |= recv_buf[4];
f_humi = (humi/65535.0)*100;
char str[50];
sprintf(str,"T:%.2fc,H:%.2f",f_temp,f_humi);
send_multi_data_by_uart((uint8_t*)str,strlen(str));
}
int main(void)
{
SYSCFG_DL_init();
APP_DL_UART_0_init();
while (1) {
read_sensor_data();
delay_cycles(32000000);
}
}
输出如图所示