<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          STM32的SPI問題。

          作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
          問題描述:

          之前一直使用的單片機(jī)是LPC2109,對(duì)其SPI很熟悉?;揪褪窃灸脕?lái)稍作修改就用。
          由于某種原因需要使用STM32,然后設(shè)備的驅(qū)動(dòng)是之前寫好的,只修改了一些硬件控制端口,由于硬件驅(qū)動(dòng)使用到了SPI接口,而我是把SPI接口提供了出來(lái),本來(lái)以為簡(jiǎn)單修改SPI配置到對(duì)應(yīng)單片機(jī)就行了。簡(jiǎn)單看了STM3的SPI配置,輕車熟路改代碼,瞬間體現(xiàn)了良好的接口有哈。
          編譯,生成目標(biāo)文件,下載運(yùn)行。
          并沒有出現(xiàn)預(yù)想的結(jié)果。由于之前的設(shè)備驅(qū)動(dòng)是能用的,所以排除設(shè)備驅(qū)動(dòng)問題。
          開始以為是由于對(duì)STM32端口配置的不熟悉導(dǎo)致的、看手冊(cè),看別人代碼,沒發(fā)現(xiàn)問題。
          debug........
          問題定在SPI代碼上。查看配置,一樣啊。郁悶?。?!
          把自己配置考到別人能用的代碼中,可以使用。更加郁悶?。。?!
          debug看寄存器。對(duì)比能運(yùn)行代碼寄存器狀態(tài)。發(fā)現(xiàn)運(yùn)行到一段代碼的時(shí)候寄存器不同
          SPI_CR 0x0043
          SPI_CR 0x2
          看datasheet.OVR置位。問題應(yīng)該就在這了??墒菫槭裁茨???????

          本文引用地址:http://www.ex-cimer.com/article/201611/318264.htm

          搜此問題,此處出自這里

          溢出錯(cuò)誤(OVR)
           溢出錯(cuò)誤表示連續(xù)傳輸多個(gè)數(shù)據(jù)時(shí),后一個(gè)數(shù)據(jù)覆蓋了前一個(gè)數(shù)據(jù)而產(chǎn)生的錯(cuò)誤。
           狀態(tài)標(biāo)志SPIF表示的是數(shù)據(jù)傳輸正在進(jìn)行中,它對(duì)數(shù)據(jù)的傳輸有較大的影響。主器件的SPIF有效由數(shù)據(jù)寄存器的空標(biāo)志SPTE=0產(chǎn)生,而從器件的SPIF有效則只能由收到的第一個(gè)SCK的跳變產(chǎn)生,且又由于從器件的SPIF和主器件發(fā)出的SCK是異步的,因此從器件的傳輸標(biāo)志SPIF從相對(duì)于主器件的傳輸標(biāo)志SPIF主有一定的滯后。如圖4所示,在主器件連續(xù)發(fā)送兩個(gè)數(shù)據(jù)的時(shí)候?qū)⒂锌赡軐?dǎo)致從器件的傳輸標(biāo)志和主器件下一個(gè)數(shù)據(jù)的傳輸標(biāo)志相重疊(圖4中虛線和陰影部分),第一個(gè)收到的數(shù)據(jù)必然被覆蓋,第二個(gè)數(shù)據(jù)的收/發(fā)也必然出錯(cuò),產(chǎn)生溢出錯(cuò)誤

          圖4溢出錯(cuò)誤
            通過對(duì)從器件的波形分析發(fā)現(xiàn),counter=8后的第一個(gè)時(shí)鐘周期,數(shù)據(jù)最后一位的傳輸已經(jīng)完成。在數(shù)據(jù)已經(jīng)收/發(fā)完畢的情況下,counter=8狀態(tài)的長(zhǎng)短對(duì)數(shù)據(jù)的正確性沒有影響,因此可以縮短counter=8的狀態(tài),以避免前一個(gè)SPIF和后一個(gè)SPIF相重疊。這樣,從硬件上避免了這一階段的溢出錯(cuò)誤。
            但是,如果從器件工作速度不夠快或者軟件正在處理其他事情,在SPI接口接收到的數(shù)據(jù)尚未被讀取的情況下,又接收到一個(gè)新的數(shù)據(jù),溢出錯(cuò)誤還是會(huì)發(fā)生的。此時(shí),SPI接口保護(hù)前一個(gè)數(shù)據(jù)不被覆蓋,舍棄新收到的數(shù)據(jù),置溢出標(biāo)志OVR=1;另外發(fā)出中斷信號(hào)(如果該中斷允許),通知從器件及時(shí)讀取數(shù)據(jù)。

          23.4.7 錯(cuò)誤標(biāo)志位
          I2S 單元有2個(gè)錯(cuò)誤標(biāo)志位。
          下溢標(biāo)志位(UDR)
          在從發(fā)送模式下,如果數(shù)據(jù)傳輸?shù)牡谝粋€(gè)時(shí)鐘邊沿到達(dá)時(shí),新的數(shù)據(jù)仍然沒有寫入SPI_DR寄存
          器,該標(biāo)志位會(huì)被置’1’ 。在寄存器SPI_I2SCFGR的I2SMOD 位置’1’ 后,該標(biāo)志位才有效。如果
          寄存器SPI_CR2的ERRIE位為’1’ ,就會(huì)產(chǎn)生中斷。
          通過對(duì)寄存器SPI_SR進(jìn)行讀操作來(lái)清除該標(biāo)志位。
          上溢標(biāo)志位(OVR)
          如果還沒有讀出前一個(gè)接收到的數(shù)據(jù)時(shí),又接收到新的數(shù)據(jù),即產(chǎn)生上溢,該標(biāo)志位置’1’ ,如
          果寄存器SPI_CR2的ERRIE位為’1’ ,則產(chǎn)生中斷指示發(fā)生了錯(cuò)誤。
          這時(shí),接收緩存的內(nèi)容,不會(huì)刷新為從發(fā)送設(shè)備送來(lái)的新數(shù)據(jù)。對(duì)寄存器SPI_DR的讀操作返回
          最后一個(gè)正確接收到的數(shù)據(jù)。其他所有在上溢發(fā)生后由發(fā)送設(shè)備發(fā)出的16位數(shù)據(jù)都會(huì)丟失。
          通過先讀寄存器SPI_SR再讀寄存器SPI_DR,來(lái)清除該標(biāo)志位。

          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);}

          整個(gè)工程修改的代碼如下(注釋代碼為不能正常工作的):

          /**/// 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配置的,而現(xiàn)在的是STM32,問題關(guān)鍵就在于STM32的接受緩沖空和發(fā)送緩沖非空的標(biāo)志是不同的。而LPC單片機(jī)是相同的。仔細(xì)分析我寫的代碼,實(shí)際上每次執(zhí)行都缺少了對(duì)狀態(tài)的判斷,從而導(dǎo)致了數(shù)據(jù)的溢出。

          解決問題:

          修改代碼如下,問題解決。

          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;}


          總結(jié):

          問題出在思維的定勢(shì),先入為主的思想導(dǎo)致了錯(cuò)誤的思維,也體現(xiàn)了對(duì)問題的分析能力,以及編碼的隨意性。哎血的教訓(xùn)啊。。。



          關(guān)鍵詞: STM32SPI問

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();