STM32配置IIC接口通信方式参考源码
2024-10-09 来源:cnblogs
最近在读取SHT3x系列sensor的温度和湿度,用到的是IIC接口。
顺便写了一下STM32的IIC接口。
这次配置的是STM32内部的IIC接口。
注意:读的时候,怎么发送Ack, 和 NAck信号,参考stm的设计文档。
#include 'Dev_SHT3X.h'
#include 'globalDef.h'
#include #define I2C1_OWN_ADDRESS7 0x0A #define I2C_Speed 40000 #define SHT3X_ADDRESS 0x44 /* read out command */ #define CMD_READH_SHX 0x2c #define CMD_READL_SHX 0x06 /** * SHX device: IIC1 * PB6 - SCL * PB7 - SDA */ static void IIC_gpioConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; /* 使能与 I2C1 有关的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); /* PB6-I2C1_SCL、PB7-I2C1_SDA*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 开漏输出 GPIO_Init(GPIOB, &GPIO_InitStructure); } static void IIC_modeConfig(void) { I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; /* I2C 配置 */ I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */ I2C_InitStructure.I2C_OwnAddress1 = I2C1_OWN_ADDRESS7; /* setting master address. */ I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ; /* enable ack */ I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* 7-bit addressing mode */ I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* communication speed <= 400k */ I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); } void SHT3X_InitDevice(void) { IIC_gpioConfig(); IIC_modeConfig(); } void sht3x_readTempHumi(uint8_t* pBuffer, uint8_t NumByteToRead) { while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* detect IIC busy */ I2C_GenerateSTART(I2C1, ENABLE); /* Send START condition */ /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send slave device address for write */ I2C_Send7bitAddress(I2C1, (SHT3X_ADDRESS << 1), I2C_Direction_Transmitter); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Clear EV6 by setting again the PE bit */ I2C_Cmd(I2C1, ENABLE); /* Send the device address to write to */ I2C_SendData(I2C1, CMD_READH_SHX); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send the device address to write to */ I2C_SendData(I2C1, CMD_READL_SHX); /* Test on EV8 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //------------------------------------------------ /* Send STRAT condition a second time */ I2C_GenerateSTART(I2C1, ENABLE); /* Test on EV5 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send shx address for read */ I2C_Send7bitAddress(I2C1, ((SHT3X_ADDRESS << 1) | 0x01), I2C_Direction_Receiver); /* Test on EV6 and clear it */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* While there is data to be read */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable Acknowledgement */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Send STOP Condition */ I2C_GenerateSTOP(I2C1, ENABLE); } /* Test on EV7 and clear it */ if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { /* Read a byte from the EEPROM */ *pBuffer = I2C_ReceiveData(I2C1); /* Point to the next location where the byte read will be saved */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } } /* Enable Acknowledgement to be ready for another reception */ I2C_AcknowledgeConfig(I2C1, ENABLE); } //----------------------------------------------------------------------------- static float SHT3X_CalcTemperature(uint16_t rawValue) { // calculate temperature [°C] // T = -45 + 175 * rawValue / (2^16-1) return 175.0f * (float)rawValue / 65535.0f - 45.0f; } //----------------------------------------------------------------------------- static float SHT3X_CalcHumidity(uint16_t rawValue) { // calculate relative humidity [%RH] // RH = rawValue / (2^16-1) * 100 return 100.0f * (float)rawValue / 65535.0f; } void sht3x_testTask(void) { uint8_t recBuffer[6]; uint16_t rawdata; float fTemp, fHumi; sht3x_readTempHumi(&recBuffer[0], 6); rawdata = recBuffer[0]; rawdata = (rawdata << 8) + recBuffer[1]; fTemp = SHT3X_CalcTemperature(rawdata); rawdata = recBuffer[3]; rawdata = (rawdata << 8) + recBuffer[4]; fHumi = SHT3X_CalcHumidity(rawdata); enterCriticalSection(); printf('T: %0.2f, H: %0.1frn', fTemp, fHumi); exitCriticalSection(); } #ifndef _DEV_SHT3X_H #define _DEV_SHT3X_H #include 'bsp_iic.h' #include 'bsp_SysConfig.h' extern void SHT3X_InitDevice(void); extern void sht3x_testTask(void); #endif /* _DEV_SHT3X_H */