您的位置 首页 新品

STM32的SPI问题。

问题描述:之前一直使用的单片机是LPC2109,对其SPI很熟悉。基本就是原本拿来稍作修改就用。由于某种原因需要使用STM32,然后设备的驱动是…

问题描绘:

之前一向运用的单片机是LPC2109,对其SPI很熟悉。根本便是原本拿来稍作修正就用。
我们某种原因需求运用STM32,然后设备的驱动是之前写好的,只修正了一些硬件操控端口,我们硬件驱动运用到了SPI接口,而我是把SPI接口供给了出来,原本认为简略修正SPI装备到对应单片机就行了。简略看了STM3的SPI装备,驾轻就熟改代码,瞬间表现了杰出的接口有哈。
编译,生成方针文件,下载运转。
并没有呈现料想的成果。我们之前的设备驱动是能用的,所以扫除设备驱动问题。
开端认为是我们对STM32端口装备的不熟悉导致的、看手册,看他人代码,没发现问题。
debug……..
问题定在SPI代码上。检查装备,相同啊。抑郁!!!
把自己装备考到他人能用的代码中,能够运用。愈加抑郁!!!!
debug看存放器。比照能运转代码存放器状况。发现运转到一段代码的时分存放器不同
SPI_CR 0x0043
SPI_CR 0x2
看datasheet.OVR置位。问题应该就在这了。可是为什么呢??????

搜此问题,此处出自这儿

溢出过错(OVR)
 溢出过错一共接连传输多个数据时,后一个数据掩盖了前一个数据而产生的过错。
 状况标志SPIF一共的是数据传输正在进行中,它对数据的传输有较大的影响。主器材的SPIF有用由数据存放器的空标志SPTE=0产生,而从器材的SPIF有用则只能由收到的第一个SCK的跳变产生,且又我们从器材的SPIF和主器材宣布的SCK是异步的,因而从器材的传输标志SPIF从相对于主器材的传输标志SPIF主有必定的滞后。如图4所示,在主器材接连发送两个数据的时分将有或许导致从器材的传输标志和主器材下一个数据的传输标志相堆叠(图4中虚线和暗影部分),第一个收到的数据必定被掩盖,第二个数据的收/发也必定犯错,产生溢出过错

图4溢出过错
  经过对从器材的波形剖析发现,counter=8后的第一个时钟周期,数据最终一位的传输现已完结。在数据现已收/发结束的情况下,counter=8状况的长短对数据的正确性没有影响,因而能够缩短counter=8的状况,以防止前一个SPIF和后一个SPIF相堆叠。这样,从硬件上防止了这一阶段的溢出过错。
  可是,假如从器材作业速度不够快或许软件正在处理其他作业,在SPI接口接纳到的数据尚未被读取的情况下,又接纳到一个新的数据,溢出过错仍是会产生的。此刻,SPI接口维护前一个数据不被掩盖,放弃新收到的数据,置溢出标志OVR=1;别的宣布中止信号(假如该中止答应),告诉从器材及时读取数据。

23.4.7 过错标志位
I2S 单元有2个过错标志位。
下溢标志位(UDR)
在从发送形式下,假如数据传输的第一个时钟边缘抵达时,新的数据依然没有写入SPI_DR存放
器,该标志位会被置’1’ 。在存放器SPI_I2SCFGR的I2SMOD 方位’1’ 后,该标志位才有用。假如
存放器SPI_CR2的ERRIE位为’1’ ,就会产生中止。
经过对存放器SPI_SR进行读操作来铲除该标志位。
上溢标志位(OVR)
假如还没有读出前一个接纳到的数据时,又接纳到新的数据,即产生上溢,该标志方位’1’ ,如
果存放器SPI_CR2的ERRIE位为’1’ ,则产生中止指示产生了过错。
这时,接纳缓存的内容,不会改写为从发送设备送来的新数据。对存放器SPI_DR的读操作回来
最终一个正确接纳到的数据。其他一切在上溢产生后由发送设备宣布的16位数据都会丢掉。
经过先读存放器SPI_SR再读存放器SPI_DR,来铲除该标志位。

void SPI_write_byte(u8 data){S0SPDR = data;while ((S0SPSR & 0x80) == 0);}u8 SPI_read_byte(void){S0SPDR = 0xff;while((S0SPSR & 0x80) == 0);return (S0SPDR);}

整个工程修正的代码如下(注释代码为不能正常作业的):

/**/// void SPI_write_byte(u8 data)// {// while (!(SPI1->SR & (1 << 1)));// SPI1->DR = data;// }// u8 SPI_read_byte(void)// {// while (!(SPI1->SR & 1));// return SPI1->DR;// }u8 spi_rw(u8 data){while (!(SPI1->SR & (1 << 1)));SPI1->DR = data;while (!(SPI1->SR & 1));return SPI1->DR;}/**/// SPI_write_byte(op  (address & ADDR_MASK));// SPI_write_byte(data);spi_rw(op  (address & ADDR_MASK));spi_rw(data);/**/// SPI_write_byte(RBM);spi_rw(RBM);// *data = SPI_read_byte();*data = spi_rw(0xff);/**/// SPI_write_byte(WBM);spi_rw(WBM);// SPI_write_byte(*data);spi_rw(*data);/**/

看完根本就理解问题所在了…

剖析问题:

我是依照LPC的SPI装备的,而现在的是STM32,问题要害就在于STM32的承受缓冲空和发送缓冲非空的标志是不同的。而LPC单片机是相同的。仔细剖析我写的代码,实际上每次执行都缺少了对状况的判别,然后导致了数据的溢出。

解决问题:

修正代码如下,问题解决。

u8 SPI_write_byte(u8 data){while (!(SPI1->SR & (1 << 1)));SPI1->DR = data;while (!(SPI1->SR & 1));return SPI1->DR;}u8 SPI_read_byte(void){while (!(SPI1->SR & (1 << 1)));SPI1->DR = 0xff;while (!(SPI1->SR & 1));return SPI1->DR;}

总结:

问题出在思想的定势,先入为主的思想导致了过错的思想,也表现了对问题的剖析才能,以及编码的随意性。哎血的经验啊。。。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/265223.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部