2013年3月27日 星期三

[STM32F3 教學] CRC 介紹



如果需要做資料傳輸,在資料的安全上需要做一些比對與檢查,而一些比較容易做,會使用checksum(把所有的資料累加在一起,所得到的結果),但是這樣的方式,最容易遇到一個問題,就是當今天資料有對換的時候,就檢查不出資料異常,或是資料錯誤,這時候不仿可以考慮一下使用CRC(Cycle Redundancy Check)的確認方式,這樣可以增加資料的穩定,在STM32F3有內建CRC的硬體模組供使用,就不需要佔用太多CPU的資源了。





說了這麼多,我相信很多人還是有聽沒有懂,關於CRC的做法,有興趣可以參考筆者之前的文章「CRC的介紹





我們以checksum來做解釋:如果今天的資料為D0/D1/D2/checksum,共有4bytes,如下圖所示:







今天假設在傳輸的過程式發生了錯誤,造成了D0/D1的資料互換,那麼checksum的機制就會失效了。






如果今天使用的是CRC8,而載子為「x8,x3,x2,1」,那麼:






一樣的,D0/D1的資料互換,不過這時候的CRC8機制就可以有效的檢查出資料出現異常。








程式範例:有1個硬體與1個軟體所實現的CRC8 運算,如果2者運算結果相同即亮LED4(藍燈),反之,則亮LED3(紅燈)




注: CRC_Cal8Bits() 1個硬體實現的CRC運算。Check_CRC8() 為一個軟體實現的CRC運算。




下一篇:ADC介紹







2013年3月22日 星期五

[馬達控制] C# 視窗介面

這次因為找到了一個有趣的課題,所以就花點時間在弄介面,所以這陣子的STM32F3的教學就先暫停一陣子,希望有在學習的人不要太失望,很快就會重新再開始繼續寫了。希望大家能體諒。


 


這次是要用C#寫一個UI(user interface), 其實以前也有寫過,不過這次想用比較不一樣的方式來寫,順便當作練習。


 


沒錯,一開始就要先把serial port 打通,順便弄點測試的log,還有裝制的版本號碼。



 


加入劃圖的元件,這次是使用ZedGraph的DLL, 這是一個非常好用的外掛元件,大家不仿試試看





 


把這次要劃的圖,做一下設定,這次要劃三個圖,所以資料還要再做整理一下



 


加入可以參整參數的元件。並測試功能



 


最後把所有的功能都做一次的測試,大概這個介面已經完成了。





目前遇到的困難:


 


因為沒有辦法解決c#的 performance, 原本device 每10ms 會送一筆資料進來,改為100ms 送一筆。 以後有空再來解決這些問題吧!
大至上的功能已完成。


未來規劃:


1、加入完整的硬體與MCU來做完整的馬達控制。


2、 支援多軸控制的介面(目前只有1軸)

3、 解決劃圖與資料處理的效能不佳。


4、 加入儲存參數的設定。


5、 加入錄製LOG的功能。


 


^^"




2013年3月8日 星期五

[STM32F3 教學] SPI介紹



SPI是一個比較好學的interface,而且除錯上也比I2C還要簡單,不過他的問題是,接腳上就會比I2C還要來得多,以成本的考量,當然I2C是首選,不過如果要考慮介面的穩定性和資料的可靠度的話,筆者是覺得SPII2C來得更穩定。而只要接的裝置不要太多,其實和I2C所差別的接腳並沒有很多。SPI的接腳每多一個裝置,就會需要再多1GPIO,用於CS(chip select)上,這就是為何SPI的接腳會多於I2C的原因了。




下圖是一個標準的SPI示意圖,MOSI(master output, slave input)MISO(master input, slave output)CS(chip select),只要使用SPI介面,就會有這四支腳。








一般來說,當CSLO時,代表master要對slave做通訊。而當CLK 上升緣時,這時候就會去讀取資料,而當CLK為下降緣時,這時候就可以改變資料的狀況。







下圖是一個多顆SPI裝置的示意圖,有幾顆SPI裝置,就需要多幾支IO來當作CS使用。(註:這邊的NSS就是CS)







有興趣的話也可以看Microchip所提供的SPI介面:「http://tinyurl.com/cpb4xsn






下一篇:CRC



[STM32F3 教學] I2C介紹




一般來說,I2C是一個只需要2支接腳,SCLSDA2支腳就可以串接很多裝置,並且也可以連來擴充使用。雖然I2C很好用也很方便,只需要2支腳就可以搞定,但如果非生了不可預期的現象需要除錯,那可就不是一個好玩的事情了。因為裝置都接在一起,當發生問題時,要除錯就有一定的困難性,這時候實務的經驗就變得非常的重要了,只要遇到問題和解決的問題夠多,當有問題時,就不怕手忙腳亂了。




下圖是一個比較典型的I2C架構圖。只要把所有的裝置串接在SDASCL上,就可以做I2C的通訊了。













1I2C的訊號,當SCLHI時,而SDAHIàLO時,這時為「Start」;而SDALOàHI時,這時後為「Stop」。記得。只有SCLHI時,這2protocol才為有效。SCLLO時,這時候是一般訊號的切換。









一般有效的資料,必需是SCLLO的時候,才可以做SDA的切換(每個BIT),假設你在SCLHI的時候切換,會被判定為「Start」或是「Stop」的,這是一件很可怕的事情。一定要注意。









