I2C通讯协议和原理这里不说,网上一大堆,自己查。直接上源码,一直用着的,没有任何问题,里面的函数都是我自己常用的一些,如果有其他需要,可以根据这些代码仿照写就行。
定义IIC结构体:
typedef struct
{
GPIO_TypeDef *SCL_GPIO;
uint16_t SCL_GPIO_PIN;
GPIO_TypeDef *SDA_GPIO;
uint16_t SDA_GPIO_PIN;
}typedef_I2C;
主文件代码:
#include "i2c.h"
#include "delay.h"
//设置I2C引脚
void I2C_setpin(typedef_I2C *i2c,GPIO_TypeDef *gpio_sck,uint16_t pin_sck,GPIO_TypeDef *gpio_sda,uint16_t pin_sda)
{
i2c->SCL_GPIO=gpio_sck;
i2c->SDA_GPIO=gpio_sda;
i2c->SCL_GPIO_PIN=pin_sck;
i2c->SDA_GPIO_PIN=pin_sda;
}
//设置SDA引脚为输入
void IIC_SDA_IN(typedef_I2C *iic)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = iic->SDA_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(iic->SDA_GPIO, &GPIO_InitStruct);
}
//设置SDA引脚为输出
void IIC_SDA_OUT(typedef_I2C *iic)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = iic->SDA_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(iic->SDA_GPIO, &GPIO_InitStruct);
}
void IIC_set_clk1(typedef_I2C *iic)
{
HAL_GPIO_WritePin(iic->SCL_GPIO, iic->SCL_GPIO_PIN, GPIO_PIN_SET);
}
void IIC_set_clk0(typedef_I2C *iic)
{
HAL_GPIO_WritePin(iic->SCL_GPIO, iic->SCL_GPIO_PIN, GPIO_PIN_RESET);
}
void IIC_set_sda1(typedef_I2C *iic)
{
HAL_GPIO_WritePin(iic->SDA_GPIO, iic->SDA_GPIO_PIN, GPIO_PIN_SET);
}
void IIC_set_sda0(typedef_I2C *iic)
{
HAL_GPIO_WritePin(iic->SDA_GPIO, iic->SDA_GPIO_PIN, GPIO_PIN_RESET);
}
uint16_t IIC_get_sda(typedef_I2C *iic)
{
return HAL_GPIO_ReadPin(iic->SDA_GPIO,iic->SDA_GPIO_PIN)==GPIO_PIN_SET;
}
//开始标志
void IIC_start(typedef_I2C *iic)
{
IIC_SDA_OUT(iic);
IIC_set_sda1(iic);
IIC_set_clk1(iic);
delay_us(1);
IIC_set_sda0(iic); //Start
de