历史上的今天

今天是:2024年09月03日(星期二)

正在发生

2019年09月03日 | 关于stm32通信协议:软件模拟SPI、软件模拟I2C的总结

发布者:心连心意 来源: eefocus关键字:stm32  通信协议  软件模拟SPI  软件模拟I2C 手机看文章 扫描二维码
随时随地手机看文章

趁着帮老师代上嵌入式实验课的机会,又重新熟悉了一遍stm32的通信协议:串口协议、SPI协议、I2C协议、RS485协议。大概半年前,是过了一遍的,但也只停留于读了遍代码,跑了下例程,最近又过了一遍(自己仔细的看了一遍,老师还给我们讲了一遍,自己又讲了一遍),然后还写了一遍软件模拟SPI、软件模拟I2C的代码,才彻底的懂了个皮毛 ,:)。稍微总结下吧,总结的不好,都是自己的理解,仅供参考,主要说软件模拟SPI、I2C,硬件SPI和硬件I2C就不说了。


串口协议

串口协议没什么可说的,现在常用的串口协议,是基于以前的RS232的协议,因为RS232的引脚太多而改进过来的。

物理层只用三根引脚:TXD、RXD、GND(最好接,不然有点影响),然后TXD接RXD、RXD接TXD、GND接GND(这里我第一次接错过的,所以写出来),通过有两个收发引脚就能看出,串口协议是支持全双工的;

协议层的话,就是起始信号(1个0表示)+数据包(5、6、7、8位可选)+校验位(无、0、1、奇、偶可选)+停止信号(0.5、1、1.5、2个1表示)。

串口协议,很常见,多用于打印调试信息,也比较简单;


RS485协议

RS485协议,协议层未改,只是在串口协议的物理层做了修改,外接了一个物理收发器,然后在通信双方的两条A、B线加了电阻,通过测A、B线的电压差来传送高低电平信号,所以485通信协议的特点就是抗干扰性强、传输距离远,可以组网。由于是通过A线、B线的电压差传输高低电平信号,所以是半双工的,同一时刻只能发送或者接收。物理连接方式:A线接A线,B线接B线。


如何理解半双工、全双工,我看到网上一个很好的例子可以帮助理解。就是说,把半双工通信比作是对讲机通信,全双工就是手机通信,对讲机同一时刻只能说或者是听,而手机是可以同时说、听的。


前面两个协议比较简单,而SPI协议、I2C协议稍微麻烦点,主要说一下。


SPI协议

SPI协议,多应用于ADC、DA、LCD等设备与MCU间,要求通信速率较高的场合。一般需要4根信号线,分别是MOSI、MISO、SCK、CS线。但是!敲黑板!有可能可以只用3根,当你通过SPI和DA设备通信的时候,MISO线就可以不要了,然后我们老师更夸张,说如果你只连一个DA设备的话,那么CS线也可以不要,这里我有点不敢苟同,因为毕竟片选线是控制通讯开始结束的,但这种思想是可取的了,规则是死的,人是活的,要活学活用,这里当时听到老师讲这点的时候还是有点震撼的。扯的有点远了。。。但其实,这里要说的软件模拟。


还是回到正题,接着说软件模拟SPI,当MCU的SPI外设不够用的时候,我们就会用GPIO去模拟SPI的方式,去和支持SPI的从设备通信。下面直接贴代码了,代码已经调通的了。我做的实验是用F429IGT6通过软件模拟SPI读写一款W25Q128的FLASH芯片,模拟的是模式3(CPOL=1,CPHA=1),有两点原因:①模式3的SCK空闲电平为高电平,由高电平向低电平翻转快,而且容易;②模式3在偶数边沿采样,防止第一个信号没采到。


首先,是GPIO的初始化,CS引脚、MOSI引脚、MISO引脚、SCK引脚。除了MISO引脚配成输入模式,其余三个引脚都配成输出模式(推挽输出)。


void SPI_FLASH_Init(void)