下圖是一個I2C在做通訊時,應該有Protocol,一般來說,要先有START 接著7bit address 1bit R/W1bit ACK 8bit data 1bit ACK 最後是STOP 有沒有覺得很亂? 其實就是一定要有「頭(S)」、「尾(P)」和「資料(Data)」,事實上你可以把7bit address 1bit R/W當成是一個8bit的資料,這樣想應該就會簡單一點。














一般來說,拿到Device,通常要看的就是slave address,記住,這個slave address其實就是每顆I2C Device的身分(ID),通常都是7-bit,記得,這是一個向右移1位的address









至於整個I2C protocol的訊號,到底應該說host還是由slave來發動的,可以看下圖的幾個介紹,一般來說,「S」、「P」和「Salve address」都會由host 發動,其他的ACKDATA就要看2造雙方的需求了,也就是不一定。















一般來說,有時候會遇到準位不同的I2C,這時候就需要一個「中間人(BUFFER)」來幫忙解決訊號準位上的問題,一般我們會稱為「level shift」這樣就可以很安心的使用I2C介面了。









這就是一個比較複雜且多組的I2C使用方式。











當你了解I2C時,其實I2C 並不可怕,而且還挺好用的,畢竟硬體上只需要2支腳就可以搞定很多事。但相對的,在程式上就需要下非常多的功夫了,哈,這時候就是証明台上十分鐘,台下十年功的好機會了。祝大家使用I2C愉快。





下一章:SPI介紹




2013年3月7日 星期四

[STM32F3 教學] SYSTICK




STM32系列的MCU,一般都會設計一個SYSTICK的簡易型Timer,但又和其他Timer有什麼差別呢?
其實你可以把這個SYSTICK想成是一個24bit的簡單Timer,而STM32Timer因為是多功能的Timer,有很多功能都需要靠Timer來產生。例如PWM或是Counter,這個是比較特別的地方。




如果你有需要在此MCU使用RTOS的總統的話,一般都會建議使用此SYSTICK,因為當初就是把它規劃給RTOS使用。





使用SYSTICK也非常簡單,你只要照著上面做就行了。1000代表,1秒中會產生1000次中斷,也就是每1ms的頻率。





    /* SysTick end of count event each 1ms */



    RCC_GetClocksFreq(&RCC_Clocks);



    SysTick_Config(RCC_Clocks.HCLK_Frequency /
1000);





有興趣可以看一下SysTick_Config()這個副程式操作的幾個暫存器。其實還滿容易理解的。








另外ST習慣把中斷都放在stm32f30x_it.c的檔案裡,而SysTick_Handler()就是SYSTICK產生中斷就會跳入的副程式。不知道各位讀者有沒有發現ST的所寫的範例註解不太一樣,其實它是可以套用「Doxygen」的一套程式使用,有興趣的話可以參照「http://www.stack.nl/~dimitri/doxygen/」。






下一章:I2C介紹

[STM32F3 教學] USART with DMA






        在前二篇的文章有教到USART的範例,可是每次當PC送一筆資料給MCU時,就需要產生中斷,而MCU把資料送給PC時,又需要在原地等待。其實我們可以善用ST更好的功能,就是利用DMA幫我們把資料收/送進來,也就是我們只需要把資料buffer位址告訴PCMCU就可以比較不需要被中斷打擾了。只要適時的關心一下DMA是否已經把我們的資料準備好了,或者是已經把資料送完了。





        至於DMA要怎麼操作,要先知道我們需要操作的暫存器,再找出其暫存器所存在的絕對位址,首先,先找到整個模組被定義的位址,再找出offset的數位,這樣,我們就可以知道這個暫存器真正被定義的絕對位址了。我們只要把這個絕對位址告訴DMA模組,那麼他就可以幫我們完成交辦的任務了。記得,每個模組一開始被分配的DMA channel也是固定的,要事先規劃自己的需求。





因為DMA的每組channel可以使用的模組是固定的,所以需要事先規劃一下,例如USART1 Tx所佔用的位置就在DMA1ch4,而USART1 Rx就在DMA 1 ch5









程式上需要先看SPEC 找出相對應的暫存器,筆者習慣是找出模組的所在絕對位址,然後找出offset的位置,例如USART的模組和所需要的暫存器位置。









   DMA_InitStructure.DMA_DIR :









DMA_DIR_PeripheralSRC : 指定的周邊模組當作資料來源,也就是暫存器資料搬到buffer




DMA_DIR_PeripheralDST: 指定的周邊模組當作資料終點, 也就是把資料放到暫存器









   DMA_InitStructure.DMA_BufferSize: 指定buffer大小,而這個大小也會決定全滿或是半滿的中斷。









   DMA_InitStructure.DMA_PeripheralInc : 周邊模組暫存器是否需要自動+1




   DMA_InitStructure.DMA_MemoryInc : 資料buffer是否需要自動+1




   DMA_InitStructure.DMA_PeripheralDataSize : 周邊模組暫存器資料大小




   DMA_InitStructure.DMA_MemoryDataSize : 資料buffer資料大小




   DMA_InitStructure.DMA_Mode :




DMA_Mode_Normal: 1次性




DMA_Mode_Circular: 連續性




   DMA_InitStructure.DMA_Priority : DMA 優先權




   DMA_InitStructure.DMA_M 2M :是否用在非周邊模組的記憶體搬運(複製)









可以看一下程程上主要的DMA設定方式。














範例程式說明:


1、   USART1  Tx利用DMA,送出資料。

範例程式:



因為只有改main.c 請與之前的USART http://tinyurl.com/a7u4qz8」共用。




下一篇,SYSTICK