既然是新手帖,寫給新手們的入門帖,那自然要從最簡單最基礎的做起。
學軟件開發的入門實驗可能是“hello world”也可能是“hello c”可能大家發揮想象,不一定是一樣的,但是學單片機一定都是一樣的,大家拿到單片機的第一個入門實驗一定是:流水燈!
話不多說,先截圖上代碼(貼在帖子中太小了,我弄到附件里面去了,大家將就看,嫌棄小的移步去附件),然后再講解。
4.png (80.42 KB, 下載次數: 48)
下載附件
2021-9-14 18:14 上傳
首先,需要熟悉一下Myos的系統環境,左側為系統的文件目錄,具體如下:
1.png (3.84 KB, 下載次數: 47)
下載附件
2021-9-14 18:14 上傳
最前面的帶Application前綴的應用程序文件夾,帶device的是STM8的驅動文件夾,帶Myos前綴的是系統核心文件夾,而Myos系統的主函數雖然也是從main函數開始運行,但是由于運行了Myos操作系統,所以不再使用main函數作為入口函數,而是以osdemo.c文件中的OS_ApplicationMainThread函數作為入口函數,翻譯過來即為“應用程序主線程”。長這樣:
6.png (10.44 KB, 下載次數: 48)
下載附件
2021-9-14 18:14 上傳
然后我們的代碼寫在這個函數內,由于這個函數是一個獨立的線程,所以在函數的最后一定要記得添加OS_ThreadExit函數來執行線程銷毀工作,否則函數退出時則會返回到一個未知的狀態,也就是程序跑飛,但是需要注意的是只有在線程需要退出的時候才能調用這個函數,在任意一個用戶線程中,只要調用了OS_ThreadExit函數則必然會導致當前的線程被銷毀。
OK,開始講解代碼:
首先,我們定義一個regist變量來保存一下流水燈的狀態,這個和51的流水燈實現還是略有區別的,需要注意的是STM8、Cortex M系列的微控制器并不支持對IO口的位操作,每次操作至少是以字節(8位)訪問方式進行訪問。
接下來如下三行代碼:
2.png (932 Bytes, 下載次數: 57)
下載附件
2021-9-14 18:14 上傳
我所使用的開發板上的四個LED燈是連接在PC1-PC4上的,所以需要設置一下PC口,首先看DDR寄存器,DDR寄存器是控制IO的數據方向的,輸入還是輸出由這個寄存器控制。而CR1在輸出模式下是控制IO的輸出類型,開漏(無法輸出高電平)輸出還是推挽輸出。CR2則是輸出模式下的IO翻轉速度,置高為10MHZ。
具體的寄存器說明可以參考上傳的STM8S參考手冊GPIO章節。
5.png (3.09 KB, 下載次數: 54)
下載附件
2021-9-14 18:14 上傳
循環體代碼如上,首先我們的流水燈是一個死循環,一直執行流水燈操作,對于regist的操作就是流水燈的發生過程,由于我只有4個LED,所以不進行8bit移位,而是進行4bit循環移位。
ODR寄存器是IO口的輸出狀態控制寄存器,置一則端口高電平輸出,否則低電平輸出,由于我的LED是低有效(低電平點亮),所以需要對數據進行取反,然后將流水燈狀態寫入ODR寄存器同步到硬件IO使IO完成對應的狀態設置。
而OS_ThreadDelay函數則是操作系統提供的系統函數,它的功能是完成延時,函數的入參是延時的時間,單位為毫秒,示例代碼中寫的是1000,也就是1秒(1000ms),流水燈的狀態每秒刷新一次。需要注意的是OS_ThreadDelay函數是一個系統函數,內部的實現方式復雜,它并不占用定時器資源也不是CPU計數進行延時,在本線程延時的同時其他的線程還是可以繼續運行。
最后在線程主函數的最后是線程退出函數
3.png (514 Bytes, 下載次數: 48)
下載附件
2021-9-14 18:14 上傳
,此函數需要再次說明,只有在一個線程執行完成需要退出的時候才調用這個函數來釋放線程資源,不是說任意一個函數中都需要調用這個函數,僅適用于每個線程的主函數(入口函數)。另外在本階段暫時還不涉及多線程編程,所以大家并不需要太過于注意這個函數,只是暫時有這么個概念即可,目前的階段大家不需要在自己編寫的函數中調用。
題外話:有關于線程、多任務和進程還請大家自行百度,本帖中就不做說明了,百度說得還是比較客觀和清楚的。
|