由于STM32内部硬件I2C通讯时跑飞,因此使用STM32 GPIO口 模拟 I2C通信如下
AT24C02 测试
单片机:
STMF103C8T6
管脚 :
GPIOB Pin6 ------ SCL
GPIOB Pin7 ------ SDA
使用时只需修改 RCC_APB2Periph_GPIOx;GPIOx; GPIO_Pin_x(SCL);GPIO_Pin_x (SDA) 即可将其移植 程序适配 STM32 标准库
#define AT24C02_RCC RCC_APB2Periph_GPIOB
#define AT24C02_GPIO GPIOB
#define AT24C02_SCL GPIO_Pin_6
#define AT24C02_SDA GPIO_Pin_7
源代码链接:IIC_Protocol.c IIC_Protocol.h AT24C02.c AT24C02.h83/79460827
#include "IIC_Protocol.h"
void IIC_Configuration(uint32_t IIC_RCC, uint16_t IIC_SCL, uint16_t IIC_SDA, GPIO_TypeDef *IIC_GPIO)
{
RCC_APB2PeriphClockCmd(IIC_RCC, ENABLE);
IIC_GPIO_Init(IIC_GPIO, IIC_SCL, IIC_SDA);
}
void IIC_GPIO_Init(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = IIC_SCL | IIC_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(IIC_GPIO, &GPIO_InitStructure);
GPIO_WriteBit(IIC_GPIO, IIC_SCL | IIC_SDA, (BitAction)LOW);
}
void IIC_GPIO_Mode(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_PIN, GPIOMode_TypeDef GPIO_Mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = IIC_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
GPIO_Init(IIC_GPIO, &GPIO_InitStructure);
}
void IIC_Start(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_OUT);
IIC_Output(IIC_GPIO, IIC_SDA, HIGH);
IIC_Output(IIC_GPIO, IIC_SCL, HIGH);
Delay_us(2);
IIC_Output(IIC_GPIO, IIC_SDA, LOW);
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
}
void IIC_Stop(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_OUT);
IIC_Output(IIC_GPIO, IIC_SDA, LOW);
IIC_Output(IIC_GPIO, IIC_SCL, HIGH);
Delay_us(2);
IIC_Output(IIC_GPIO, IIC_SDA, HIGH);
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
Delay_us(5000);
}
void IIC_Transmit_Acknowledge(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_OUT);
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
IIC_Output(IIC_GPIO, IIC_SDA, LOW);
IIC_Output(IIC_GPIO, IIC_SDA, HIGH);
Delay_us(2);
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
}
unsigned char IIC_Receive_Acknowledge(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
unsigned int n = 0;
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_IN);
IIC_Output(IIC_GPIO, IIC_SCL, HIGH);
Delay_us(1);
while(IIC_Input(IIC_GPIO, IIC_SDA) == HIGH)
{
Delay_us(1);
n++;
if(n > 20)
{
IIC_Stop(IIC_GPIO, IIC_SCL, IIC_SDA);
return 1;
}
}
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
return 0;
}
void IIC_Transmit_Byte(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA, unsigned char byte)
{
unsigned char i;
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_OUT);
for(i = 0; i < 8; i++)
{
IIC_Output(IIC_GPIO, IIC_SDA, ((byte & (0x80 >> i)) == (0x80 >> i)));
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
Delay_us(1);
IIC_Output(IIC_GPIO, IIC_SCL, HIGH);
Delay_us(1);
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
}
}
unsigned char IIC_Receive_Byte(GPIO_TypeDef *IIC_GPIO, uint16_t IIC_SCL, uint16_t IIC_SDA)
{
unsigned char i;
unsigned char data = 0;
IIC_GPIO_Mode(IIC_GPIO, IIC_SDA, IIC_IN);
for(i = 0; i < 8; i++)
{
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
IIC_Output(IIC_GPIO, IIC_SCL, HIGH);
data = ((data * 2) | IIC_Input(IIC_GPIO, IIC_SDA));
IIC_Output(IIC_GPIO, IIC_SCL, LOW);
}
return data;
}
|