STM32F103 模拟IIC时序

IIC时序网上一搜一大把,我就不在这里啰嗦了,下面程序已经配置好了,只需要修改一下引脚就可以使用。这里强调一下,这里面的delay延时函数用的SysTick定时器,延时比较精确。具体配置可以看一下下面链接:
https://blog.csdn.net/zhai17863966493/article/details/104380691

#include "IIC.h"
#include "delay.h"
//#include "TIM2.h"


#define IIC_SCL   GPIO_Pin_8
#define IIC_SDA   GPIO_Pin_9
#define IIC_PORT  GPIOA


#define IIC_SCL_H() GPIO_SetBits(IIC_PORT,IIC_SCL)
#define IIC_SCL_L() GPIO_ResetBits(IIC_PORT,IIC_SCL)


#define IIC_SDA_H()	GPIO_SetBits(IIC_PORT,IIC_SDA)
#define IIC_SDA_L()	GPIO_ResetBits(IIC_PORT,IIC_SDA)

#define READ_SDA()	GPIO_ReadInputDataBit(IIC_PORT,IIC_SDA)  


//引脚初始化
void IIC_Init(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  
	/*Configure GPIO pin Output Level */
	GPIO_InitStruct.GPIO_Pin = IIC_SCL|IIC_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(IIC_PORT, &GPIO_InitStruct);
    

}


void IIC_SDA_OUT()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};  
	GPIO_InitStruct.GPIO_Pin = IIC_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(IIC_PORT, &GPIO_InitStruct);
}

void IIC_SDA_IN()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0}; 	
	GPIO_InitStruct.GPIO_Pin = IIC_SDA;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(IIC_PORT, &GPIO_InitStruct);
	
}

//IIC起始信号
void IIC_Start()
{
	IIC_SDA_OUT();
	
	IIC_SCL_H();
	IIC_SDA_H();		
	delay_us(1);
	IIC_SDA_L();
	delay_us(3);
	IIC_SCL_L();	
}

//IIC终止信号
void IIC_Stop()
{
	IIC_SDA_OUT();
	IIC_SCL_L();
	IIC_SDA_L();	
	IIC_SCL_H();
	delay_us(1);
	IIC_SDA_H();
	delay_us(1);	
}

//主机应答信号
void IIC_ACK()
{
	IIC_SCL_L();
	IIC_SDA_OUT();
	IIC_SDA_L();
	delay_us(1);
	IIC_SCL_H();
	delay_us(3);
	IIC_SCL_L();
}
//主机非应答
void IIC_NACK()
{
	IIC_SCL_L();
	IIC_SDA_OUT();
	IIC_SDA_H();
	delay_us(1);
	IIC_SCL_H();
	delay_us(3);
	IIC_SCL_L();	
}

//等待从机应答
uint8_t IIC_Wait_ACK()
{
	uint8_t  tempTime = 0;
	IIC_SDA_IN();
	IIC_SDA_H();
	delay_us(1);
	IIC_SCL_H();
	delay_us(1);
	
	while(READ_SDA())
	{
		tempTime++;
		if(tempTime>250)
		{
			IIC_Stop();
			return 1;   //返回1:应答失败  返回0:应答成功		
		}	
	}
		IIC_SCL_L();
		return 0;
}

//发送一个字节的函数
void IIC_Send_Byte(uint8_t txd)
{
	uint8_t i = 0;
	
	IIC_SDA_OUT();
	IIC_SCL_L();
	
	for(i=0;i<8;i++)
	{
		if((txd&0x80) > 0)
		{
			IIC_SDA_H();		
		}
		else
		{
			IIC_SDA_L();	
		}		
		txd <<= 1;
		IIC_SCL_H();
		delay_us(2);
		IIC_SCL_L();
		delay_us(2);	
	}
	
}

//读取一个字节
uint8_t IIC_Read_Byte(uint8_t ack)
{
	uint8_t i=0;
	uint8_t receive = 0;
	IIC_SDA_IN();
	for(i=0;i<8;i++)
	{
		IIC_SCL_L();
		delay_us(2);
		IIC_SCL_H();
		receive <<= 1;
		if(READ_SDA())
		{
			receive++;		
		}
		delay_us(1);	
	}	
	if(ack == 0)
	{
		IIC_NACK();	
	}
	else
	{
		IIC_ACK();	
	}
	return receive;	
}
/
#ifndef __IIC_H__
#define __IIC_H__
#include "stm32f10x.h"

void IIC_Init(void);
void IIC_SDA_OUT(void);
void IIC_SDA_IN(void);

void IIC_Start(void);
void IIC_Stop(void);
void IIC_ACK(void);
void IIC_NACK(void);
uint8_t IIC_Wait_ACK(void);
void IIC_Send_Byte(uint8_t txd);
uint8_t IIC_Read_Byte(uint8_t ack);



#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值