历史上的今天
今天是:2025年01月14日(星期二)
2021年01月14日 | STM32F10x_硬件I2C主从通信(轮询发送,中断接收)
2021-01-14 来源:eefocus
Ⅰ、写在前面
关注我分享文章的朋友应该知道我在前面讲述过(软件、硬件)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协议。
史海拾趣
|
在大学里我对人生有了新的认识,也想清楚了很多问题.大一时候曾经迷茫,大二也曾经郁闷,\"郁闷\"似乎是现在大学生的口头禅.今天,这些感觉正随着时间慢慢褪去.我觉得这是很正常的. 关于排名第一的那件事情,现在的想法还不系统,而思考也随 ...… 查看全部问答> |
|
在定点DSP中,能够熟练使用Q格式。能够编写出大量符合TI公司的规范的代码程序,虽然不可把规范看的太死。能够熟练使用C语言,从C51到DSP.到ARM.等。这是个嵌入式编程泛C语言的时代,程序员最好还能够知道一些面向对象的语言,如C++,JAVA,C#.能够吸 ...… 查看全部问答> |
|
双激式变压器开关电源(part1) 开关电源原理与设计(连载26) 1-8.双激式变压器开关电源 所谓双激式变压器开关电源,就是指在一个工作周期之内,变压器的初级线圈分别被直流电压正、反激励两次。与单激式变压器开关电源不同,双激式变压器开关电源一般在整个工作周期之内,都向负载提供功率输出。双激式变压 ...… 查看全部问答> |
|
$(\'swf_r2D\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/30391850/v.swf\'), ...… 查看全部问答> |
|
TCPMP Wince6.0 VS2005 编过了, interface.plg死活加载不上 相关的只做过一个改动 player下main.c下只改了一个宏定义 // don\'t want to use common.dll, but don\'t want to collide with DLL import function either #define tcscpy_s _tcscpy_s 改成了 #define tcscpy_s _mtcscpy_s 原因是_tcscpy_s ...… 查看全部问答> |
|
tc下使用borland图形接口出现 BGI Error:Graphics not initialized(use 'initgraph') 用borland C++做一个工控机上的dos程序, 代码里有:initgraph(&drv,&mode,\"\"); 这句话, 并且我的源文件目录下有EGAVGA.BGI这个文件, 编译通过, 当Run的时候就出现BGI Error:Graphics not initialized(use \'initgraph\') 请问这是怎么回事? ...… 查看全部问答> |
|
功能:主要用于数据采集和回放。 1.打算做成一块带CPCI或者PCI接口的板卡,插入工控机中。板上有处理器、SATA-PCI或者SATA-localbus转接芯片、A/D、D/A等,采集工作时由处理器控制A/D采集,采集数据经处理器简单处理通过SATA转接芯片写入SATA硬 ...… 查看全部问答> |
|
大家好: 我做的WINCE 5.0的pocket pc 程序里对数据库建立CeCreateDatabaseEx2(SDK里有EDB版的这个函数),但数据库总建立失败,查看错误是:参数不对。我不知道自己的参数错在哪,请求大家给我指教: &nb ...… 查看全部问答> |
|
我想用vb.net写的程序来取得串口的句柄,但是getlasterror总是得到12的值,查MSDN,注明为The access code is invalid。请各位高手给予指点程序哪儿有问题还是我createfile的参数值有问题: Dim hDiskName ...… 查看全部问答> |
|
最近在一个展会上看到深圳一家叫芯海的公司展出了数字电表方案,感觉有点新鲜。电力计量这个市场是蛮大的,不过好像早都被AXX等几家大公司瓜分的差不多了,本土企业还有机会吗?不晓得了解这个行业的人士如何看?… 查看全部问答> |




