使用stm32f103c8t6标准库写一个INA3221模块使用IIC
时间: 2024-01-30 19:02:48 浏览: 204
好的,我来给你提供一份简单的代码。
首先,我们需要确定使用哪个I2C总线,以及INA3221的I2C地址。这里假设我们使用I2C1总线,并将INA3221的地址设置为0x40。
```c
#define I2C1_SCL_PIN GPIO_Pin_6
#define I2C1_SDA_PIN GPIO_Pin_7
#define I2C1_PORT GPIOB
#define INA3221_ADDR 0x40
```
然后,我们需要在main函数中初始化I2C总线和INA3221模块。这里我们使用标准库提供的函数来初始化。
```c
int main(void)
{
// 初始化I2C总线
I2C1_Init();
// 初始化INA3221模块
INA3221_Init();
while (1)
{
// 循环读取INA3221的电压值
uint16_t voltage1 = INA3221_ReadVoltage(INA3221_CHANNEL_1);
uint16_t voltage2 = INA3221_ReadVoltage(INA3221_CHANNEL_2);
uint16_t voltage3 = INA3221_ReadVoltage(INA3221_CHANNEL_3);
// 延时一段时间
delay_ms(1000);
}
}
```
接下来,我们需要实现I2C总线的初始化和读写函数。这里我们使用标准库提供的函数来实现。
```c
void I2C1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
// 使能GPIOB和I2C1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// 配置GPIOB6和GPIOB7为复用推挽输出
GPIO_InitStruct.GPIO_Pin = I2C1_SCL_PIN | I2C1_SDA_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C1_PORT, &GPIO_InitStruct);
// 配置I2C1为标准模式,时钟速率为100kHz
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_ClockSpeed = 100000;
I2C_Cmd(I2C1, ENABLE);
I2C_Init(I2C1, &I2C_InitStruct);
}
void I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
;
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
;
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
I2C_SendData(I2C1, reg);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
I2C_GenerateSTOP(I2C1, ENABLE);
}
uint8_t I2C1_Read(uint8_t addr, uint8_t reg)
{
uint8_t data;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
;
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
;
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
;
I2C_SendData(I2C1, reg);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
;
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
;
I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
;
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
;
data = I2C_ReceiveData(I2C1);
return data;
}
```
最后,我们需要实现INA3221模块的初始化和读取函数。
```c
void INA3221_Init(void)
{
// 将模块内部的寄存器配置为默认值
I2C1_Write(INA3221_ADDR, 0x00, 0x7F);
I2C1_Write(INA3221_ADDR, 0x05, 0x7F);
I2C1_Write(INA3221_ADDR, 0x06, 0x7F);
}
uint16_t INA3221_ReadVoltage(INA3221_ChannelTypeDef channel)
{
uint16_t voltage;
uint8_t msb, lsb;
// 读取指定通道的电压值
msb = I2C1_Read(INA3221_ADDR, channel);
lsb = I2C1_Read(INA3221_ADDR, channel + 1);
// 将读取到的数据转换为电压值
voltage = ((msb << 8) | lsb) * 0.008;
return voltage;
}
```
这样,我们就完成了使用stm32f103c8t6标准库写一个INA3221模块使用IIC的代码。如果你还有其他问题或者需要更详细的代码实现,可以再和我联系哦。
阅读全文