first commit

This commit is contained in:
2026-01-24 20:03:14 +08:00
commit a2224908e3
318 changed files with 278538 additions and 0 deletions

175
Drivers/BSP/IIC/iic.c Normal file
View File

@@ -0,0 +1,175 @@
/**
******************************************************************************
* @文件 iic.c
* @作者 阜阳师范大学物电学院
* @版本 V0.1
* @日期 2025-03-27
* @简介 软件 IIC 驱动程序
******************************************************************************
**/
#include "iic.h"
/**
* @brief IIC初始化函数
* @note 初始化IIC通信所需的GPIO引脚配置为开漏输出模式
* @retval 无
*/
void iic_init()
{
GPIO_InitTypeDef gpio_init_struct;
IIC_SCL_GPIO_CLK_ENABLE();
IIC_SDA_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(IIC_SCL_GPIO_PORT,&gpio_init_struct);
gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
HAL_GPIO_Init(IIC_SDA_GPIO_PORT,&gpio_init_struct);
IIC_SDA(1);
IIC_SCL(1);
}
/**
* @brief IIC总线延时函数
* @note 提供固定2微秒的延时满足IIC通信时序要求
* @retval 无
*/
static void iic_delay(void)
{
delay_us(2);
}
/**
* @brief 产生IIC起始信号
* @note 起始信号时序SCL高电平时SDA由高变低
* @retval 无
*/
void iic_start(void)
{
IIC_SCL(1);
IIC_SDA(1);
iic_delay();
IIC_SDA(0);
iic_delay();
IIC_SCL(0);
iic_delay();
}
/**
* @brief 向IIC总线发送一个字节数据
* @param data待发送的8位数据
* @retval 无
*/
void iic_send_byte(uint8_t data)
{
uint8_t t;
for(t = 0;t<8;t++)
{
IIC_SDA((data&0x80)>>7);
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SCL(0);
data<<=1;
}
IIC_SDA(1);
}
/**
* @brief 产生IIC停止信号
* @note 停止信号时序SCL高电平时SDA由低变高
* @retval 无
*/
void iic_stop(void)
{
IIC_SDA(0);
iic_delay();
IIC_SCL(1);
iic_delay();
IIC_SDA(1);
iic_delay();
}
/**
* @brief 等待IIC从机应答信号
* @note 从机应答信号为SDA低电平超时自动释放总线
* @retval 1未接收到应答0接收到应答
*/
uint8_t iic_wait_ack(void)//返回1失败0成功
{
IIC_SDA(1);
iic_delay();
IIC_SCL(1);
iic_delay();
if(IIC_READ_SDA)
{
iic_stop();
return 1;
}
IIC_SCL(0);
iic_delay();
return 0;
}
/**
* @brief 主机发送应答信号
* @note 应答信号时序SCL高电平时SDA保持低电平
* @retval 无
*/
void iic_ack(void)
{
IIC_SCL(0);
iic_delay();
IIC_SDA(0);
iic_delay();
IIC_SCL(1);
iic_delay();
}
/**
* @brief 主机发送非应答信号
* @note 非应答信号时序SCL高电平时SDA保持高电平
* @retval 无
*/
void iic_nack(void)
{
IIC_SCL(0); /* 产生一个时钟 */
iic_delay();
IIC_SDA(1);
iic_delay();
IIC_SCL(1); /* 主机释放SDA线 */
iic_delay();
}
/**
* @brief 从IIC总线读取一个字节数据
* @param ack应答控制0=发送非应答1=发送应答
* @retval 读取到的8位数据
*/
uint8_t iic_read_byte(uint8_t ack)
{
uint8_t i,receive = 0;
for(i=0;i<8;i++)
{
receive<<=1;
IIC_SCL(1);
iic_delay();
if(IIC_READ_SDA) receive++;
IIC_SCL(0);
iic_delay();
}
if(!ack) iic_nack();
else iic_ack();
return receive;
}