系统供电3.3V,IIC模拟通信(SCL:PB8,SDA:PB9),模拟IIC通信方式底层驱动,移植时可根据项目需求,适配应用代码即可。同样,前面是头文件代码,后面是应用代码,仅做记录,方便以后移植应用,代码已实测。
#ifndef __DA215_I2C__H__
#define __DA215_I2C__H__
#include "iic2.h"
#include "main.h"
#define IIC2_DELAY 40
// #define SDA2(n) (n?GPIO_SetBits(GPIOD, GPIO_PIN_0):GPIO_ResetBits(GPIOD, GPIO_PIN_0))
#define SDA2_HIGH() GPIOD->PBSC = GPIO_PIN_0 //
#define SDA2_LOW() GPIOD->PBC = GPIO_PIN_0 //
#define SDA2_READ() GPIO_ReadInputDataBit(GPIOD, GPIO_PIN_0) // SDA read
#define SCL2_HIGH() GPIOD->PBSC = GPIO_PIN_1 //(n?GPIO_SetBits(GPIOD, GPIO_PIN_1):GPIO_ResetBits(GPIOD, GPIO_PIN_1))
#define SCL2_LOW() GPIOD->PBC = GPIO_PIN_1 //(n?GPIO_SetBits(GPIOD, GPIO_PIN_1):GPIO_ResetBits(GPIOD, GPIO_PIN_1))
#define IIC2_POWER(n) (n?GPIO_SetBits(GPIOB, GPIO_PIN_12):GPIO_ResetBits(GPIOB, GPIO_PIN_12))
void iic2Start(void);
void iic2Stop(void);
uint8_t iic2WaitAck(void);
void iic2SendAck(void);
void i2c_send_nack(void);
uint8_t iic2ReadByte(void);
void iic2SendByte(uint8_t tdata);
void iic2IoInit(void); //IIC2 IO口初始化
#endif //__I2C_DRV_H__
#include "iic2.h"
void iic2IoInit(void) //IIC2 IO口初始化
{
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOD, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);
GPIO_InitType GPIO_InitStructure;
GPIO_InitStruct(&GPIO_InitStructure); //初始化结构体
GPIO_InitStructure.Pin = GPIO_PIN_0; //SDA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_1; //SCK
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_12; //gsensor/aht20电源
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
GPIO_ConfigPinRemap(AFIO_RMP_CFG_PD01_RMP, ENABLE);
// IIC2_POWER(0); //关闭gsensor/aht20电源
IIC2_POWER(1); //默认给gsensor/aht20电源
// aht20.debug = TRUE;
}
void SDA2DirIn(void) //SDA dir set in
{
GPIO_InitType GPIO_InitStructure;
GPIO_InitStruct(&GPIO_InitStructure); //初始化结构体
GPIO_InitStructure.Pin = GPIO_PIN_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Input Floating Mode
GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
}
void SDA2DirOut(void) //SDA dir set out
{
GPIO_InitType GPIO_InitStructure;
GPIO_InitStruct(&GPIO_InitStructure); //初始化结构体
GPIO_InitStructure.Pin = GPIO_PIN_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(GPIOD, &GPIO_InitStructure);
}
void iic2Start(void)
{
SDA2DirOut(); // sda线输出
SDA2_HIGH();
SCL2_HIGH();
delay_us(IIC2_DELAY);
SDA2_LOW(); // START:when CLK is high,DATA change form high to low
delay_us(IIC2_DELAY);
SCL2_LOW(); //钳住I2C总线,准备发送或接收数据
}
void iic2Stop(void)
{
SDA2DirOut(); // sda线输出
SCL2_LOW();
SDA2_LOW(); // STOP:when CLK is high DATA change form low to high
delay_us(IIC2_DELAY);
SCL2_HIGH();
SDA2_HIGH(); //发送I2C总线结束信号
delay_us(IIC2_DELAY);
}
uint8_t iic2WaitAck(void)
{
uint8_t ucErrTime = 0;
SDA2_HIGH();
SDA2DirIn(); // SDA设置为输入
delay_us(IIC2_DELAY);
SCL2_HIGH();
delay_us(IIC2_DELAY);
while (SDA2_READ())
{
ucErrTime++;
if (ucErrTime > 250)
{
iic2Stop();
return 1;
}
}
SCL2_LOW(); //时钟输出0
return 0;
}
void iic2SendAck(void)
{
SCL2_LOW();
SDA2DirOut(); // SDA设置为输出
SDA2_LOW();
delay_us(IIC2_DELAY);
SCL2_HIGH();
delay_us(IIC2_DELAY);
SCL2_LOW();
}
void i2c_send_nack(void)
{
SCL2_LOW();
SDA2DirOut();
SDA2_HIGH();
delay_us(IIC2_DELAY);
SCL2_HIGH();
delay_us(IIC2_DELAY);
SCL2_LOW();
}
uint8_t iic2ReadByte(void)
{
unsigned char i, receive = 0;
SDA2DirIn(); // SDA设置为输入
for (i = 0; i < 8; i++)
{
SCL2_LOW();
delay_us(IIC2_DELAY);
SCL2_HIGH();
receive <<= 1;
if (SDA2_READ())
receive++;
delay_us(IIC2_DELAY);
}
return receive;
}
void iic2SendByte(uint8_t tdata)
{
uint8_t t;
SDA2DirOut(); // SDA设置为输出
SCL2_LOW(); //拉低时钟开始数据传输
for (t = 0; t < 8; t++)
{
if ((tdata & 0x80) >> 7)
{
SDA2_HIGH();
}
else
{
SDA2_LOW();
}
tdata <<= 1;
delay_us(IIC2_DELAY); //对TEA5767这三个延时都是必须的
SCL2_HIGH();
delay_us(IIC2_DELAY);
SCL2_LOW();
delay_us(IIC2_DELAY);
}
}