STM32 模拟IIC源代码 多个I2C减少冗余代码

   日期:2021-04-15     浏览:112    评论:0    
核心提示:当设计中使用I2C的数量多于1个时,其底层I2C的代码逻辑都是一样的,只有IO口变了,为此还要复制粘贴、修改IO,不仅费时,而且还浪费片内资源,因此可以使用指针来重复执行IIC底层代码,实现一个代码,多个IO使用。Stm32f30x_SMLT_I2C.h#ifndef __Stm32f30x_SMLT_I2C_H#define __Stm32f30x_SMLT_I2C_H//========================= Include ===========================

当设计中使用I2C的数量多于1个时,其底层I2C的代码逻辑都是一样的,只有IO口变了,为此还要复制粘贴、修改IO,不仅费时,而且还浪费片内资源,因此可以使用指针来重复执行IIC底层代码,实现一个代码,多个IO使用。

Stm32f30x_SMLT_I2C.h


#ifndef __Stm32f30x_SMLT_I2C_H
#define __Stm32f30x_SMLT_I2C_H

//========================= Include ===============================================================

#include "stm32f30x.h"

//========================= Variable ==============================================================

typedef struct
{ 
	GPIO_TypeDef* I2C_GPIO;
	uint32_t SDA_SBIT;
	uint32_t SDA_RBIT;
	uint32_t SCL_SBIT;
	uint32_t SCL_RBIT;
	uint32_t SDA_MODER;
	uint32_t SDA_MODER_0;
	uint32_t SDA_MODER_1;
}I2C_Struct;

extern I2C_Struct S_I2C_IO[2];//------------------------------------- 需修改
//(想要3个的话,数组添加,下面的define也要添加,初始化函数S_I2C_Init中也要添加)

//========================= I2C1_Define ================================================================
//--------------------------SDA-------------------------------------- 需修改
#define S_I2C1_SDA_GPIO GPIOB
#define S_I2C1_SDA_BIT 9
//--------------------------SCL-------------------------------------- 需修改
#define S_I2C1_SCL_GPIO GPIOB
#define S_I2C1_SCL_BIT 8
//还需配置结构体初始化函数 S_I2C_Init

//========================= I2C2_Define ================================================================
//--------------------------SDA-------------------------------------- 需修改
#define S_I2C2_SDA_GPIO GPIOE
#define S_I2C2_SDA_BIT 1
//--------------------------SCL-------------------------------------- 需修改
#define S_I2C2_SCL_GPIO GPIOE
#define S_I2C2_SCL_BIT 0
//还需配置结构体初始化函数 S_I2C_Init

// //========================= I2Cx_Define ================================================================
// //--------------------------SDA-------------------------------------- 需修改
// #define S_I2Cx_SDA_GPIO GPIOx
// #define S_I2Cx_SDA_BIT x
// //--------------------------SCL-------------------------------------- 需修改
// #define S_I2Cx_SCL_GPIO GPIOx
// #define S_I2Cx_SCL_BIT x
// //添加在此添加


//========================= Function ==============================================================

void S_I2C_Init(void);//--------------------------------------------- 需修改

void S_I2C_Start(I2C_Struct I2C_temp);
void S_I2C_Stop(I2C_Struct I2C_temp);
uint8_t S_I2C_SendByte(I2C_Struct I2C_temp, uint8_t byte);
uint8_t S_I2C_ReceiveByte(I2C_Struct I2C_temp, uint8_t nack);
uint8_t S_I2C_WriteRegister(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t data);
uint8_t S_I2C_ReadRegister(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t amount, uint8_t* data, uint8_t typ);
uint8_t S_I2C_PointerRead(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t amount, uint8_t* data, uint8_t typ);

