STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

发布者:mancozc最新更新时间:2018-06-03 来源: eefocus关键字:STM32F10x  硬件I2C  主从通信  轮询发送  中断接收 手机看文章 扫描二维码
随时随地手机看文章

Ⅰ、写在前面

关注我分享文章的朋友应该知道我在前面讲述过(软件、硬件)I2C主机控制从机EEPROM的例子。在I2C通信主机控制程序是比较常见的一种,可以说在实际项目中,很多应用都会使用到I2C通信。但在实际项目中作为I2C从机的应用相对要少的多,本文主要讲述关于【STM32F10x_硬件I2C主从通信】中STM32作为从机的例子。

在学习本问内容之前,如果对I2C协议还不太了解的朋友请先去了解一下I2C协议,或看我之前关于I2C通信的文章(我微信公众号和博客都有)。

 

关于STM32硬件I2C作为从机的文章网上很少(我在写本文之前也在百度、谷歌等网站上搜索了解过),我猜测大概的原因主要是两点:1.使用该功能的人比较少; 2.说STM32硬件I2C存在BUG。

“使用该功能的人比较少”这个可以理解。其实我不能理解的是,普遍说这个有BUG的现象。我只觉得,你选择了使用这个芯片来作为开发,你选择之前应该是认可它的,什么东西都不可能尽善尽美,一点小的瑕疵,只要可以避免就行。就像Windos系统一样,偶尔死机、蓝屏,但是你还是依然会选择使用它。

 

关于STM32硬件I2C自身BUG也不否认,但官方给出了解决的办法,作为程序员,解决一项BUG,也是对自身能力的一种提升。所以,遇到困难,勇于面对才是正确的做法。

 

实例实验:

本文提供两个实例:一个主机发送(硬件I2C轮询发送数据)、一个从机接收并打印接收数据(硬件I2C中断接收数据)。

主机间隔500ms发送10字节,从机接收10字节检测到I2C停止,将收到的数据通过串口打印出来。【发送的数据及长度可修改,从机自动检测停止条件,也就是可以检测得到主机发送了多少字节数据】


 

关于本文的更多详情请往下看。

 

Ⅱ、实例工程下载

笔者针对于初学者提供的例程都是去掉了许多不必要的功能,精简了官方的代码,对初学者一看就明白,以简单明了的工程供大家学习。

笔者提供的实例工程都是在板子上经过多次测试并没有问题才上传至360云盘,欢迎下载测试、参照学习。

 

提供下载的软件工程是基于Keil(MDK-ARM)V5版本、STM32F103ZE芯片,但F1其他型号也适用(适用F1其他型号: 关注微信,回复“修改型号”)。

 

STM32F10x_硬件I2C主机(发送数据- 轮询方式)实例源代码工程:

https://yunpan.cn/cMKS6muF6643V  访问密码

 

STM32F10x_硬件I2C从机(接收数据- 中断方式)实例源代码工程:

https://yunpan.cn/cMKSMCkcn8tKv  访问密码

 

STM32F1资料:

https://yunpan.cn/crBUdUGdYKam2  访问密码ca90

 

Ⅲ、关于I2C协议

这里再次提示一下I2C协议重要的几点:

 

1.开始和停止条件

SCL时钟电平为高:

SDA数据线由高 -> 低 为总线开始条件;

SDA数据线由低 -> 高 为总线结束条件;

(IO模拟I2C时注意:开始之后将SCL变为低电平,防止误操作SDA使其通信停止)

时序图:


 

2.数据位传输

SCL时钟电平为低, 可以改换SDA数据线的电平,在SCL上升沿的过程将SDA数据发送出去。

(IO模拟I2C时切记:请先将SCL变为低电平,再改变SDA电平状态)

时序图:


 

3.数据传输

I2C 是以字节(8位)的方式进行传输,总线上每传输完1字节之后会有一个应答信号,主器件(主机)需要产生对应的一个额外时钟。

传输格式:8位数据 + 1位应答

数据传输必须带响应,相关的响应时钟脉冲由主机产生,在响应的时钟脉冲期间,发送器释放 SDA 线(高)。

