first commit
This commit is contained in:
175
Drivers/BSP/IIC/iic.c
Normal file
175
Drivers/BSP/IIC/iic.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user