IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> stm32中I2Cx的简单配置以及源码 -> 正文阅读

[嵌入式]stm32中I2Cx的简单配置以及源码

首先我们看到F1系列单片机引脚的截图,可以看到PB7,PB8可以复用为I2C1接口。PB10,PB11可以复用为I2C2接口。

在后面i2c产生起始位,以及使能的时候,会填入参数:i2cX,这时候要和复用的GPIO口对应的通讯线路一致

从51单片机学习的时候可以知道,I2C接口需要配置上拉电阻。保证通讯,在这里上拉电阻配置在外面,所以说GPIO口复用的时候配置为开漏输出模式。
请添加图片描述

I2C通讯的软件架构和之前的51单片机也略微有些不同:

请添加图片描述

总体而言就是增加了官方的固件库:stm32f10x_i2c 用于配置底层的功能寄存器,寄存器进一步管理硬件电路,而实现功能。所以自然i2c总线驱动函数中调用stm32f10x_i2c的库函数是不可少的。

请添加图片描述

其中着重说一下这个I2C_CheckEvent()函数,在后面的函数中,多次嵌套在while循环中进行判断,这个相当于是51单片机里面,每次发送数据后都要等一个Ack,具体等待的是什么发来的应答就要到库函数里面去看了,基本掌握运用就行。

通过对库函数的重新封装,组合成新的驱动函数,具体可以见下面的.h文件,定义的5个基本函数
(下面的代码注释紊乱是编码的问题,复制到Keil5里选择ANSI编码就没问题了)

#define I2CPORT		GPIOB	//?¨ò?IO?ó?ú
#define I2C_SCL		GPIO_Pin_6	//?¨ò?IO?ó?ú
#define I2C_SDA		GPIO_Pin_7	//?¨ò?IO?ó?ú
#define HostAddress	0xc0	//×ü???÷?úμ??÷?tμ??·
#define BusSpeed	200000	//×ü???ù?裨2???óú400000£?
void I2C_Configuration(void);
void I2C_SAND_BUFFER(u8 SlaveAddr, u8 WriteAddr, u8* pBuffer, u16 NumByteToWrite);
void I2C_SAND_BYTE(u8 SlaveAddr,u8 writeAddr,u8 pBuffer);
void I2C_READ_BUFFER(u8 SlaveAddr,u8 readAddr,u8* pBuffer,u16 NumByteToRead);
u8 I2C_READ_BYTE(u8 SlaveAddr,u8 readAddr);

请添加图片描述
请添加图片描述

看到下面的初始化结构体函数中

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;我们定义的是7位地址模式,十位地址定义如下:

#define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000)
#define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000)

#include "i2c.h"
void I2C_GPIO_Init(void){ //I2C?ó?ú3?ê??ˉ(?????ó?ú£??ú??óúvoid I2C_Configuration(void)£?é?à-μ?×è?úμ¥???úía£??ùò?ó??′ó??a??ê?3?)
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //???ˉI2C1|?ü 
    GPIO_InitStructure.GPIO_Pin = I2C_SCL | I2C_SDA; //???????úo?                      
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //????IO?ó?ú1¤×÷·?ê?       
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //éè??IO?ó?ú?ù?裨2/10/50MHz£?    
	GPIO_Init(I2CPORT, &GPIO_InitStructure);
}

void I2C_Configuration(void){ //I2C3?ê??ˉ
	I2C_InitTypeDef  I2C_InitStructure;//?¨ò??á11ì?£???DD3?ê??ˉ
	I2C_GPIO_Init(); //?èéè??GPIO?ó?úμ?×′ì?
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//éè???aI2C?£ê?
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_InitStructure.I2C_OwnAddress1 = HostAddress; //?÷?úμ??·£¨′ó?ú2?μ?ó?′?μ??·£?(ò?°??a0xc0?ú.h???tà????¨ò?μ?óD)
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//?êDíó|′e
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //7??μ??·?£ê?
	I2C_InitStructure.I2C_ClockSpeed = BusSpeed; //×ü???ù?èéè?? 	
	I2C_Init(I2C1,&I2C_InitStructure);
	I2C_Cmd(I2C1,ENABLE);//?a??I2C1(?ù?Yòy???′ó?êóí?£?F1?μáDμ?μ¥???úóD2×éi2c?ó?ú£??aà?ó?μ?ê?μúò?×é)				
}