{

/*定义一个GPIO_InitTypeDef类型的(基本IO)结构体*/

  GPIO_InitTypeDef GPIO_InitStructure;

  

  /***** 使能 GPIO 时钟 *****/

 /* 使能 FLASH_SPI引脚的GPIO时钟< SPI_CS; SPI_MOSI; SPI_MISO; SPI_SCK > ( F口 )*/

  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF, ENABLE);


/* < 配置 SPI_FLASH_SPI 引脚: SCK; MISO; MOSI > */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7  | GPIO_Pin_9;

 /* 设置引脚模式为 SPI_5 复用功能*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 

/* 设置引脚速率为50MHz */   

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   

  /* 设置引脚的输出类型为推挽输出*/

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  /* 设置引脚为无上拉 下拉模式*/

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  

  /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO_F*/

GPIO_Init(GPIOF, &GPIO_InitStructure);

  

/* < 配置 SPI_FLASH_SPI 引脚: CS > */

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_Init(GPIOF, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

GPIO_Init(GPIOF, &GPIO_InitStructure);

GPIOF->BSRRL = GPIO_Pin_6;//拉高CS线

GPIO_SetBits(GPIOF, GPIO_Pin_7);//拉高时钟线,模拟模式3


}


接下来,就是基本的发送、接收函数了。延时是用Symtick来延时,为了延时精确,符合W25Q128芯片数据手册的时序,理论上应该也可以用软件延时(未尝试)。


//软件模拟SPI写(发送)

void Soft_SPI_Write(uint8_t a)

{

uint8_t cnt;

for(cnt=0;cnt<8;cnt++)

{

GPIO_ResetBits(GPIOF, GPIO_Pin_7);//拉低CLK

Delay_us(10);//这个延时时间任意,但要大于芯片数据手册上的(纳秒级的)

if(a &0x80)

{

GPIO_SetBits(GPIOF, GPIO_Pin_9);

}

else

{

GPIO_ResetBits(GPIOF, GPIO_Pin_9);

}

a <<= 1;

Delay_us(10);

GPIO_SetBits(GPIOF, GPIO_Pin_7);//拉高CLK

Delay_us(10);

}

}


//软件模拟SPI读(接收)

uint8_t Soft_SPI_Read(void)

{

uint8_t cnt;

uint8_t Rxdata = 0;

for(cnt=0;cnt<8;cnt++)

{

GPIO_ResetBits(GPIOF, GPIO_Pin_7);//拉低CLK

Delay_us(10);

Rxdata <<= 1;

if(GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_8))

{

Rxdata |= 0x01;

}

GPIO_SetBits(GPIOF, GPIO_Pin_7);//拉高CLK

Delay_us(10);

}

return Rxdata;

}


然后是,W25Q128芯片的等待准备好的函数。通过读取该芯片的BUSY位是否为1(繁忙)实现,这款FLAH 是这样的,你要根据你要执行的操作找到要发送的指令是哪个,以及对应的时序,按照它的时序来,注意时序线上的时间。


void Soft_WaitFlahToBeReady(void)

{

u8 FLASH_Status = 0x01;

GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Soft_SPI_Write(0x05);

do

{

Soft_SPI_Write(0xFF);

FLASH_Status = Soft_SPI_Read();

}

while((FLASH_Status & 0x01) == 1);


printf("rn 繁忙状态位为: 0x%Xrn", FLASH_Status);

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**


}


再是,FLASH 的扇区擦除函数了,所有的FLASH每次写入前都要进行擦除。


void Soft_Flash_SectorErase(u32 EraseAddr)

{

GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Soft_SPI_Write(0x06);//写使能指令

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**


GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Soft_SPI_Write(0x20);//扇区擦除指令

Soft_SPI_Write((EraseAddr & 0xFF0000) >> 16);

Soft_SPI_Write((EraseAddr & 0xFF00) >> 8);

Soft_SPI_Write((EraseAddr & 0xFF));

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**

Soft_WaitFlahToBeReady();

}