//========================= Define ================================================================
//通过宏定义将IO结构体直接放入基础函数中
//-------------------------- I2C1 -----------------------------------
#define S_I2C1_Start() S_I2C_Start(S_I2C_IO[0])
#define S_I2C1_Stop() S_I2C_Stop(S_I2C_IO[0])
#define S_I2C1_SendByte(byte) S_I2C_SendByte(S_I2C_IO[0], byte)
#define S_I2C1_ReceiveByte(nack) S_I2C_ReceiveByte(S_I2C_IO[0], nack)
#define S_I2C1_WriteRegister(addr, regAddr, data) S_I2C_WriteRegister(S_I2C_IO[0], addr, regAddr, data)
#define S_I2C1_ReadRegister(addr, regAddr, amount, data, typ) S_I2C_ReadRegister(S_I2C_IO[0], addr, regAddr, amount, data, typ)
#define S_I2C1_PointerRead(addr, regAddr, amount, data, typ) S_I2C_PointerRead(S_I2C_IO[0], addr, regAddr, amount, data, typ)

//-------------------------- I2C2 -----------------------------------
#define S_I2C2_Start() S_I2C_Start(S_I2C_IO[1])
#define S_I2C2_Stop() S_I2C_Stop(S_I2C_IO[1])
#define S_I2C2_SendByte(byte) S_I2C_SendByte(S_I2C_IO[1], byte)
#define S_I2C2_ReceiveByte(nack) S_I2C_ReceiveByte(S_I2C_IO[1], nack)
#define S_I2C2_WriteRegister(addr, regAddr, data) S_I2C_WriteRegister(S_I2C_IO[1], addr, regAddr, data)
#define S_I2C2_ReadRegister(addr, regAddr, amount, data, typ) S_I2C_ReadRegister(S_I2C_IO[1], addr, regAddr, amount, data, typ)
#define S_I2C2_PointerRead(addr, regAddr, amount, data, typ) S_I2C_PointerRead(S_I2C_IO[1], addr, regAddr, amount, data, typ)

//-------------------------- Another --------------------------------
#define ACK 0
#define NACK 1

#define FAILED 0
#define SUCCEED 1

//=================================================================================================

#endif

Stm32f30x_SMLT_I2C.c


#include "Stm32f30x_SMLT_I2C.h"

I2C_Struct S_I2C_IO[2];//IO口结构体,通过.h文件定义使用的引脚


void S_I2C_IO_Init(I2C_Struct* I2C_temp, GPIO_TypeDef* I2C_GPIO, uint8_t SDA_BIT, uint8_t SCL_BIT)
{ 
	I2C_temp->I2C_GPIO = I2C_GPIO;
	I2C_temp->SDA_SBIT = (SBIT0 << SDA_BIT);
	I2C_temp->SDA_RBIT = (RBIT0 << SDA_BIT);
	I2C_temp->SCL_SBIT = (SBIT0 << SCL_BIT);
	I2C_temp->SCL_RBIT = (RBIT0 << SCL_BIT);
	I2C_temp->SDA_MODER = 0x03 << (SDA_BIT << 1);
	I2C_temp->SDA_MODER_0 = 0x01 << (SDA_BIT << 1);
	I2C_temp->SDA_MODER_1 = 0x02 << (SDA_BIT << 1);
}


void S_I2C_Init(void)
{ 
	S_I2C_IO_Init(&S_I2C_IO[0], S_I2C1_SDA_GPIO, S_I2C1_SDA_BIT, S_I2C1_SCL_BIT);
	S_I2C_IO_Init(&S_I2C_IO[1], S_I2C2_SDA_GPIO, S_I2C2_SDA_BIT, S_I2C2_SCL_BIT);
	// S_I2C_IO_Init(&S_I2C_IO[x], S_I2Cx_SDA_GPIO, S_I2Cx_SDA_BIT, S_I2Cx_SCL_BIT); //添加在此添加
}


void Delay(void)
{ 
    for (uint8_t i = 0; i < 0x10; i++)
	{ 
		
	}
}


void S_I2C_Start(I2C_Struct I2C_temp)
{ 
	I2C_temp.I2C_GPIO->MODER |= I2C_temp.SDA_MODER_0;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_SBIT;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
    Delay();
}


void S_I2C_Stop(I2C_Struct I2C_temp)
{ 
	I2C_temp.I2C_GPIO->MODER |= I2C_temp.SDA_MODER_0;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_SBIT;
    Delay();
}


uint8_t S_I2C_SendByte(I2C_Struct I2C_temp, uint8_t byte)
{ 
	uint8_t temp = 0x00;
	for(uint8_t i = 0x80; i; i >>= 1)
	{ 
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
		if(byte & i)
		{ 
			I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_SBIT;
		}
		else
		{ 
			I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
		}
        Delay();
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
        Delay();
	}
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
	I2C_temp.I2C_GPIO->MODER &= ~I2C_temp.SDA_MODER;
	Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
	if(I2C_temp.I2C_GPIO -> IDR & I2C_temp.SDA_SBIT)
	{ 
		temp = NACK;
	}
	else
	{ 
		temp = ACK;
	}
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
	I2C_temp.I2C_GPIO->MODER |= I2C_temp.SDA_MODER_0;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
    Delay();
	return temp;
}


uint8_t S_I2C_ReceiveByte(I2C_Struct I2C_temp, uint8_t nack)
{ 
	uint8_t byte = 0x00;
	I2C_temp.I2C_GPIO->MODER &= ~I2C_temp.SDA_MODER;
	for (uint8_t i = 8; i; i--)
	{ 
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
        Delay();
		byte <<= 1;
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
		if(I2C_temp.I2C_GPIO -> IDR & I2C_temp.SDA_SBIT)
		{ 
			byte |= 0x01;
		}
        Delay();
	}
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
	I2C_temp.I2C_GPIO->MODER |= I2C_temp.SDA_MODER_0;
	if(nack)
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_SBIT;
	else
		I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SDA_RBIT;
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_RBIT;
    Delay();
	I2C_temp.I2C_GPIO->BSRR |= I2C_temp.SCL_SBIT;
    Delay();
	return byte;
}



uint8_t S_I2C_WriteRegister(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t data)
{ 
	addr <<= 1;
	S_I2C_Start(I2C_temp);
	if(S_I2C_SendByte(I2C_temp, addr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	if(S_I2C_SendByte(I2C_temp, regAddr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	if(S_I2C_SendByte(I2C_temp, data) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	S_I2C_Stop(I2C_temp);
	return SUCCEED;
}



uint8_t S_I2C_ReadRegister(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t amount, uint8_t* data, uint8_t typ)
{ 
	S_I2C_Start(I2C_temp);
	addr = (addr << 1) | 0x01;
	if(S_I2C_SendByte(I2C_temp, addr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	if(S_I2C_SendByte(I2C_temp, regAddr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	for(amount -= 1;amount;amount --)
	{ 
		*data = S_I2C_ReceiveByte(I2C_temp, ACK);
		if(typ == ARRAY)
			data ++;
		else
			data --;
	}
	*data = S_I2C_ReceiveByte(I2C_temp, NACK);
	S_I2C_Stop(I2C_temp);
	return SUCCEED;
}


uint8_t S_I2C_PointerRead(I2C_Struct I2C_temp, uint8_t addr, uint8_t regAddr, uint8_t amount, uint8_t* data, uint8_t typ)
{ 
	addr <<= 1;
	S_I2C_Start(I2C_temp);
	if(S_I2C_SendByte(I2C_temp, addr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	if(S_I2C_SendByte(I2C_temp, regAddr) == NACK)
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	S_I2C_Stop(I2C_temp);
	
	addr |= 0x01;
	S_I2C_Start(I2C_temp);
	if(S_I2C_SendByte(I2C_temp, addr) == NACK)	//NACK
	{ 
		S_I2C_Stop(I2C_temp);
		return FAILED;
	}
	for(amount -= 1;amount;amount --)
	{ 
		*data = S_I2C_ReceiveByte(I2C_temp, ACK);
		if(typ == ARRAY)
			data ++;
		else
			data --;
	}
	*data = S_I2C_ReceiveByte(I2C_temp, NACK);
	S_I2C_Stop(I2C_temp);
	return SUCCEED;
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服