本次测试使用STM32C031的I2C接口应用。首先初始化STM32C031的I2C接口,使用GPIO为PB8和PB9.
生成工程之后就可以使用I2C接口了。
温湿度SHTC3是一个arduino接口扩展板,可以直接插在开发板上。
下面是shtc3的驱动代码:
extern I2C_HandleTypeDef hi2c1;
uint8_t I2C_Write(uint8_t index,uint8_t dev_addr, uint16_t cmd,uint32_t len,uint8_t *str,uint32_t num)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&hi2c1, dev_addr<<1, cmd, I2C_MEMADD_SIZE_16BIT, str, num, 1000);
return status;
}
uint8_t I2C_Read(uint8_t index,uint8_t dev_addr, uint16_t cmd,uint32_t len,uint8_t *str,uint32_t num)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Read(&hi2c1, dev_addr<<1, cmd, I2C_MEMADD_SIZE_16BIT, str, num, 1000);
return status;
}
void shtc3_gpio_init(void)
{
}
void SHTC3_WriteCmd(uint16_t cmd)
{
uint8_t cbuf[2];
cbuf[0]=cmd>>8;
cbuf[1]=cmd&0xff;
I2C_Write(0,SHTC3_ADDRESS,cmd,2,cbuf,0);
}
void SHTC3_ReadData(uint16_t cmd,uint8_t *buff,uint32_t len)
{
uint8_t cbuf[2];
cbuf[0]=cmd>>8;
cbuf[1]=cmd&0xff;
I2C_Read(0,SHTC3_ADDRESS,cmd,2,buff,len);
}
int SHTC3_CalcTemperature(uint16_t rawValue)
{
// calculate temperature
// T = -45 + 175 * rawValue / 2^16
return (((175*1 * rawValue)>>16) - 45*1); //放大100倍
}
int SHTC3_CalcHumidity(uint16_t rawValue)
{
// calculate relative humidity
// RH = rawValue / 2^16 * 100
return ((100 * 1 * rawValue)>>16); //放大100倍
}
static uint8_t SHTC3_CheckCRC(uint8_t *buff, uint32_t nbyte)
{
uint32_t i; // byte counter
uint8_t bit; // bit mask
uint8_t crc = 0xFF; // calculated checksum
// calculates 8-Bit checksum with given polynomial
for(i = 0; i < nbyte; i++)
{
crc ^= (buff[i]);
for(bit = 8; bit > 0; --bit)
{
if(crc & 0x80) {
crc = (crc << 1) ^ SHTC3_CRC_POLYNOMIAL;
} else {
crc = (crc << 1);
}
}
}
return crc;
}
uint16_t SHTC3_Init(void)
{
uint16_t shtc3_id;
uint8_t buff[4]={0};
shtc3_id = 0;
shtc3_gpio_init();
HAL_Delay(1);
SHTC3_ReadData(SHTC3_REG_ID,buff,3);
if(buff[2] != SHTC3_CheckCRC(buff,2))
{
return -1;
}
HAL_Delay(10);
SHTC3_WriteCmd(SHTC3_REG_WAKEUP);
shtc3_id = (buff[0]<<8)|buff[1];
return shtc3_id;
}
uint8_t SHTC3_GetMode1_TempRH(int *temp, int *humi)
{
uint8_t buff[8]={0};
SHTC3_ReadData(SHTC3_REG_CELPM_TEMP_RH,buff,6);
if((buff[2] != SHTC3_CheckCRC(buff,2))||(buff[5] != SHTC3_CheckCRC(&buff[3],2)))
{
return 1;
}
*temp = SHTC3_CalcTemperature((buff[0]<<8)|buff[1]);
*humi = SHTC3_CalcHumidity((buff[3]<<8)|buff[4]);
return 0;
}
使用串口shell命令来测试一下:
void shell_shtc3(char argc, char *argv)
{
int temp,rh;
printf("shtc3 id=0x%X:\r\n",temp = SHTC3_Init());
if(temp != -1)
{
SHTC3_GetMode1_TempRH(&temp,&rh);
printf("temp=%d,\t rh=%d \r\n",temp,rh);
}
}
NR_SHELL_CMD_EXPORT(shtc3, shell_shtc3, "get shtc3 data.");
下面编译下载到开发板上看看效果。