此为软件模拟IIC,可以直接移植到HAL库使用。.h文件需要自己做函数声明这里就不再放出,如有问题大家可以讨论。
使用的时候只需要更改SDA 和SCL引脚的宏定义就可以移植使用,当然IIC协议其实就是根据IIC的时序图编写代码,主要内容就是包括开始信号,停止信号以及发送数据的格式、接收数据和数据的应答。
此IIC代码可以供所有的IIC模块使用,包括IIC必须要的几个基本功能代码中都已经给出。下面开始来介绍IIC协议。
IIC协议具体内容
写数据 :主机给从机发 从机只收 SDA为输出模式
读数据: 从机给主机发 主机收 SDA为输入模式
IIC具体内容:(只规定了开始信号 停止信号 8位数据(发8位收一位ACK) ACK应答(低电位有效) 具体使用IIC模块要看模块数据的发送协议) 时钟线为高电平期间数据有效 ACK应答的时候SDA的模式为输入模式(因为要判断SDA的电平状态)
应答:
MCU一次只能和IIC总线的一个从机进行通信文章来源:https://www.toymoban.com/news/detail-605639.html
SDA数据线 SCLK时钟线文章来源地址https://www.toymoban.com/news/detail-605639.html
具体代码如下:包括IIC开始 停止 应答 发送 接收数据的几种模式
#include "iic.h"
#include "delay.h"
#include "gpio.h"
/**********************************************************
ST芯片单片机HAL库之IIC软件模拟
作者:十一
**********************************************************/
/**********************************************************
1.IIC软件模拟 使用HAL库时
2.需要STM32CubeMX配置初始化的相关引脚为GPIO模式 SDA SCL初始状态下都是输出 推挽 上拉模式
4.初始状态下SDA 与 SCL要给高电平 使用高低电平转换时之间要有明显的us级延时
**********************************************************/
static GPIO_InitTypeDef GPIO_InitStruct;
/**********************************************************
1.引脚配置 宏定义用IF语句
2.给引脚电平必须要给输出模式
3.SCL一直都是输出模式(输出时钟肯定是输出模式)
4.宏定义绑定引脚SDA与SCL SDA PB7 SCL PB6
**********************************************************/
#define SCL_Type GPIOB
#define SDA_Type GPIOB
#define SCL_GPIO GPIO_PIN_6
#define SDA_GPIO GPIO_PIN_7
//设置输出高低电平模式
#define SDA_OUT(X) if(X) \
HAL_GPIO_WritePin(SDA_Type, SDA_GPIO, GPIO_PIN_SET); \
else \
HAL_GPIO_WritePin(SDA_Type, SDA_GPIO, GPIO_PIN_RESET);
#define SCL_OUT(X) if(X) \
HAL_GPIO_WritePin(SCL_Type, SCL_GPIO, GPIO_PIN_SET); \
else \
HAL_GPIO_WritePin(SCL_Type, SCL_GPIO, GPIO_PIN_RESET);
#define SDA_IN HAL_GPIO_ReadPin(SDA_Type,SDA_GPIO)//只有输入模式才能读取电平状态
/*****************************************
SDA引脚转变为 OUT输出模式(输出模式给停止 开始信号)
******************************************/
void IIC_SDA_Mode_OUT(void)
{
GPIO_InitStruct.Pin = SDA_GPIO;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SDA_Type, &GPIO_InitStruct);
}
/*****************************************
SDA引脚转变为 输入模式(输入模式传输具体的数据)
******************************************/
void IIC_SDA_Mode_IN(void)
{
GPIO_InitStruct.Pin = SDA_GPIO;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SDA_Type, &GPIO_InitStruct);
}
/*****************************************
IIC开始信号
******************************************/
void IIC_Start(void)//IIC开始信号
{
//设置为输出模式
IIC_SDA_Mode_OUT();
//空闲状态两个引脚是高电平
SDA_OUT(1);
SCL_OUT(1) ;
delay_us(5);
//拉低数据线
SDA_OUT(0);
delay_us(5);
//再拉低时钟线
SCL_OUT(0) ;
delay_us(5);
}
//IIC停止信号
void IIC_Stop(void)
{
//设置为输出模式
IIC_SDA_Mode_OUT();
//拉低
SDA_OUT(0);
SCL_OUT(0);
delay_us(5);
//时钟线先拉高
SCL_OUT(1);
delay_us(5);
//再把数据线拉高
SDA_OUT(1);
delay_us(5);
}
void IIC_Send_Byte(uint8_t d)//主机发送8位数据给从机MSB 高位先发
{
uint8_t i = 0;
//设置为输出模式
IIC_SDA_Mode_OUT();
SDA_OUT(0);
SCL_OUT(0);
delay_us(5);
for(i=0;i<8;i++)
{
if(d & (0x1<<(7-i)))//表示数据是1
SDA_OUT(1)
else
SDA_OUT(0);
delay_us(5);
SCL_OUT(1);//拉高时钟线,告诉对方你可以读了
delay_us(5);
SCL_OUT(0);//拉低时钟线,告诉对方你暂时别读,我在准备数据
}
}
uint8_t IIC_Wait_Ack(void)//等待从机给主机应答或者不应答
{
uint8_t ack = 0;
//设置为输入模式
IIC_SDA_Mode_IN();
//时钟线拉高,时钟线为高电平期间,不管是数据还是ack都是有效的
SCL_OUT(1);
delay_us(5);
if( SDA_IN == 1)
ack = 1;//无效ACK,就是无效应答
else
ack = 0;//有效ACK,就是有效应答
SCL_OUT(0);
delay_us(5);
return ack;
}
uint8_t IIC_Read_Byte(void)//从机发送8位数据给主机
{
uint8_t i =0;
uint8_t data = 0;
//设置为输入模式
IIC_SDA_Mode_IN();
//先拉低时钟线,准备数据
SCL_OUT(0);
delay_us(5);
for(i=0;i<8;i++)
{
SCL_OUT(1);//时钟线为高电平期间数据才是有效的
delay_us(5);
if(SDA_IN == 1)
data |= (0x1<<(7-i));//数据就是1
else
data &= ~(0x1<<(7-i));//数据就是0
SCL_OUT (0);//告诉对方此时准备数据,先别读写
delay_us(5);
}
return data;
}
void IIC_Ack(uint8_t ack)//主机发送应答或者不应答给从机
{
//设置为输出模式
IIC_SDA_Mode_OUT();
SDA_OUT(0);
SCL_OUT(0);
delay_us(5);
SDA_OUT(ack) ;//发送高/低电平--->发送不应答/应答
delay_us(5);
SCL_OUT(1);//告诉从机我已经准备好数据,你可以读取了
delay_us(5);
SCL_OUT (0);//拉低时钟线,发送ack结束
delay_us(5);
}
到了这里,关于STM32 Cube MX 之hal库软件模拟IIC 可直接移植使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!