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