void I2C_SAND_BUFFER(u8 SlaveAddr,u8 WriteAddr,u8* pBuffer,u16 NumByteToWrite){ //I2C·¢?íêy?Y′?£¨?÷?tμ??·£???′??÷£??ú2?μ??·£?êyá?£?
	I2C_GenerateSTART(I2C1,ENABLE);//2úéú?eê???
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //??3yEV5
	I2C_Send7bitAddress(I2C1,SlaveAddr,I2C_Direction_Transmitter);//·¢?í?÷?tμ??·
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//??3yEV6
	I2C_SendData(I2C1,WriteAddr); //?ú2?1|?üμ??·
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//ò?????′??÷·???£?êy?Y??′??÷ò???£?2úéúEV8£?·¢?íêy?Yμ?DR?è??3y??ê??t
	while(NumByteToWrite--){ //?-?··¢?íêy?Y	
	I2C_SendData(I2C1,*pBuffer); //·¢?íêy?Y
	pBuffer++; //êy?Y????ò???
	while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//??3yEV8
	}
	I2C_GenerateSTOP(I2C1,ENABLE);//2úéúí£?1D?o?
}

void I2C_SAND_BYTE(u8 SlaveAddr,u8 writeAddr,u8 pBuffer){ //I2C·¢?íò???×??ú£¨′óμ??·£??ú2?μ??·£??úèY£?
	I2C_GenerateSTART(I2C1,ENABLE); //·¢?í?aê?D?o?
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //μè′yíê3é	
	I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); //·¢?í′ó?÷?tμ??·?°×′ì?£¨D′è?£?
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //μè′yíê3é	
	I2C_SendData(I2C1,writeAddr); //·¢?í′ó?÷?t?ú2???′??÷μ??·
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //μè′yíê3é	
	I2C_SendData(I2C1,pBuffer); //·¢?íòaD′è?μ??úèY
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //μè′yíê3é	
	I2C_GenerateSTOP(I2C1,ENABLE); //·¢?í?áê?D?o?
}

void I2C_READ_BUFFER(u8 SlaveAddr,u8 readAddr,u8* pBuffer,u16 NumByteToRead){ //I2C?áè?êy?Y′?£¨?÷?tμ??·£???′??÷£?′¢′??÷μ??·£?×??ú3¤?è£?
	while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
	I2C_GenerateSTART(I2C1,ENABLE);//?a??D?o?
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));	//??3y EV5
	I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); //D′è??÷?tμ??·
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//??3y EV6
	I2C_Cmd(I2C1,ENABLE);
	I2C_SendData(I2C1,readAddr); //·¢?í?áμ?μ??·
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //??3y EV8
	I2C_GenerateSTART(I2C1,ENABLE); //?a??D?o?
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); //??3y EV5
	I2C_Send7bitAddress(I2C1,SlaveAddr,I2C_Direction_Receiver); //???÷?tμ??·′?3?£??÷?ú?a?á
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); //??3yEV6
	while(NumByteToRead){
		if(NumByteToRead == 1){ //??ê£??×?oóò???êy?Yê±??è? if ó???
			I2C_AcknowledgeConfig(I2C1,DISABLE); //×?oóóDò???êy?Yê±1?±?ó|′e??
			I2C_GenerateSTOP(I2C1,ENABLE);	//×?oóò???êy?Yê±ê1?üí£?1??
		}
		if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)){ //?áè?êy?Y
			*pBuffer = I2C_ReceiveData(I2C1);//μ÷ó??aoˉêy??êy?Yè?3?μ? pBuffer
			pBuffer++; //????ò???
			NumByteToRead--; //×??úêy?? 1 
		}
	}
	I2C_AcknowledgeConfig(I2C1,ENABLE);
}

u8 I2C_READ_BYTE(u8 SlaveAddr,u8 readAddr){ //I2C?áè?ò???×??ú
	u8 a;
	while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//è·?¨i2c×ü????óD????éè±?????
	I2C_GenerateSTART(I2C1,ENABLE);//i2c?aê?ì??t
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
	I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Transmitter); 
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
	I2C_Cmd(I2C1,ENABLE);//??ó?i2c
	I2C_SendData(I2C1,readAddr);
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	I2C_GenerateSTART(I2C1,ENABLE);
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
	I2C_Send7bitAddress(I2C1,SlaveAddr, I2C_Direction_Receiver);
	while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
	I2C_AcknowledgeConfig(I2C1,DISABLE); //×?oóóDò???êy?Yê±1?±?ó|′e??
	I2C_GenerateSTOP(I2C1,ENABLE);	//×?oóò???êy?Yê±ê1?üí£?1??
	a = I2C_ReceiveData(I2C1);
	return a;
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:58:47  更:2022-04-18 17:59:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:49:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码