关于STM32系列单片机串口通信I2C通信的问题,求教各位大牛

> 资讯详情
jiangliu 375700
上一篇经验谈,我们谈到了单片机、ARM和DSP三者的异同与应用分析。本期快包邀请了专注ST芯片开发的优质服务商王总,谈谈STM32芯片的通信接口以及基于ST芯片外围设计的那些事儿。以下为王总结合自身经验总结的STM32芯片的通信接口开发经验总结。
STM32芯片的通信接口是出了名的多,如STM32F103VET6单片机,它除了UART,还有SPI、CAN、I2C等通信接口。一个单片机,为什么会有这么多的通信接口?一种接口不够用么!这是一部分小伙伴的疑问。
基于单片机的电子产品,从简单的到复杂的,基本上没有只用单片机就可以完成了。这一点,大家在看到很多电子产品的电路板之后就发现了,上面有若干个芯片。带有单片机的电路板上,其他的芯片都被称作单片机的外围芯片。
根据不同的应用,有不同的外围芯片。这些外围芯片有很多种,例如加速度传感器芯片、数字收音机芯片、存储芯片、无线通信芯片、放大器芯片、温度传感器芯片等等。当然,除了外围芯片,还会有很多的电子元件,诸如电阻电容三极管MOS管等。
下面就开始介绍我曾经做过的开发板所要连接的一些外围芯片。
I2C通信芯片
STM32F103VET6有2个I2C口,分别是I2C1和I2C2,我们用I2C1口来学习。和它连接的芯片我们选择AT24C02,这是一个EEPROM类型的存储芯片。
EEPROM芯片是我们做任何产品时经常会用到的芯片,最常见的是Atmel公司的AT24XX系列。所以这个芯片也是我们开发板上必须要有的芯片。这个芯片说白了,就是个存储芯片。(一般的单片机由ROM和RAM构成,ROM用来放程序,RAM用来放程序运行时的数据,单片机运行完了关机后,ROM中的内容还是原来的程序,RAM中的内容也都没有了。如果想要保存数据,就需要外加一个存储芯片了。)
这个芯片的用途就是保存一些不允许掉电丢失的数据。举个例子,一个产品需要限定用户的使用次数,每开机一次,就记录一次,如果达到10000次,就需要维护,这里的使用次数,就需要掉电不丢失。
这里虽然连接的是硬件I2C口,但是也可以把I2C口的两个引脚配置为普通的IO口模拟I2C时序来学习I2C通信,作为单片机的初学者,强烈建议要先学习普通IO模拟I2C时序。
SPI通信芯片
STM32F103VET6有2个SPI接口,分别是SPI1和SPI2,我们用无线通信芯片NRF24L01和W25Q16来连接SPI1口,SPI2口用作和触摸屏芯片XPT2046通信。
作为初学者,看到SPI1口同时连接了W25Q16和NRF24L01两个芯片,感到诧异,为什么一个SPI口可以连接2个芯片?要理解这个原因,需要先简单的知道一下SPI通信的原理,SPI通信都会有一个CS片选引脚,听名字,片选引脚,也就是“选择哪一个芯片”的意思,也就是说,你的SPI口可以连接很多SPI通信的芯片,只要每个芯片的CS引脚连接到单片机不同的CS引脚就可以了。到时候,你要和哪个芯片通信,就把哪个芯片对应的CS引脚拉低就可以了。
W25Q16也是存储芯片,它与前面说的AT24C02的不同之处是,W25Q16是FLASH类型的存储芯片。你有机会的话,就会见到在实际的产品中,也有同时出现EEPROM和FLASH两种存储芯片的时候。FLASH类型的存储芯片一般要比EEPROM类型的芯片存储更多的内容,容量更大。
我们使用的时候,有一点非常重要,就是EEPROM可以一个字节一个字节的修改,而FLASH的话,即使你要修改一个字节,也需要先擦除一整页(256个字节)。所以,如果我们要存储字节为单位的数据的话,就用EEPROM,如果要存储很多数据的话,就用FLASH。
值得一提的是,ST单片机引脚与芯片之间采用双排排针,利用短路帽连接,如果不接短路帽,单片机引脚就是独立的引脚,还可以用杜邦线引出和电路板之外的各种芯片模块连接,这就是开发板的一大功能,如果直接相连,那就失去了“开发板”的意义了。而在这里,SPI1实际上也没有与NRF24L01直接相连,因为我们这里使用的是一个NRF24L01的插座,拔掉模块以后,实际上就是不连接的。
以上就是王总做过的一些STM32项目以及它的通信接口部分的经验总结,不知道有没有给你带来一些启发呢?“赠人玫瑰,手有余香”,好的东西只有分享出去才会产生更大的价值。为了更好地服务于电子工程社区,助力工程师成长,快包将定期邀请平台上的资深工程师,分享行业经验、设计技巧以及工程师开发的酸甜苦辣。
如果你也是工程师,也喜欢与人分享经验或者想要从资深研发大咖那里“偷师”,那么,这里是最适合你的地方!你只需要完成以下表单,即可加入工程师学习圈,免费获取各种专业学习资料以及行业圈子资源共享,并有机会受邀参加我爱方案网的独家媒体专访,加入快包工程师大家庭,下一期“谈”经验的大咖或许就是你!
后参与评论
我爱方案网candytang我爱方案网candytangsunny
sunnycandytangcandytangZoesunny
我是服务商关于STM32系列单片机I2C通信的有关问题,求教各位大牛 - 单片机当前位置:& &&&关于STM32系列单片机I2C通信的有关问题,求教各位大关于STM32系列单片机I2C通信的有关问题,求教各位大牛&&网友分享于:&&浏览:1次关于STM32系列单片机I2C通信的问题,求教各位大牛最近再做一个关于STM32F103系列单片机I2C通信的项目,因为以前没有玩过单片机所以有一些东西实在搞不懂,也没人可以咨询,所以来求教各位大牛了
先贴我的第一个问题:下面是一个简单的I2C写数据以及读数据的函数void&I2C_WriteByte(unsigned&char&write_address,unsigned&char&byte)
I2C_GenerateSTART(I2C2,ENABLE);
//产生起始条件
while(!I2C_CheckEvent(I2C2,&I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C2,EEPROM_ADDR,I2C_Direction_Transmitter);
//向设备发送设备地址
while(!I2C_CheckEvent(I2C2,&I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C2,&write_address);
//寄存器地址
while(!I2C_CheckEvent(I2C2,&I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C2,&byte);
//发送数据
while(!I2C_CheckEvent(I2C2,&I2C_EVENT_MASTER_BYTE_TRANSMITTED));
//发送完成
I2C_GenerateSTOP(I2C2,&ENABLE);
//产生结束信号
void&I2C_EE_BufferRead(u8*&pBuffer,&u8&ReadAddr,&u16&NumByteToRead)//将EEPROM的数据读入缓冲器
I2C_GenerateSTART(I2C1,&ENABLE);//产生&I2Cx传输&START条件
while(!I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_MODE_SELECT));//检查最近一次&I2C事件是否是输入的事件
/*&In&the&case&of&a&single&data&transfer&disable&ACK&before&reading&the&data&*/
if(NumByteToRead==1)&
I2C_AcknowledgeConfig(I2C1,&DISABLE);//使能或者失能指定&I2C的应答功能
I2C_Send7bitAddress(I2C1,&EEPROM_ADDRESS,&I2C_Direction_Transmitter);//向指定的从&I2C设备传送地址字,选择发送方向
while(!I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//检查最近一次&I2C事件是否是输入的事件
I2C_Cmd(I2C1,&ENABLE);//使能或者失能&I2C外设
I2C_SendData(I2C1,&ReadAddr);&//通过外设&I2Cx发送读取地址()
while(!I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_BYTE_TRANSMITTED));//检查最近一次&I2C事件是否是输入的事件
I2C_GenerateSTART(I2C1,&ENABLE);//产生&I2Cx传输&START条件
while(!I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_MODE_SELECT));//检查最近一次&I2C事件是否是输入的事件
I2C_Send7bitAddress(I2C1,&EEPROM_ADDRESS,&I2C_Direction_Receiver);//向指定的从&I2C设备传送地址字,选择接收方向
while(!I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//检查最近一次&I2C事件是否是输入的事件
/*&While&there&is&data&to&be&read&*/
while(NumByteToRead)&
/*&Test&on&EV7&and&clear&it&*/
if(I2C_CheckEvent(I2C1,&I2C_EVENT_MASTER_BYTE_RECEIVED))&//检查最近一次&I2C事件是否是输入的事件
if(NumByteToRead&==&2)
I2C_AcknowledgeConfig(I2C1,&DISABLE);//使能或者失能指定&I2C的应答功能
if(NumByteToRead&==&1)
I2C_GenerateSTOP(I2C1,&ENABLE);//产生&I2Cx传输&STOP条件
*pBuffer&=&I2C_ReceiveData(I2C1);//返回通过&I2Cx最近接收的数据
pBuffer++;&
NumByteToRead--;&
/*&Enable&Acknowledgement&to&be&ready&for&another&reception&*/
I2C_AcknowledgeConfig(I2C1,&ENABLE);//使能或者失能指定&I2C的应答功能
我查资料说STM32和器件通信有以下步骤:
写:检测SDA是否空闲;
-&按I2C协议发出起始讯号;
-&发出7位器件地址和写模式;
-&要写入的存储区首地址;
-&用页写入方式或字节写入方式写入数据;
读:检测SDA是否空闲;
-&按I2C协议发出起始讯号;
-&发出7位器件地址和写模式(伪写);
-&发出要读取的存储区首地址;
-&重发起始讯号;
-&发出7位器件地址和读模式;
-&接收数据;
无论读和写在发送完要写入或者读取的器件地址后都要再发送一个要写入或者读取的存储区地址,我的疑问是,这个地址读和写分别如何确定的呢?
还有一个疑问是:STM32有I2C1和I2C2两个I2C,如果我想做一下自回环,即I2C1给I2C2发送一个数据,I2C2收到后在传给I2C1一个数据,其中I2C1做主设备,I2C2做从设备,那么I2C1给I2C2发数据的时候器件地址是什么呢,I2C2给I2C1回数据的时候器件地址又是什么呢
东西有点多,跪求大神给解答!谢谢了------解决方案--------------------没用过,给2个参考
STM32硬件I2C读写AT24Cxx&http://download.csdn.net/detail/xiaoxia711/6411779
http://download.csdn.net/detail/sjxabc123/3716906
/BLOG_ARTICLE_152425.HTM------解决方案--------------------你照着单片机datasheet上的操作去配置寄存器就是你贴出来的程序。你说的EEPROM的地址,是因为这些器件内部已经有了通讯协议,你只需按照通讯协议去操作就会读/写对应地址的值。你如果想用单片机模拟这种协议,只需在地址后再加一条命令(即寄存器地址),就是你看到的EEPROM的操作。&你说的循环会有问题,估计是你的开始或停止信号时序有问题。
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有

我要回帖

更多关于 gsm模块与单片机通信 的文章

 

随机推荐