stm32F103软件模拟iic驱动
时间: 2023-07-14 11:12:27 浏览: 162
stm32f103模拟IIC
5星 · 资源好评率100%
STM32F103可以通过软件模拟I2C总线,下面是一个简单的例子,可以供参考:
```c
#include "stm32f10x.h"
#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7) //SDA输出高电平
#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7) //SDA输出低电平
#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6) //SCL输出高电平
#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6) //SCL输出低电平
#define SDA_read GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7) //读取SDA口状态
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //选择GPIOB的6、7口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最大输出频率50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB的6、7口
SDA_H;
SCL_H;
}
void IIC_Start(void)
{
SDA_H;
SCL_H;
delay_us(4);
SDA_L;
delay_us(4);
SCL_L;
}
void IIC_Stop(void)
{
SDA_L;
SCL_H;
delay_us(4);
SDA_H;
delay_us(4);
}
void IIC_Ack(void)
{
SDA_L;
delay_us(4);
SCL_H;
delay_us(4);
SCL_L;
delay_us(4);
SDA_H;
delay_us(4);
}
void IIC_NAck(void)
{
SDA_H;
delay_us(4);
SCL_H;
delay_us(4);
SCL_L;
delay_us(4);
}
uint8_t IIC_WaitAck(void)
{
uint8_t ucErrTime = 0;
SDA_H;
delay_us(1);
SCL_H;
delay_us(1);
while(SDA_read)
{
ucErrTime++;
if(ucErrTime > 250)
{
IIC_Stop();
return 1;
}
}
SCL_L;
return 0;
}
void IIC_SendByte(uint8_t txd)
{
uint8_t t;
SDA_L;
for(t=0;t<8;t++)
{
if((txd&0x80) >> 7)
SDA_H;
else
SDA_L;
txd <<= 1;
SCL_H;
delay_us(4);
SCL_L;
delay_us(4);
}
}
uint8_t IIC_ReadByte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_H;
for(i=0;i<8;i++)
{
SCL_H;
delay_us(4);
receive <<= 1;
if(SDA_read)
receive++;
SCL_L;
delay_us(4);
}
if (ack)
IIC_Ack();
else
IIC_NAck();
return receive;
}
void IIC_WriteByte(uint8_t device_addr, uint8_t reg_addr, uint8_t data)
{
IIC_Start();
IIC_SendByte(device_addr<<1);
IIC_WaitAck();
IIC_SendByte(reg_addr);
IIC_WaitAck();
IIC_SendByte(data);
IIC_WaitAck();
IIC_Stop();
}
uint8_t IIC_ReadByte(uint8_t device_addr, uint8_t reg_addr)
{
uint8_t data;
IIC_Start();
IIC_SendByte(device_addr<<1);
IIC_WaitAck();
IIC_SendByte(reg_addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte((device_addr<<1) + 1);
IIC_WaitAck();
data = IIC_ReadByte(0);
IIC_Stop();
return data;
}
```
这里用到了GPIOB的6、7口作为I2C总线的SCL和SDA,通过不同的函数可以实现I2C总线的初始化,发送数据和读取数据等操作。需要注意的是,软件模拟I2C总线的速度相对硬件I2C总线较慢,因此在实际使用时需要根据具体情况进行优化。
阅读全文