在响应的时钟脉冲期间 接收器必须将 SDA 线拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平。

 

应答位的产生及接收:

1.在(主机)写数据的时候是从机应答(给主机),主机检测;

2.在(主机)读数据的时候是主机应答(给从机),从机检测;

(这里可以借助I2C读写函数一起理解)

1.时序图(主机写,从机应答,主机读取应答):


 

2.时序图(主机读,主机产生应答):


 

 

更多关于I2C协议的文档可以网上查询,也可以参看我下面下载链接的文档(周立功翻译的版本):https://yunpan.cn/cMJxKJzpWFtHE  访问密码 82f3

 

Ⅳ、硬件I2C主机发送数据

硬件I2C主机的配置其实很简单,和前面读写EEPROM的(主机)配置一样。

可参考我之前的文章:STM32F10x_模拟I2C读写EEPROM

 

这里就不再描述。主要讲述一下主机发送数据这一块的代码。

 

我封装的发送数据函数:

I2C_Master_BufferWrite(uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress)

主要就是3个参数:数据BUF、数据长度、从设备地址


看过我前面主机读写EEPEOM代码的人应该很清楚,这里很相似。读写EEPROM比这里多了一个步骤,那就是多了写数据地址的步骤。

 

必须要有的三大步骤:

1.开始

2.设备地址/写

3.停止

 

主程序间隔500ms调用一次该函数,发送一串(我们定义10字节),从机也是间隔500ms收到一串数据并打印出来。

 

Ⅴ、硬件I2C从机中断接收数据

硬件I2C的从机接收数据一般分为三类:中断接收、DMA接收和轮询接收;

 

在实际项目中中断接收和DMA接收比较常见,因为不用占据CPU资源,有数据来了才响应接收【需要CPU具有硬件I2C功能】。

而轮询接收数据很占用CPU资源,一般是CPU没有硬件I2C资源,处理的数据不多的情况下。

 

硬件I2C从机配置I2C这一块比较简单,和上面主机类似,请参看源代码或参考我之前文章的讲述。

可参考我之前的文章:STM32F10x_模拟I2C读写EEPROM

 

提醒:配置中注意关于I2C事件中断这一块(请看源代码)。

 

中断接收函数源代码如下:


位于stm32f10x_it.c文件下。

 

进入I2C事件中断,判断是I2C从机事件,此时,作为从机接收数据需要检测三个标示:

1.检测主机已发生地址(ADDR = 1);

2.检测有接收数据(RXNE = 1);

3.检测到停止条件(STOPF =1)。

 

硬件I2C通信中,起始条件由硬件判断完成,我们检测的就需要这几步就能完成基本的接收数据功能。

 

 

Ⅵ、说明

理解本文之前请先理解I2C协议。

更多关于硬件I2C主从通信的例子(如:DMA发送、DMA接收等)就不再单独写文章讲述了,可以在微信公众号联系我。

 

以上总结仅供参考,若有不对之处,敬请谅解。


关键字:STM32F10x  硬件I2C  主从通信  轮询发送  中断接收 引用地址:STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

上一篇:STM32F10x硬件I2c读写AT24c02,程序卡死
下一篇:关于stm32f129的硬件I2C锁死的重要解决办法

推荐阅读最新更新时间:2024-03-16 16:04

