一种基于STM32标准库简易多端口IIC配置方式
以下是具体代码:仅供参考
//= .c文件=============
#include “IIC.h”
#include “delay.h”
/*
by lewis-- 2019.8
*/
SOFT_I2C_TypeDef IIC_1 =
{
GPIOB, GPIO_Pin_6,//SCL
GPIOB, GPIO_Pin_7,//SDA
};
int Log2(int data)
{
unsigned char x=0;
while(data>1)
{
data=/2;
x++;
}
return x;
}
void IIC_Init(SOFT_I2C_TypeDef* IIC)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//
GPIO_InitStructure.GPIO_Pin = IIC->SCL_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(IIC->SCL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = IIC->SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//
GPIO_Init(IIC->SDA_PORT, &GPIO_InitStructure);//
IIC_SCL(1,IIC);
IIC_SDA(1,IIC);
}
void IIC_Start(SOFT_I2C_TypeDef* IIC)
{
SDA_OUT(IIC); //
IIC_SDA(1,IIC);
IIC_SCL(1,IIC);
Delay_1us(4);
IIC_SDA(0,IIC);//
Delay_1us(4);
IIC_SCL(0,IIC);//
}
//产生IIC停止信号
void IIC_Stop(SOFT_I2C_TypeDef* IIC)
{
SDA_OUT(IIC);//
IIC_SCL(0,IIC);
IIC_SDA(0,IIC);//
Delay_1us(2);
IIC_SCL(1,IIC);
Delay_1us(2);
IIC_SDA(1,IIC);//
Delay_1us(2);
}
u8 IIC_Wait_Ack(SOFT_I2C_TypeDef* IIC)
{
u8 Timeout=0;
SDA_IN(IIC); //SDA设置为输入
IIC_SDA(1,IIC);
Delay_1us(1);
IIC_SCL(1,IIC);
Delay_1us(1);
while(READ_SDA(IIC))
{
Timeout++;
if(Timeout>250)
{
IIC_Stop(IIC);
return 1;
}
}
IIC_SCL(0,IIC);//时钟输出0
return 0;
}
void IIC_Ack(SOFT_I2C_TypeDef* IIC)
{
IIC_SCL(0,IIC);
SDA_OUT(IIC);
IIC_SDA(0,IIC);
Delay_1us(1);
IIC_SCL(1,IIC);
Delay_1us(1);
IIC_SCL(0,IIC);
}
void IIC_NAck(SOFT_I2C_TypeDef* IIC)
{
IIC_SCL(0,IIC);
SDA_OUT(IIC);
IIC_SDA(1,IIC);
Delay_1us(1);
IIC_SCL(1,IIC);
Delay_1us(1);
IIC_SCL(0,IIC);
}
void IIC_Send_Byte(SOFT_I2C_TypeDef* IIC,u8 data)
{
u8 t;
SDA_OUT(IIC);
IIC_SCL(0,IIC);//
for(t=0;t<8;t++)
{
if(((data&0x80)>>7) == 1)
IIC_SDA(1,IIC);
else
IIC_SDA(0,IIC);
data<<= 1;
Delay_1us(2); //
IIC_SCL(1,IIC);
Delay_1us(2);
IIC_SCL(0,IIC);
Delay_1us(2);
}
}
int IIC_Send_Nbyte(SOFT_I2C_TypeDef* IIC,uint8_t addr,uint8_t* wrbuf,uint8_t cmd)
{
uint8_t i ;
uint8_t wrbuf_len;
wrbuf_len=strlen((char*)wrbuf); //
IIC_Start(IIC);
IIC_Send_Byte(IIC,addr|0x00);
if((IIC_Wait_Ack(IIC))) return 0;
IIC_Send_Byte(IIC,cmd);
if((IIC_Wait_Ack(IIC))) return 0;
for(i=0;i<wrbuf_len;i++)
{
IIC_Send_Byte(IIC,wrbuf[i]);
if((IIC_Wait_Ack(IIC))) return 0;
}
IIC_Stop(IIC);
return 1;
}
u8 IIC_Read_Byte(SOFT_I2C_TypeDef* IIC,uint8_t ACk)
{
unsigned char i,receive=0;
SDA_IN(IIC);
for(i=0;i<8;i++ )
{
IIC_SCL(0,IIC);
Delay_1us(2);
IIC_SCL(1,IIC);
receive<<=1;
if(READ_SDA(IIC))receive++;
Delay_1us(1);
}
if (!ACk)
IIC_NAck(IIC);
else
IIC_Ack(IIC);
return receive;
}
int IIC_Read_Nbyte(SOFT_I2C_TypeDef* IIC,uint8_t addr,uint8_t cmd,uint8_t rbuf,int ACK)
{
uint8_t i;
IIC_Start(IIC);
IIC_Send_Byte(IIC,addr|0x00);
if((IIC_Wait_Ack(IIC))) return 0;
IIC_Send_Byte(IIC,cmd);
if((IIC_Wait_Ack(IIC))) return 0;
IIC_Start(IIC);
IIC_Send_Byte(IIC,addr|0x01);
if((IIC_Wait_Ack(IIC))) return 0;
for(i=0;ACK>0;i++)
{
rbuf[i]=IIC_Read_Byte(IIC,ACK–);
}
IIC_Stop(IIC);
return 1;
}
//.h文件=======
#include “stm32f4xx.h”
#include “stm32f4xx_gpio.h”
#include “math.h”
/
by lewis-- 2019.8
*/
//IO方向设置
//系统log()耗时太长,导致只能读取一个字节数据
//#define SDA_IN(IIC) {IIC->SDA_PORT->MODER&=~(3<<((uint8_t)(log2(IIC->SDA_PIN))*2));IIC->SDA_PORT->MODER|=0<<((uint8_t)(log2(IIC->SDA_PIN))*2);} //
//#define SDA_OUT(IIC) {IIC->SDA_PORT->MODER&=~(3<<((uint8_t)(log2(IIC->SDA_PIN))*2));IIC->SDA_PORT->MODER|=1<<((uint8_t)(log2(IIC->SDA_PIN))*2);} //
//#define SCL_OUT(IIC) {IIC->SCL_PORT->MODER&=~(3<<((uint8_t)(log2(IIC->SCL_PIN))*2));IIC->SCL_PORT->MODER|=1<<((uint8_t)(log2(IIC->SCL_PIN))*2);} //
#define SDA_IN(IIC) {IIC->SDA_PORT->MODER&=~(3<<((uint8_t)(Log2(IIC->SDA_PIN))*2));IIC->SDA_PORT->MODER|=0<<((uint8_t)(Log2(IIC->SDA_PIN))*2);} //
#define SDA_OUT(IIC) {IIC->SDA_PORT->MODER&=~(3<<((uint8_t)(Log2(IIC->SDA_PIN))*2));IIC->SDA_PORT->MODER|=1<<((uint8_t)(Log2(IIC->SDA_PIN))*2);} //
#define SCL_OUT(IIC) {IIC->SCL_PORT->MODER&=~(3<<((uint8_t)(Log2(IIC->SCL_PIN))*2));IIC->SCL_PORT->MODER|=1<<((uint8_t)(Log2(IIC->SCL_PIN))*2);} //
#define IIC_SCL(x,IIC) (x ? GPIO_SetBits(IIC->SCL_PORT, IIC->SCL_PIN): GPIO_ResetBits(IIC->SCL_PORT, IIC->SCL_PIN))
#define IIC_SDA(x,IIC) (x ? GPIO_SetBits(IIC->SDA_PORT, IIC->SDA_PIN): GPIO_ResetBits(IIC->SDA_PORT, IIC->SDA_PIN))
#define READ_SDA(IIC) GPIO_ReadInputDataBit(IIC->SDA_PORT, IIC->SDA_PIN)
typedef struct SoftIIC
{
GPIO_TypeDef* SCL_PORT;
uint16_t SCL_PIN;
GPIO_TypeDef* SDA_PORT;
uint16_t SDA_PIN;
}SOFT_I2C_TypeDef;
int Log2(int data);
extern SOFT_I2C_TypeDef IIC_1 ;
void IIC_Init(SOFT_I2C_TypeDef* IIC);
void IIC_Start(SOFT_I2C_TypeDef* IIC);
void IIC_Stop(SOFT_I2C_TypeDef* IIC);
u8 IIC_Wait_Ack(SOFT_I2C_TypeDef* IIC);
void IIC_Ack(SOFT_I2C_TypeDef* IIC);
void IIC_NAck(SOFT_I2C_TypeDef* IIC);
void IIC_Send_Byte(SOFT_I2C_TypeDef* IIC,u8 txd);
int IIC_Send_Nbyte(SOFT_I2C_TypeDef* IIC,uint8_t addr,uint8_t* wrbuf,uint8_t cmd);
u8 IIC_Read_Byte(SOFT_I2C_TypeDef* IIC,unsigned char ack);
int IIC_Read_Nbyte(SOFT_I2C_TypeDef* IIC,uint8_t addr,uint8_t cmd,uint8_t *rbuf,int ACK);
#endif