2016年10月31日 星期一

作業系統之前的程式 for stm32f4discovery (16.3) - spi1 與 spi2 對接

蝸牛角上爭何事,石火光中寄此身。
左邊 DD 的服飾是不是太華麗了, 衣服很好看, 但不好穿上, 搞得我滿頭大汗才順利裝扮完畢, 尤其是那大腿襪, 真的有夠難穿, 總是卡在腳踝的部份, 大腿襪 size 一定有問題。疑 ... 這篇好像不是談這個 ... 趕緊進入正題。

在完成《作業系統之前的程式 for stm32f4discovery (16) - spi》之後, 我打算把 stm32f407 discovery board 的 spi1 <-> spi2 互接, 並測試能否從 spi1 送資料, 從 spi2 收到這筆資料。

這麼有創意的點子當然不是我想到的,《STM32自学笔记》裡頭有個 spi 實驗就是這麼做的。

spi 接腳
使用 soft nss
spi1 : pa5, pa6, pa7 master
spi2: pb13, pb14, pb15 slave
pa5 <-> pb13 sck
pa6 <- pb14 miso
pa7 <-> pb15 mosi

spi1 設定為 master。
spi2 設定為 slave。

spi1 接在 ABP2 再呼叫 SystemInit() 之後被設定為 84MHz, spi2 接在 APB1, 被設定為 42MHz。

對接之後, spi2 是吃 spi1 sck 的時脈, 所以 spi2 的 clock 設定並不是依照暫存器的值來反應 clock。

由於我已經知道怎麼設定 spi, 此役我信心滿滿, 應該沒問題吧, 不過沒有搞懂 spi 是在 master 送出資料時, clock 才會啟動, 而這個時候不只是把 master 資料送出, 如果 slave 要接收資料時, 也要在 master 送出資料的程式碼這邊, 接在下方補上收 slave 資料的程式碼, 這樣 slave 才能在這時間點收到資料, 用講的很亂, 請直接參考 my_spi.c spi1_spi2_send_recv() 就知道我在說什麼。

fig 1 fig 2

當把所有錯誤排除之後, 終於可以脫離 LA 了, 最終我可以從 usart2 來印出從 spi1/spi2 互相傳輸的資料, fig2, fig2 圖示這次的線路接法, 看來有點複雜, 其實並沒有那麼可怕, 由於我把 pa2, pa3 拿去用在 spi1, 所以原本的 usart2 pa2, pa3 就不能用了, 我修改了原本的 usart2 程式碼, 讓它可以接 pd5, pd6, 所以後面的那組接線是 usart2, 前面的上方則是用 LA 接出來看波形的, 下方才是 spi1 與 spi2 對接。

source code:
https://github.com/descent/stm32f4_prog/blob/master/spi/my_spi.c

my_spi.c
 837 void spi1_spi2_send_recv(u8 spi1_data, u8 spi2_data, u8 *r_spi1_data, u8 *r_spi2_data)
 838 {
 839   //SPI1->DR = 0xfa; // write data to be transmitted to the SPI data register
 840   //SPI2->DR = 0xfe; // write data to be transmitted to the SPI data register
 841   SPI1->DR = spi1_data; // write data to be transmitted to the SPI data register
 842   SPI2->DR = spi2_data; // write data to be transmitted to the SPI data register
 843   while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
 844   while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
 845   while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
 846   *r_spi1_data = SPI1->DR; // return received data from SPI data register
 847 #if 1
 848   while( !(SPI2->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
 849   while( !(SPI2->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
 850   while( SPI2->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
 851   *r_spi2_data = SPI2->DR; // return received data from SPI data register
 852 #endif
 853 }

感謝 juluos 陳兄的意見, 讓我得以完成這個實驗。

usart 和 spi 都好了, 再來就可以搞更有趣的事情了。

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。