由于stm32后续的库文件只有hal库了,为了使代码更方便,也做了一个移植性很高的库文件,拿到手之后改改引脚就可以快速使用
c文件如下文章来源:https://www.toymoban.com/news/detail-631827.html
/**
* @file softwareiic.c
* @brief 适用于STM32 HAL库及CUBEMX生成工程的软件模拟IIC
* @version V1.0.0
* @author Sundea
* @date 2023/5/8
*/
#include "softwareIIC.h"
/**
* @brief IIC延时
* @param 无
* @return 无
*/
void IIC_Delay(uint8_t time)
{
uint32_t i = time * 800; // 用户根据自己的MCU时钟进行设置倍数
while (i--)
{
;
}
}
/**
* @brief IIC初始化
* @param 无
* @return 无
*/
void Soft_IIC_Init(void)
{
IIC_SDA_H();
IIC_SCL_H();
}
/**
* @brief SDA引脚设置输出模式
* @param 无
* @return 无
*/
static void Soft_IIC_Output(void)
{
GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_OUTPUT_PP;
SOFT_IIC_GPIO_STRUCT.Pin = IIC_SDA_PIN;
SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(IIC_SDA_PORT, &SOFT_IIC_GPIO_STRUCT);
}
/**
* @brief SDA引脚设置输入模式
* @param 无
* @return 无
*/
static void Soft_IIC_Input(void)
{
GPIO_InitTypeDef SOFT_IIC_GPIO_STRUCT;
SOFT_IIC_GPIO_STRUCT.Mode = GPIO_MODE_INPUT;
SOFT_IIC_GPIO_STRUCT.Pin = IIC_SDA_PIN;
SOFT_IIC_GPIO_STRUCT.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(IIC_SDA_PORT, &SOFT_IIC_GPIO_STRUCT);
}
/**
* @brief IIC起始信号
* @param 无
* @return 无
*/
void Soft_IIC_Start(void)
{
Soft_IIC_Output();
IIC_SCL_L();
IIC_SDA_H();
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SDA_L();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_L();
}
/**
* @brief IIC停止信号
* @param 无
* @return 无
*/
void Soft_IIC_Stop(void)
{
Soft_IIC_Output();
IIC_SCL_L();
IIC_SDA_L();
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SDA_H();
IIC_Delay(IIC_DELAY_TIME);
}
/**
* @brief IIC应答信号
* @param 无
* @return 无
*/
void Soft_IIC_ACK(void)
{
Soft_IIC_Output();
IIC_SCL_L();
IIC_SDA_L();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_L();
}
/**
* @brief IIC无应答信号
* @param 无
* @return 无
*/
void Soft_IIC_NACK(void)
{
Soft_IIC_Output();
IIC_SCL_L();
IIC_SDA_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
}
/**
* @brief IIC等待应答信号
* @param 无
* @return 0无应答 1有应答
*/
uint8_t Soft_IIC_Wait_ACK(void)
{
uint8_t wait;
Soft_IIC_Output();
IIC_SDA_H();
Soft_IIC_Input();
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
while (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN))
{
wait++;
if (wait > 200)
{
Soft_IIC_Stop();
return 0;
}
}
IIC_SCL_L();
return 1;
}
/**
* @brief IIC写数据1
* @param 无
* @return 无
*/
void Soft_IIC_Write_High(void)
{
IIC_SCL_L();
IIC_SDA_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_L();
}
/**
* @brief IIC写数据0
* @param 无
* @return 无
*/
void Soft_IIC_Write_Low(void)
{
IIC_SCL_L();
IIC_SDA_L();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_L();
}
/**
* @brief IIC写入单个数据
* @param 无
* @return 应答信号, 0无应答 1有应答
*/
uint8_t Soft_IIC_Write_Byte(uint8_t Byte)
{
uint8_t i;
Soft_IIC_Output();
for (i = 0x80; i != 0; i >>= 1)
{
if (Byte & i)
{
Soft_IIC_Write_High();
}
else
{
Soft_IIC_Write_Low();
}
}
return (Soft_IIC_Wait_ACK());
}
/**
* @brief IIC读一个数据
* @param ACK:应答 NACK:不应答
* @return 返回读到的数据
*/
uint8_t Soft_IIC_Recv_Byte(ACK_STATUS ack_sta)
{
uint8_t data = 0, i;
Soft_IIC_Input();
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
for (i = 0x80; i != 0; i >>= 1)
{
if (HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN) == 1)
{
data |= i;
}
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_L();
IIC_Delay(IIC_DELAY_TIME);
IIC_SCL_H();
IIC_Delay(IIC_DELAY_TIME);
}
if (ack_sta == ACK)
{
Soft_IIC_ACK();
}
else
{
Soft_IIC_NACK();
}
return data;
}
h文件如下文章来源地址https://www.toymoban.com/news/detail-631827.html
#ifndef _SOFTWAREIIC_H_
#define _SOFTWAREIIC_H_
#include "main.h"
typedef enum{
NACK = 0,
ACK = 1
}ACK_STATUS;
#define IIC_DELAY_TIME 10
#define IIC_SCL_PIN GPIO_PIN_2
#define IIC_SCL_PORT GPIOB
#define IIC_SDA_PIN GPIO_PIN_1
#define IIC_SDA_PORT GPIOB
// #define IIC_SDA_H() GPIOB->BSRR = 0x010
// #define IIC_SDA_L() GPIOB->BRR = 0x010
// #define IIC_SCL_H() GPIOB->BSRR = 0x100
// #define IIC_SCL_L() GPIOB->BRR = 0x100
#define IIC_SCL_H() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET)
#define IIC_SCL_L() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET)
#define IIC_SDA_H() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET)
#define IIC_SDA_L() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET)
void Soft_IIC_Init(void);
void Soft_IIC_Start(void);
void Soft_IIC_Stop(void);
void Soft_IIC_ACK(void);
void Soft_IIC_NACK(void);
uint8_t Soft_IIC_Wait_ACK(void);
uint8_t Soft_IIC_Write_Byte(uint8_t Byte);
uint8_t Soft_IIC_Recv_Byte(ACK_STATUS ack_sta);
#endif
到了这里,关于HAL库&STM32cubeMX工程软件模拟IIC,改改引脚即可直接使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!