再就是,页写入函数了,这款FLASH芯片支持三种写入方式,单字节写入、页写入(<256Bytes)、多字节写入(基于页写入)。显然,页写入方式比单字节写入快,这里我只做了页写入的方式,用于验证是否成功,多字节写入的方式可以在此方式上拓展,秉火的例程上有,可以参考。


void Soft_SPIFlashPageWrite(u8* Pbuffer,u32 Writeaddr,u16 NumberByteToWrite)

{

GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Soft_SPI_Write(0x06);//写使能指令

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**


GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Soft_SPI_Write(0x02);//写页写入指令


Soft_SPI_Write((Writeaddr & 0xFF0000) >> 16);

Soft_SPI_Write((Writeaddr & 0xFF00) >> 8);

Soft_SPI_Write((Writeaddr & 0xFF));

if(NumberByteToWrite > 256)

{

NumberByteToWrite = 256;

printf("写入的字节数大于256");

}

while(NumberByteToWrite--)

{

Soft_SPI_Write(*Pbuffer);

Pbuffer++;

}

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**

Soft_WaitFlahToBeReady();

}


最后就是读FLASH函数了,该芯片支持多字节一直读。


void Soft_SPIFlashRead(u8* Pbuffer,u32 ReadAddr,u16 NumberByteToRead)

{


GPIOF->BSRRH = GPIO_Pin_6;  //**CS低**

Delay_us(10);

Soft_SPI_Write(0x03);//写读使能指令


Soft_SPI_Write((ReadAddr & 0xFF0000) >> 16);

Soft_SPI_Write((ReadAddr & 0xFF00) >> 8);

Soft_SPI_Write((ReadAddr & 0xFF));

while(NumberByteToRead--)

{

//Soft_SPI_Write(0xFF);//这里一开始是加了的,因为SPI是全双工的,

*Pbuffer = Soft_SPI_Read();//但是加了,读就有问题,然后仔细看了时序图,发现其实不加也可以

Pbuffer++;

}

GPIOF->BSRRL = GPIO_Pin_6;  //**CS高**

}

关键字:stm32  通信协议  软件模拟SPI  软件模拟I2C 引用地址:关于stm32通信协议:软件模拟SPI、软件模拟I2C的总结

上一篇:JTAG和SWD的禁用配置及无法下载问题解决
下一篇:STM32常用通信——USART,IIC,SPI,CAN

推荐阅读

AI翻译是否精准一直是人们重点关心的问题。尽管Google翻译、科大讯飞翻译机2.0、腾讯“翻译君”等由行业巨头推出的产品纷纷亮相,海量翻译数据正在积累,算法和神经网络正在优化,但类似AI同传在博鳌亚洲论坛的失误,仍让人为AI翻译捏一把汗。8月28日,记者在成都高新区了解到,“阅读级”AI翻译产品“云译通”已在今年上线,通过打造4000亿字的自由双语平...
8月29日,“服务机器人第一股”科沃斯(603486)发布2019年半年报,报告期内,科沃斯品牌服务机器人实现销售收入16.38亿元人民币,较上年同期增长11.24%,占公司当期营业收入的 67.5%。 此外,科沃斯积极加大研发投入,支出较上年同期增长38.86%。财报显示,科沃斯持续推进战略落地,在收缩家用服务机器人ODM 业务的同时,进一步在全球市场大力...
在2019年,联想在Tech World大会上率先展示了Razr折叠屏手机,独特的翻盖式折叠屏身上既有经典翻盖手机的影子,同时又极具未来感。  时隔近一年时间,摩托罗拉折叠屏新机终于要推出国行版。  9月3日消息,摩托罗拉宣布将于9月10日举行新品发布会,海报显示本次发布会将推出折叠屏手机,这将是摩托罗拉首款5G折叠屏。  根据披露的信息,摩...
机器视觉行业主要上市公司:目前国内机器视觉行业的上市公司主要有天准科技(688003)、美亚光电(002690)、精测电子(300567)、赛腾股份(603283)、矩子科技(300802)、先导智能(300450)、康鸿智能(839416)、劲拓股份(300400)等。本文核心数据:技术来源国、专利申请人排名、专利申请新进入者、市场最高专利价值全文统计口径说明:1)搜索关键...

