STM32F103标准库开发---IIC主控实验---普通I/O口模拟---底层驱动程序
2022-09-20 来源:csdn
IIC底层驱动程序
这次I是普通I/O端口模拟IIC通信实验
具体引脚配置如下:

IIC主控实验----底层驱动GPIO配置
GPIO初始化配置
具体代码如下:
//初始化IIC
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;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 输出高电平---空闲状态
}
时钟线(SCL)—GPIO功能配置
在IIC通信中,主控的时钟线(SCL) 一直是输出状态
具体程序如下:
//时钟线(SCL):PB6输出---高电平
#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)
//时钟线(SCL):PB6输出---低电平
#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)
数据线(SDA)—GPIO功能配置
由于IIC通信是半双工通信方式
因而数据线(SDA)可能会是数据输入,也可能是数据输出。
数据线(SDA)输入模式
//数据线(SDA):PB7输入
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
//读取PB7的电平
#define READ_SDA GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)
数据线(SDA)输出模式
//数据线(SDA):PB7输出
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//数据线(SDA):PB7输出---高电平
#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)
//数据线(SDA):PB7输出---低电平
#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)
IIC主控实验----底层驱动程序
开始信号
当时钟线SCL 为高电平时,数据线SDA 由高电平向低电平跳变。

具体程序如下:
void IIC_Start(void)//开始信号
{
SDA_OUT(); //数据线(SDA)输出模式
SDA_H; //数据线(SDA)输出高电平
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SDA_L; //数据线(SDA)输出低电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
终止信号
当时钟线SCL 为高电平时,数据线SDA 由低电平向高电平跳变。

具体程序如下:
void IIC_Stop(void)//终止信号
{
SDA_OUT(); //数据线(SDA)输出模式
SCL_L; //时钟线(SCL)输出低电平
SDA_L; //数据线(SDA)输出低电平
delay_us(5);
SCL_H; //时钟线(SCL)输出高电平
SDA_H; //数据线(SDA)输出高电平
delay_us(5);
}
应答信号
我们这里写的是IIC主控程序,在读取从控数据的时候,需要回复应答信号。
产生应答信号,表示接收数据成功。

具体程序如下:
void IIC_Ack(void)//产生应答信号
{
SCL_L; //时钟线(SCL)输出低电平
SDA_OUT(); //数据线(SDA)输出模式
SDA_L; //数据线(SDA)输出低电平
delay_us(2);
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
产生非应答信号,表示接收数据失败。

具体程序如下:
void IIC_NAck(void)//不产生应答信号
{
SCL_L; //时钟线(SCL)输出低电平
SDA_OUT(); //数据线(SDA)输出模式
SDA_H; //数据线(SDA)输出高电平
delay_us(2);
SCL_H; //时钟线(SCL)输出高电平
delay_us(5);
SCL_L; //时钟线(SCL)输出低电平
}
IIC主控程序,在写入数据到从控的时候,需要等待应答信号。
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)//等待应答信号
{
int uc=0;
SDA_IN(); //数据线(SDA)输入模式
SDA_H; delay_us(1);
SCL_H; delay_us(1);
while(READ_SDA)
{
uc++;
if(uc>250)//接收应答失败
{
IIC_Stop();//发送终止信号
return 1;
}
}
SCL_L;
return 0;
}
数据传输
IIC总线进行数据传送时,时钟线(SCL)上的信号为高电平期间,数据线(SDA)上的数据必须保持稳定。
只有在时钟线(SCL)上的信号为低电平期间,数据线(SCL)上的高电平或低电平状态才允许变化。

输出到数据线(SDA)上的每个字节必须是8位
数据传送时,先传送最高位(MSB),后传送最低位(LSB)
每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)

IIC主控发送一个字节数据
具体程序如下:
void IIC_Send_Byte(u8 txdata)//发送一个字节数据---高位在前,低位在后
{
SDA_OUT(); //数据线(SDA)输出模式
SCL_L;
for(int t=0;t<8;t++) //高位在前,低位在后。
{
if((txdata&0x80)>>7) SDA_H;
else SDA_L;
txdata<<=1;
delay_us(2);
SCL_H;
delay_us(2);
SCL_L;
delay_us(2);
}
}
IIC主控接收一个字节数据
具体程序如下:
u8 IIC_Read_Byte(unsigned char ack)//读取一个字节数据---ack=1时,发送ACK,ack=0,发送nACK
{
unsigned char rxdata=0,i;
SDA_IN(); //数据线(SDA)输入模式
for(i=0;i<8;i++)
{
SCL_L;
delay_us(2);
SCL_H;
rxdata<<=1;
if(READ_SDA) rxdata++;
delay_us(1);
}
if(!ack) IIC_NAck();
else IIC_Ack();
return rxdata;
}
- 基于STM32F103的AS5600磁编码器角度数据采集
- 基于STM32F103单片机的示波器设计
- STM32F103C8T6开发板+GY521制作无刷四轴飞控详细图文教程
- 入门STM32F103-GPIO输入
- STM32F103C8T6制作舵机/电调测试仪详细图文教程 | 定时器触发ADC | DMA传输 | PWM输出
- STM32F103的硬件I2C调试记录
- 【讲义】STM32的IAP技术,基于CAN总线的STM32F103 BootLoader设计
- 【 STM 系列 】STM32F103 流水灯仿真
- 基于STM32F103C8T6和L298N电机驱动模块调速实验NO.1
- 使用Makefile在Windows环境下编译STM32F103C8T6标准库工程,脱离Keil的指南
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策




