写个STM32F103的I2C驱动框架
#include "stm32f10x.h"
#define I2C_TIMEOUT 1000
void I2C_Init(I2C_TypeDef* I2Cx) { // I2C GPIO Configuration GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct);
// I2C Configuration
I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_ClockSpeed = 100000;
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_Init(I2Cx, &I2C_InitStruct);
// Enable I2C
I2C_Cmd(I2Cx, ENABLE);
}
void I2C_Write(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t reg, uint8_t val) { // Wait for I2C to become idle uint32_t timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)) { if(--timeout == 0) return; }
// Send start condition
I2C_GenerateSTART(I2Cx, ENABLE);
// Wait for start condition to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if(--timeout == 0)
return;
}
// Send device address for write
I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Transmitter);
// Wait for device address to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if(--timeout == 0)
return;
}
// Send register address
I2C_SendData(I2Cx, reg);
// Wait for register address to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if(--timeout == 0)
return;
}
// Send data to be written
I2C_SendData(I2Cx, val);
// Wait for data to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if(--timeout == 0)
return;
}
// Send stop condition
I2C_GenerateSTOP(I2Cx, ENABLE);
}
uint8_t I2C_Read(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t reg) { uint8_t val;
// Wait for I2C to become idle
uint32_t timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))
{
if(--timeout == 0)
return 0xFF;
}
// Send start condition
I2C_GenerateSTART(I2Cx, ENABLE);
// Wait for start condition to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if(--timeout == 0)
return 0xFF;
}
// Send device address for write
I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Transmitter);
// Wait for device address to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if(--timeout == 0)
return 0xFF;
}
// Send register address
I2C_SendData(I2Cx, reg);
// Wait for register address to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if(--timeout == 0)
return 0xFF;
}
// Send repeated start condition
I2C_GenerateSTART(I2Cx, ENABLE);
// Wait for repeated start condition to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if(--timeout == 0)
return 0xFF;
}
// Send device address for read
I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Receiver);
// Wait for device address to be sent
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if(--timeout == 0)
return 0xFF;
}
// Disable ACK and send stop condition
I2C_AcknowledgeConfig(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
// Wait for data to be received
timeout = I2C_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
{
if(--timeout == 0)
return 0xFF;
}
// Read data and return
val = I2C_ReceiveData(I2Cx);
return val;
}
原文地址: http://www.cveoy.top/t/topic/rnS 著作权归作者所有。请勿转载和采集!