MSP430串口接收发送中断程序
MSP430串口接收发送中断程序F149 #include msp430x14x.h unsigned char RecBuf ; //接收数据缓存 unsigned char *SDat; //指向要发送的数据 unsigned char Rindex; //接收数据计数 unsigned char Tindex; //发送数据计数 unsigned char SendLen; //发送数据长度 void ConfigUart0() { P3SEL |= 0x30; // 选择
[单片机]
stm32硬件i2c stm32硬件iic缺陷如何解决
STM32单片机具有IIC接口,IIC接口具有多主机功能、主设备功能、C地址检测、产生和检测7位/10位地址和广播呼叫和支持不同的通讯速度。 STM硬件I2C的状态标签如下: 发送器/接收器模式标志、字节发送结束标志、中先忙标志、错误标志 STM硬件有9个寄存器。 STM32硬件I2C的CLK在50kHz及以下情况下工作,短时间内不会出现任何情况下的卡住。 STM32硬件I2C的CLK在常用的100kHz和400kHz下工作,一小时内大概率出现卡住现象。 STM32硬件I2C的CLK在任何频率下工作,在读取或发送数据时不允许有其他中断事件干扰,否则将有卡住现象。 总的来说,STM32硬件I2C是个坑,对正常工作的环境要求非常高
[单片机]
STM32(RFID)阶段一:添加串口USART2,修改中断接收协议
因学校比赛原因接触到RFID技术,并结合STM32单片机开发一卡通系统。由于需要和RFID读写器通信,以及上位机软件通信,所以添加USART2串口,并根据RFID数据包改写中断接收协议。资料支持:《不完全手册》《中文手册》端口通用与复用,APB1外设,串口寄存器,中断配置 阶段一:demo程序功能:通过串口USART2接收数据包,并把数据再发回去。RFID型号M3650A-HA 数据包第二个数据为数据包的长度,使用str接收长度,USART_RX_STA bit15置1 表示接收结束。 上代码 void uart_init(u32 bound){ GPIO_InitTypeDef GPIO_InitStructure
[单片机]
STM32的硬件I2C设计有BUG
坊间一直流传着一个传说~STM32的硬件I2C设计有BUG,最好不要用,用软件I2C比较靠谱。长久以来,为了不必要的麻烦,我也一直没有用过硬件I2C,主要是软件I2C也比较方便,基本上任意端口都可以用。 最近画了块板子,正好用到了I2C,就顺便来测试一下硬件I2C是不是真的像有些人说的不好用。 测试硬件:STM32F407VET6+AT24C64测试软件:STM32CubeMX v6.1.1HAL库:STM32CubeF4 Firmware Package V1.25.2 STM32CubeMX配置 使用STM32CubeMX配置很方便,时钟等基础配置不再详细介绍,直接看I2C配置如下: 这里的速度模式选择为标准模式,
[单片机]
STM32的<font color='red'>硬件</font><font color='red'>I2C</font>设计有BUG
基于stm32f10x单片机USB流程理解
主要思路: 文件从main.c文件到main()函数开始: 主要重点是,开启中断: USB_Interrupts_Config(); STM32不像C51单片机那样可以用过interrupt关键字来定义中断响应函数,STM32的中断响应函数接口存在中断向量表中。 其格式如下: 在文件hw_config.c里: /* Enable the USB interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; N
[单片机]
STM32F10X库函数逻辑
#define PERIPH_BASE ((unsigned int)0x40000000) //定义外围总线基地址 #define APB1PERIPH_BASE (PERIPH_BASE) //APB1总线开始与外围总线基地址 #define APB2PERIPH_BASE (PERIPH_BASE +0x10000) //APB2外围总线偏移0x10000 #define APBPERIPH_BASE (PERIPH_BASE +0x20000) //APB外围总线偏移0x20000 #define RCC_BASE (APBPERIPH_BASE+0x1000)
[单片机]
STM32串口中断接收一个完整的数据帧
代码运行条件: (1) 大端发送; (2) 上位机发送一帧数据的时间间隔不能大于主循环周期; (3)数据帧满足下面格式: 帧头部(Head) 类型(Type) 长度(Length) 值(Value) CRC校验 2字节 1字节 1字节 X字节 2字节 0xaa 0x55 X void USART6_Init (void) { GPIO_InitTypeDef GPIO_InitStructur
[单片机]
STM32串口中断的4种接收数据的实现方式
本例程通过PC机的串口调试助手将数据发送至STM32,接收数据后将所接收的数据又发送至PC机。 实例一: void USART1_IRQHandler(u8 GetData) { u8 BackData; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志. GetData = UART1_GetByte(BackData); //也行GetData=USART1- DR; USART1_SendByte(GetDa
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved