stm32之31.iic

iic双线制。一根是SCL,作为时钟同步线;一根是SDA,作为数据传输线

SDN

cs 复制代码
#include "iic.h"

#define SCL    PBout(8)

#define SDA_W  PBout(9)
#define SDA_R  PBin(9)


void IIC_GPIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	//使能时钟G
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	
	//3、配置PG9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}


static void __IIC_SDAMode( GPIOMode_TypeDef GPIO_Mode)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	//使能时钟G
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	
	//3、配置PG9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
}



//1、主机发送启动信号操作
//启动信号:在SCL的高电平期间,SDA产生下降沿
void IIC_Start(void)
{
	//设置SDA引脚为输出模式
	__IIC_SDAMode(GPIO_Mode_OUT);
	
	//先保持一段时间空闲>=4us
	SCL = 1;
	SDA_W = 1;
	delay_us(5);
	
	//开始启动信号
	SDA_W = 0;//下降沿
	delay_us(5);
	
	SCL   = 0;//保证启动信号后面函数能顺畅的接上
}

//2、主机发送停止信号操作
//停止信号:在SCL的高电平期间,SDA产生上升沿
void IIC_Stop(void)
{
	//SDA设置为输出模式
	__IIC_SDAMode(GPIO_Mode_OUT);
	
	SDA_W = 0;
	SCL   = 0;
	delay_us(5);
	
	SCL = 1;//先拉高  --- 高电平期间
	delay_us(5);
	SDA_W = 1;//产生上升沿
}


//3、主机给从机发送8个数据位
void IIC_WriteByte(unsigned char WData)
{
	//SDA设置为输出模式
	__IIC_SDAMode(GPIO_Mode_OUT);
	
	for(int i=0;i<8;i++)
	{
		SCL = 0;
		delay_us(2);
		SDA_W = (WData>>(7-i)) & 0x01;
		delay_us(3);

		SCL = 1;
		delay_us(5);
	}
		
	SCL = 0;
}


//4、主机读取从机发送过来8个数据位
void IIC_ReadByte(unsigned char *RData)
{
	unsigned char TemData=0;//临时存放读取的8bit数据
	//SDA设置为输入模式
	__IIC_SDAMode(GPIO_Mode_IN);
	
	for(int i=0;i<8;i++)
	{
		SCL = 0;
		delay_us(5);//SCL低电平期间是给从机发送数据位的时间
		
		SCL = 1;
		delay_us(2);
		if(SDA_R)
		{
			//数字1
			TemData |= 0x80>>i; //1000 0000
		}
		delay_us(3);//高电平期间主机可以判断SDA_R读取
	}
	
	SCL = 0;
	*RData = TemData;//将读到的结果存放到外面的容器中
		
}

//5、主机读取从机发送过来1个应答位
//返回读到的应答位 0---有应答  1-----无应答
char IIC_ReadAck(void)
{
	char Ack=1;
	//SDA设置为输入模式
	__IIC_SDAMode(GPIO_Mode_IN);
	
	SCL = 0;
	delay_us(5);//低电平期间给从机发送应答信号的时间
	
	SCL = 1;
	delay_us(2);//高电平期间给主机读取数据位的时间
	Ack = SDA_R;
	delay_us(3);
	
	SCL = 0;
	return Ack;//返回读取到的应答结果 外面做判断处理
}

//6、主机发送给从机1个应答位
//主机调用这个函数可以传参自己决定是发有应答还是无
void IIC_WriteAck(char Ack)
{
	//SDA设置为输出模式
	__IIC_SDAMode(GPIO_Mode_OUT);
	
	SCL = 0;
	delay_us(2);
	SDA_W = Ack;
	delay_us(3);
	
	SCL = 1;
	delay_us(5);
	
	SCL = 0;
}
相关推荐
LongRunning7 小时前
【BLE】STM32WB55_低功耗(十一)
stm32
芯片人0077 小时前
纯硬件一键开关机ASIC芯片,为什么比 MCU 方案更适合更可靠
人工智能·单片机·嵌入式硬件·物联网·芯片
染予8 小时前
Ka 阵面星历下发与执行逻辑说明
stm32·嵌入式硬件
芯片人0079 小时前
武汉广昇科技的GMUX1308A模拟开关芯片成功导入中国台湾上市企业联昌电子,助力汽车电子供应链自主可控
科技·嵌入式硬件·物联网·汽车·芯片
恒锐丰科技林技术员12 小时前
EG2181D 半桥栅极驱动芯片详解:高压 MOS/IGBT 驱动实用器件
经验分享·嵌入式硬件·硬件工程
国科安芯12 小时前
面向卫星测控应答机的抗辐射MCU信号采集与定时控制研究
单片机·嵌入式硬件·mcu·架构·卫星·商业航天·抗辐射
CC城子12 小时前
EtherNet/IP I/O 丢包排查(linux系统)
linux·单片机·tcp/ip·ethernetip
新晨单片机设计13 小时前
S010A-基于STM32单片机水温控制系统(数码管显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·嵌入式硬件
事界见闻13 小时前
高性能电机控制MCU选型对比:精度、功耗与实时性如何兼得?
单片机·嵌入式硬件
Brilliantwxx13 小时前
【STM32】 初认识USART串口
linux·stm32·单片机·嵌入式硬件·架构