stm32软件模拟IIC协议

stm32软件模拟IIC协议:

IIC协议需要SCl,SDA两根线,在主机的视角来看由六个基本单元组成:起始信号,终止信号,发送字节,接收字节,发送应答,接收应答。

下面用一个初始化函数,以及六个分别与基本单元对应的函数来完成IIC底层驱动:

GuiStar_IIC.h:

/**
  ****************************************************************************************
  * @file    GuiStar_IIC.h
  * @author  GuiStar-李什么恩
  * @version V2.0.1
  * @date    2023-1-20
  * @brief   IIC通讯协议基本单元函数
  * @note	 本程序没有设置SCL,SDA线上拉电阻,需要硬件上提供!
  ****************************************************************************************
  */

#ifndef __GUISTAR_IIC_H__
#define __GUISTAR_IIC_H__

#include "stm32f10x.h"                  // Device header
#include "IO.h"
#include "Delay.h"

void GuiStar_IIC_Init(GPIO_TypeDef* SCL_Port, uint16_t SCL_Pin, GPIO_TypeDef* SDA_Port, uint16_t SDA_Pin, uint8_t Delay_TIME);
void GuiStar_IIC_Start(void);
void GuiStar_IIC_Stop(void);
void GuiStar_IIC_SendByte(uint8_t Byte);
uint8_t GuiStar_IIC_ReceiveByte(void);
void GuiStar_SendAck(uint8_t AckBit);
uint8_t GuiStar_ReceiveAck(void);

#endif

/***********************IIC时序的一般结构(未完待续。。。)**************************/

GuiStar_IIC.c:

#include "GuiStar_IIC.h"

GPIO_TypeDef* 		scl_Port;
uint16_t 			scl_Pin;
GPIO_TypeDef* 		sda_Port;
uint16_t 			sda_Pin;
uint8_t 			Delay_time;

#define GuiStar_W_SCL(x)		GPIO_WriteBit(scl_Port, scl_Pin, (BitAction) (x))//时钟线控制宏
#define GuiStar_W_SDA(x)		GPIO_WriteBit(sda_Port, sda_Pin, (BitAction) (x))//数据线写宏
#define GuiStar_R_SDA			GPIO_ReadInputDataBit(sda_Port, sda_Pin)		 //数据线读宏
#define waiting_Delay_time		Delay_us(Delay_time)							 //延时函数宏

/**
  * @brief  IIC初始化函数,完成引脚选择和初始化
  * @param  SCL_Port      选择SCL端口
  * @param  SCL_Pin   	  选择SCL引脚
  * @param  SDA_Port      选择SDA端口
  * @param  SDA_Pin   	  选择SDA引脚
  * @param  Delay_TIME    选择延时时长,单位us
  * @retval 无
  */
void GuiStar_IIC_Init(GPIO_TypeDef* SCL_Port, uint16_t SCL_Pin, GPIO_TypeDef* SDA_Port, uint16_t SDA_Pin, uint8_t Delay_TIME)
{
	//全局传参
	scl_Port=SCL_Port;
	scl_Pin=SCL_Pin;
	sda_Port=SDA_Port;
	sda_Pin=SDA_Pin;
	Delay_time=Delay_TIME;
	
	//初始化IO为开漏输出
	IO_Init(SCL_Port, SCL_Pin, GPIO_Mode_Out_OD);
	IO_Init(SDA_Port, SDA_Pin, GPIO_Mode_Out_OD);
	
	//IO置高电平(开漏输出下,高电平为浮空状态,但是可以接受外部硬件上拉电阻拉高电平)
	GuiStar_W_SCL(1);
	GuiStar_W_SDA(1);
}

//IIC起始信号
void GuiStar_IIC_Start(void)
{
	GuiStar_W_SDA(1);
	GuiStar_W_SCL(1);
	waiting_Delay_time;
	GuiStar_W_SDA(0);
	waiting_Delay_time;
	GuiStar_W_SCL(0);
	waiting_Delay_time;
}

//IIC终止信号
void GuiStar_IIC_Stop(void)
{
	GuiStar_W_SDA(0);
	waiting_Delay_time;
	GuiStar_W_SCL(1);
	waiting_Delay_time;
	GuiStar_W_SDA(1);
	waiting_Delay_time;
}

/**
  * @brief  SDA总线向从机发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void GuiStar_IIC_SendByte(uint8_t Byte)
{
	uint8_t i;
	for(i=0;i<8;i++)
	{
		GuiStar_W_SDA((0x80>>i)&Byte);
		waiting_Delay_time;
		GuiStar_W_SCL(1);
		waiting_Delay_time;
		GuiStar_W_SCL(0);
		waiting_Delay_time;
	}
}

/**
  * @brief  主机(stm32)在SDA总线上接收一个字节
  * @param  无
  * @retval Byte 接受的字节
  */
uint8_t GuiStar_IIC_ReceiveByte(void)
{
	uint8_t i;
	uint8_t Byte=0x00;
	
	GuiStar_W_SDA(1);//主机释放SDA为输入模式,SDA将由从机掌管高低电平
	waiting_Delay_time;
	
	for(i=0;i<8;i++)
	{
		GuiStar_W_SCL(1);
		waiting_Delay_time;
		if(GuiStar_R_SDA)
		{
			Byte |= (0x80>>i);
		}
		GuiStar_W_SCL(0);
		waiting_Delay_time;
	}
	return Byte;
}

/**
  * @brief  主机发送应答
  * @param  AckBit 0代表主机应答从机,1代表主机不应答从机
  * @retval 无
  */
void GuiStar_SendAck(uint8_t AckBit)
{
		GuiStar_W_SDA(AckBit);
		waiting_Delay_time;
		GuiStar_W_SCL(1);
		waiting_Delay_time;
		GuiStar_W_SCL(0);
		waiting_Delay_time;
}

/**
  * @brief  主机接收从机应答
  * @param 	无
  * @retval AckBit 0代表从机应答主机,1代表从机不应答主机
  */
uint8_t GuiStar_ReceiveAck(void)
{
	uint8_t AckBit;
	
	GuiStar_W_SDA(1);//主机释放SDA为输入模式,SDA将由从机掌管高低电平
	
	GuiStar_W_SCL(1);
	waiting_Delay_time;
	AckBit=GuiStar_R_SDA;//读取Ack
	GuiStar_W_SCL(0);
	waiting_Delay_time;
	return AckBit;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GuiStar_李什么恩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值