#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;

}

写个STM32F103的I2C驱动框架

原文地址: http://www.cveoy.top/t/topic/rnS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录