史海拾趣

问答坊 | AI 解惑

12月09日 -硬件原理图修改版—最后一次查错

12月09日 最新版原理图文件 请大家做最后一次检查,之后我们就开始布线了。 wangkj: 晶体直接连接到a3p060不可行 arm上的的晶振信号比较低,到a3p060后信号不对。 所以,这个方案需要修改。 用外置晶振或者经过cpu的信号才行。 这个是我 ...…

查看全部问答∨

莫名其妙有输出?

两个单片机之间的通信,只要一上电,其中一个单片机上的输出信号端口就一直发送脉冲信号,程序中应该是在一个标志位的控制下才会发送数据的。已经检测外围电路,并没有干扰,就是由单片机自身发出的信号。造成这种现象的原因可能是什么啊?…

查看全部问答∨

DSP6713开发板,DSP开发板,6713开发板

开发板中心网址:http://www.huanor.com 开发板中心论坛:http://www.huanor.com/bbs 淘宝网址:http://shop36289907.taobao.com QQ: 1060087047或者871001268 手机:13466617480或者15801405586 座机:010-82534219 Email:huanor_sales@hot ...…

查看全部问答∨

Porting linux to Stellaris Cortex-M3

最近Linux讨论组里面比较火的一个主题,谁有兴趣耍耍,目标平台LM3S9B96     <5>Linux version 2.6.33-arm1 (fernando@fernando-POS-MIG31AG) (gccversion 4.5.2 (Sourcery G++ Lite 2011.03-41) ) #127 Tue Sep 2709:14:21 BRT 2 ...…

查看全部问答∨

2010英特尔杯获奖作品--皮影艺术,凌动舞台

针对皮影戏这一国家非物质文化遗产逐步淡出人们视线的现状,以唤回人们对皮影的关注为目的,设计了皮影表演系统。系统将现代计算机技术与传统皮影艺术相结合,使用高效能的基于Intel(R) Atom(TM)处理器的嵌入式平台,结合自主设计的数字控制机械系 ...…

查看全部问答∨

北京招聘两个嵌入式软件工程师

人手不够啊,想招两个嵌入式搞软件的专职人员,一个有工作经验的,可以直接上手干活的,另一个可以是应届的新手,慢慢培养。 招聘职位:嵌入式软件工程师 职位要求: 相关专业毕业,专科以上学历; 一年以上相关工作经验; 熟悉C语言,及嵌入 ...…

查看全部问答∨

ARM 用 SPI 接外部扩展 AD

小弟新手,刚掌握 arm 2119基本的功能,现在想用SPI 总线外接一个外部扩展的AD, 目前想用AD7714. 但不知道如何下手,相关的手册都读过了,但对外接AD内部寄存器的操作不知道如何编程。 哪位大哥有类似的SPI控制外扩AD或者FLASH的程序,求一个,万 ...…

查看全部问答∨

出青风 QF-TM4C123 TI LM4F232 Cortex-M4 开发板

本帖最后由 nwcheroes 于 2014-7-21 23:48 编辑 青风QF-TM4C123开发板,做毕设的时候用过一段时间,做完就放着吃灰了。现在和jlink打包一起出,资料光盘都有 http://item.taobao.com/item.htm?id=40208434125 …

查看全部问答∨

一些电子模块、板子、相机

本帖最后由 ddllxxrr 于 2016-1-7 16:23 编辑 准备离校了,开始清仓换点生活费。 现在还在整理当中,整理好后,统一发图及链接。 东西还会陆续更新,什么电饭煲啊,电磁炉啊,低音炮,捷安特660,什么乱七八糟的都出了 …

查看全部问答∨

寻找一个5v转3.3v DC-DC电流2A

寻找一个5v转3.3v DC-DC电流2A 如题,有认识的介绍下,谢谢了 …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved