模拟IIC
SCL = PB6
SDA = PB7
.c文件
#include "MCU_DRV_Soft_IIC.h"
/************************************************************************
函数名称:IIC_1_Init
函数功能:IIC初始化
输入参数:
返回参数:
其他说明:
************************************************************************/
void IIC_1_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟
// PB6,7初始化设置
GPIO_Initure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_Initure.Pull = GPIO_PULLUP; // 上拉
GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // 快速
HAL_GPIO_Init(GPIOB, &GPIO_Initure);
IIC_1_SDA = 1;
IIC_1_SCL = 1;
}
/************************************************************************
函数名称:IIC_1_Start
函数功能:产生IIC_1起始信号
输入参数:
返回参数:
其他说明:
************************************************************************/
void IIC_1_Start(void)
{
// START:当CLK为高电平时,DATA从高电平变为低电平
IIC_1_SDA_OUT(); // sda线输出
IIC_1_SDA = 1;
IIC_1_SCL = 1;
delay_us(4);
IIC_1_SDA = 0;
delay_us(4);
IIC_1_SCL = 0; // 钳住I2C总线,准备发送或接收数据
}
/************************************************************************
函数名称:IIC_1_Stop
函数功能:产生IIC_1停止信号
输入参数:
返回参数:
其他说明:
************************************************************************/
void IIC_1_Stop(void)
{
// STOP:当CLK为高电平时,DATA从低电平变为高电平
IIC_1_SDA_OUT(); // sda线输出
IIC_1_SCL = 0;
IIC_1_SDA = 0;
delay_us(4);
IIC_1_SCL = 1;
delay_us(4);
IIC_1_SDA = 1; // 发送I2C总线结束信号
}
/************************************************************************
函数名称:IIC_1_Wait_Ack
函数功能:等待应答信号到来
输入参数:
返回参数:1,接收应答失败 0,接收应答成功
其他说明:
************************************************************************/
u8 IIC_1_Wait_Ack(void)
{
u8 ucErrTime = 0;
IIC_1_SDA_IN(); // SDA设置为输入
IIC_1_SDA = 1;
delay_us(1);
IIC_1_SCL = 1;
delay_us(1);
while (IIC_1_READ_SDA)
{
ucErrTime++;
if (ucErrTime > 250)
{
IIC_1_Stop();
return 1;
}
}
IIC_1_SCL = 0; // 时钟输出0
return 0;
}
/************************************************************************
函数名称:IIC_1_Ack
函数功能:产生ACK应答
输入参数:
返回参数:
其他说明:
************************************************************************/
void IIC_1_Ack(void)
{
IIC_1_SCL = 0;
IIC_1_SDA_OUT();
IIC_1_SDA = 0;
delay_us(2);
IIC_1_SCL = 1;
delay_us(2);
IIC_1_SCL = 0;
}
/************************************************************************
函数名称:IIC_1_NAck
函数功能:不产生ACK应答
输入参数:
返回参数:
其他说明:
************************************************************************/
void IIC_1_NAck(void)
{
IIC_1_SCL = 0;
IIC_1_SDA_OUT();
IIC_1_SDA = 1;
delay_us(2);
IIC_1_SCL = 1;
delay_us(2);
IIC_1_SCL = 0;
}
/************************************************************************
函数名称:IIC_1_Send_Byte
函数功能:IIC_1发送一个字节
输入参数:
返回参数:返回从机有无应答 1,有应答 0,无应答
其他说明:
************************************************************************/
void IIC_1_Send_Byte(u8 txd)
{
u8 t;
IIC_1_SDA_OUT();
IIC_1_SCL = 0; // 拉低时钟开始数据传输
for (t = 0; t < 8; t++)
{
IIC_1_SDA = (txd & 0x80) >> 7;
txd <<= 1;
delay_us(2); // 对TEA5767这三个延时都是必须的
IIC_1_SCL = 1;
delay_us(2);
IIC_1_SCL = 0;
delay_us(2);
}
}
/************************************************************************
函数名称:IIC_1_Read_Byte
函数功能:读1个字节,ack=1时,发送ACK,ack=0,发送nACK
输入参数:
返回参数:
其他说明:
************************************************************************/
u8 IIC_1_Read_Byte(unsigned char ack)
{
unsigned char i, receive = 0;
IIC_1_SDA_IN(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
IIC_1_SCL = 0;
delay_us(2);
IIC_1_SCL = 1;
receive <<= 1;
if (IIC_1_READ_SDA)
receive++;
delay_us(1);
}
if (!ack)
IIC_1_NAck(); // 发送nACK
else
IIC_1_Ack(); // 发送ACK
return receive;
}
.h文件
#ifndef _MCU_DRV_SOFT_IIC_H
#define _MCU_DRV_SOFT_IIC_H
#include "sys.h" // 数据类型、位带操作的头文件,位带操作:https://blog.csdn.net/dxjlg/article/details/150262542?spm=1001.2014.3001.5501
#include "delay.h" // 延时相关函数的头文件
//IO方向设置
#define IIC_1_SDA_IN() {GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=0<<7*2;} //输入模式
#define IIC_1_SDA_OUT() {GPIOB->MODER&=~(3<<(7*2));GPIOB->MODER|=1<<7*2;} //输出模式
//IO操作
#define IIC_1_SCL PBout(6) //SCL
#define IIC_1_SDA PBout(7) //SDA
#define IIC_1_READ_SDA PBin(7) //输入SDA
//IIC所有操作函数
void IIC_1_Init(void); //初始化IIC的IO口
void IIC_1_Start(void); //发送IIC开始信号
void IIC_1_Stop(void); //发送IIC停止信号
void IIC_1_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_1_Read_Byte(unsigned char ack); //IIC读取一个字节
u8 IIC_1_Wait_Ack(void); //IIC等待ACK信号
void IIC_1_Ack(void); //IIC发送ACK信号
void IIC_1_NAck(void); //IIC不发送ACK信号
#endif
————————————————
版权声明:本文为CSDN博主「冲动的老飞鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dxjlg/article/details/150422844
|
|