找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4383|回復(fù): 3
收起左側(cè)

Myos環(huán)境STM8開發(fā)持續(xù)更新帖

[復(fù)制鏈接]
ID:229155 發(fā)表于 2018-1-26 22:27 | 顯示全部樓層 |閱讀模式
    一直以來都想為Myos操作系統(tǒng)寫一個開發(fā)者的入門帖,然而因?yàn)楦鞣N各樣的原因,拖延到現(xiàn)在才開始編寫。
    在這之前也嘗試過很多種其他的方式,比如編寫使用手冊、編寫例程、直播開發(fā)過程等等,后來都發(fā)現(xiàn)效果不好,還是有很多想要使用Myos的朋友無法真正熟練的使用。

    在這之前我曾經(jīng)還想錄制一個類似于現(xiàn)在某一個寶上銷售的開發(fā)板的新手入門視頻,還沒動手呢,自己都覺得肯定沒什么效果,琢磨來琢磨去決定發(fā)一個持續(xù)更新的帖子,盡量的堅(jiān)持快速更新,講解STM8、編程技巧、經(jīng)驗(yàn)規(guī)范以及操作系統(tǒng)提供的功能等等。
    然而寫帖子或者博客總得有一個話題,總不能我想到什么就給大家寫什么,那樣太亂了,也沒有太多的營養(yǎng)。所以我決定走一個和現(xiàn)在賣開發(fā)板不同的路線,不再把各種例程分開寫,而是按照實(shí)際的項(xiàng)目流程來,做一個相對于STM8來說非常復(fù)雜的項(xiàng)目,以此來給大家展示STM8和Myos操作系統(tǒng)。想了很久不知道到底做什么,然而就在上幾天調(diào)試電路板,再想起以前調(diào)試電路板的經(jīng)歷,我決定寫一個多功能的示波器,沒錯!就是用STM8寫一個示波器!
    由于本帖是持續(xù)更新帖,所以在本段我會做一些說明:
      1.本帖中的軟件環(huán)境是IAR For STM8,下位機(jī)的操作系統(tǒng)是Myos操作系統(tǒng)。
      2.本帖中的硬件環(huán)境是STM8S007C8、12864點(diǎn)陣屏、4M字節(jié)Flash以及矩陣按鍵等等常備的小玩意。
      3.本帖是持續(xù)更新帖,大家盡可能的私信我,給我發(fā)小紙條免得中途插樓太多影響大家閱讀體驗(yàn)。
      4.本帖中所用到的硬件原理圖和Myos操作系統(tǒng)環(huán)境我會以附件的方式上傳到帖子上,大家都可以自由下載。
    以下均為技術(shù)干貨帖。

Myos_Private_2_4_9.7z

2.53 MB, 下載次數(shù): 27, 下載積分: 黑幣 -5

開發(fā)板電路.pdf

83.33 KB, 下載次數(shù): 15, 下載積分: 黑幣 -5

STM8S系列參考手冊.pdf

4.6 MB, 下載次數(shù): 16, 下載積分: 黑幣 -5

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:229155 發(fā)表于 2018-1-26 22:56 | 顯示全部樓層
    既然是新手帖,寫給新手們的入門帖,那自然要從最簡單最基礎(chǔ)的做起。
    學(xué)軟件開發(fā)的入門實(shí)驗(yàn)可能是“hello world”也可能是“hello c”可能大家發(fā)揮想象,不一定是一樣的,但是學(xué)單片機(jī)一定都是一樣的,大家拿到單片機(jī)的第一個入門實(shí)驗(yàn)一定是:流水燈!
    話不多說,先截圖上代碼(貼在帖子中太小了,我弄到附件里面去了,大家將就看,嫌棄小的移步去附件),然后再講解。
    4.png

    首先,需要熟悉一下Myos的系統(tǒng)環(huán)境,左側(cè)為系統(tǒng)的文件目錄,具體如下:
    1.png
    最前面的帶Application前綴的應(yīng)用程序文件夾,帶device的是STM8的驅(qū)動文件夾,帶Myos前綴的是系統(tǒng)核心文件夾,而Myos系統(tǒng)的主函數(shù)雖然也是從main函數(shù)開始運(yùn)行,但是由于運(yùn)行了Myos操作系統(tǒng),所以不再使用main函數(shù)作為入口函數(shù),而是以osdemo.c文件中的OS_ApplicationMainThread函數(shù)作為入口函數(shù),翻譯過來即為“應(yīng)用程序主線程”。長這樣:
6.png

    然后我們的代碼寫在這個函數(shù)內(nèi),由于這個函數(shù)是一個獨(dú)立的線程,所以在函數(shù)的最后一定要記得添加OS_ThreadExit函數(shù)來執(zhí)行線程銷毀工作,否則函數(shù)退出時則會返回到一個未知的狀態(tài),也就是程序跑飛,但是需要注意的是只有在線程需要退出的時候才能調(diào)用這個函數(shù),在任意一個用戶線程中,只要調(diào)用了OS_ThreadExit函數(shù)則必然會導(dǎo)致當(dāng)前的線程被銷毀。
    OK,開始講解代碼:
    首先,我們定義一個regist變量來保存一下流水燈的狀態(tài),這個和51的流水燈實(shí)現(xiàn)還是略有區(qū)別的,需要注意的是STM8、Cortex M系列的微控制器并不支持對IO口的位操作,每次操作至少是以字節(jié)(8位)訪問方式進(jìn)行訪問。
    接下來如下三行代碼:
    2.png
    我所使用的開發(fā)板上的四個LED燈是連接在PC1-PC4上的,所以需要設(shè)置一下PC口,首先看DDR寄存器,DDR寄存器是控制IO的數(shù)據(jù)方向的,輸入還是輸出由這個寄存器控制。而CR1在輸出模式下是控制IO的輸出類型,開漏(無法輸出高電平)輸出還是推挽輸出。CR2則是輸出模式下的IO翻轉(zhuǎn)速度,置高為10MHZ。
    具體的寄存器說明可以參考上傳的STM8S參考手冊GPIO章節(jié)。
    5.png
    循環(huán)體代碼如上,首先我們的流水燈是一個死循環(huán),一直執(zhí)行流水燈操作,對于regist的操作就是流水燈的發(fā)生過程,由于我只有4個LED,所以不進(jìn)行8bit移位,而是進(jìn)行4bit循環(huán)移位。
    ODR寄存器是IO口的輸出狀態(tài)控制寄存器,置一則端口高電平輸出,否則低電平輸出,由于我的LED是低有效(低電平點(diǎn)亮),所以需要對數(shù)據(jù)進(jìn)行取反,然后將流水燈狀態(tài)寫入ODR寄存器同步到硬件IO使IO完成對應(yīng)的狀態(tài)設(shè)置。
    而OS_ThreadDelay函數(shù)則是操作系統(tǒng)提供的系統(tǒng)函數(shù),它的功能是完成延時,函數(shù)的入?yún)⑹茄訒r的時間,單位為毫秒,示例代碼中寫的是1000,也就是1秒(1000ms),流水燈的狀態(tài)每秒刷新一次。需要注意的是OS_ThreadDelay函數(shù)是一個系統(tǒng)函數(shù),內(nèi)部的實(shí)現(xiàn)方式復(fù)雜,它并不占用定時器資源也不是CPU計(jì)數(shù)進(jìn)行延時,在本線程延時的同時其他的線程還是可以繼續(xù)運(yùn)行。
    最后在線程主函數(shù)的最后是線程退出函數(shù) 3.png ,此函數(shù)需要再次說明,只有在一個線程執(zhí)行完成需要退出的時候才調(diào)用這個函數(shù)來釋放線程資源,不是說任意一個函數(shù)中都需要調(diào)用這個函數(shù),僅適用于每個線程的主函數(shù)(入口函數(shù))。另外在本階段暫時還不涉及多線程編程,所以大家并不需要太過于注意這個函數(shù),只是暫時有這么個概念即可,目前的階段大家不需要在自己編寫的函數(shù)中調(diào)用。
    題外話:有關(guān)于線程、多任務(wù)和進(jìn)程還請大家自行百度,本帖中就不做說明了,百度說得還是比較客觀和清楚的。

回復(fù)

使用道具 舉報(bào)

ID:229155 發(fā)表于 2018-1-27 23:21 | 顯示全部樓層
昨天寫了一下STM8環(huán)境下GPIO的流水燈操作說明以及操作系統(tǒng)的OS_ThreadDelay延時函數(shù),然而流水燈只是最基本的一個小實(shí)驗(yàn),并沒有太大的實(shí)用價(jià)值,所以今天的帖子是GPIO操作的升級版,也是操作系統(tǒng)環(huán)境下的"管理組件"的驅(qū)動開發(fā)示例帖,今天的帖子是示范一下系統(tǒng)環(huán)境下的矩陣鍵盤驅(qū)動編寫以及在STM8環(huán)境下的實(shí)現(xiàn)。
在Myos操作系統(tǒng)環(huán)境下的按鍵驅(qū)動接口原型有三個,代碼如下:
  1. /*********************************************************************系統(tǒng)按鍵管理驅(qū)動函數(shù)*********************************************************************/
  2. /*
  3. *函數(shù)名:MCU_ButtonIOInit( void )
  4. *入?yún)ⅲ簾o
  5. *返回值:無
  6. *作用域:本地
  7. *線程訪問:回調(diào)
  8. *函數(shù)作用:初始化系統(tǒng)硬件成為可使用的按鍵輸入
  9. */
  10. void MCU_ButtonIOInit( void )
  11. {
  12. }

  13. /*
  14. *函數(shù)名:MCU_GetButtonvallower( void )
  15. *入?yún)ⅲ簾o
  16. *返回值:按下的按鍵狀態(tài)
  17. *作用域:本地
  18. *線程訪問:回調(diào)
  19. *函數(shù)作用:獲取當(dāng)前鍵盤中被按下的按鍵低32位
  20. */
  21. unsigned int32 MCU_GetButtonvallower( void )
  22. {
  23.   return 0x00;
  24. }

  25. /*
  26. *函數(shù)名:MCU_GetButtonvalhigh( void )
  27. *入?yún)ⅲ簾o
  28. *返回值:按下的按鍵狀態(tài)
  29. *作用域:本地
  30. *線程訪問:回調(diào)
  31. *函數(shù)作用:獲取當(dāng)前鍵盤中被按下的按鍵高32位
  32. */
  33. unsigned int32 MCU_GetButtonvalhigh( void )
  34. {
  35.   return 0x00;
  36. }
復(fù)制代碼
這三個驅(qū)動接口原型函數(shù)位于Myos_driver文件夾下的myosmanagedriver.c文件中,系統(tǒng)會在組件初始化階段調(diào)用
MCU_ButtonIOInit函數(shù)來執(zhí)行按鍵的輸入輸出口屬性初始化工作,而在需要進(jìn)行按鍵檢測的時候通過調(diào)用MCU_GetButtonvallower和MCU_GetButtonvalhigh函數(shù)來獲取最大64個按鍵的狀態(tài),并在系統(tǒng)內(nèi)部進(jìn)行處理,對按鍵進(jìn)行單擊、長按檢測,并提供一系列的接口來使能或禁能按鍵的連續(xù)輸出,具體的功能會在后續(xù)的帖子中一一說明。
我所使用的開發(fā)板上有一個2x3的矩陣鍵盤,共計(jì)6個按鍵,一般情況下入門單片機(jī)的時候大家接觸的按鍵一般都是獨(dú)立按鍵,也就是每個IO接一個按鍵,通過IO的狀態(tài)來判定按鍵的按下或抬起狀態(tài),而在實(shí)際的項(xiàng)目中大多使用的是矩陣鍵盤。
矩陣鍵盤的原理實(shí)際上是分而治之,舉個例子,大家上小學(xué)的時候舉手,一個教室有很多行有很多列的學(xué)生,有的學(xué)生舉手而有的學(xué)生不一定舉手,而老師看的時候也不是同時看的,一般都是先看第一行,然后再看第二行、第三行,以此類推。矩陣鍵盤也是一樣的原理,一行按鍵一行按鍵的檢測。
話不多說,根據(jù)我手里開發(fā)板的原理進(jìn)行驅(qū)動的編寫,上傳的文件中所有的文件均為只讀文件,請大家找到對應(yīng)的文件路徑然后解除只讀屬性后進(jìn)行修改,編寫后的代碼如下:
  1. /*********************************************************************系統(tǒng)按鍵管理驅(qū)動函數(shù)*********************************************************************/
  2. /*
  3. *函數(shù)名:MCU_ButtonIOInit( void )
  4. *入?yún)ⅲ簾o
  5. *返回值:無
  6. *作用域:本地
  7. *線程訪問:回調(diào)
  8. *函數(shù)作用:初始化系統(tǒng)硬件成為可使用的按鍵輸入
  9. */
  10. void MCU_ButtonIOInit( void )
  11. {
  12.   GPIOD->DDR &= ~0x1C;                                                          //設(shè)置PD2-PD4為輸入
  13.   GPIOD->CR1 |=  0x1C;                                                          //設(shè)置PD2-PD4為上拉
  14.   GPIOD->CR2 &= ~0x1C;                                                          //設(shè)置PD2-PD4不中斷

  15.   GPIOA->DDR |= 0x06;                                                           //設(shè)置PA1-PA2為輸出
  16.   GPIOA->CR1 &= ~0x06;                                                          //設(shè)置PA1-PA2為開漏
  17.   GPIOA->CR2 |= 0x06;                                                           //設(shè)置PA1-PA2為10MHZ
  18. }

  19. /*
  20. *函數(shù)名:MCU_GetButtonvallower( void )
  21. *入?yún)ⅲ簾o
  22. *返回值:按下的按鍵狀態(tài)
  23. *作用域:本地
  24. *線程訪問:回調(diào)
  25. *函數(shù)作用:獲取當(dāng)前鍵盤中被按下的按鍵低32位
  26. */
  27. unsigned int32 MCU_GetButtonvallower( void )
  28. {
  29.   unsigned dshort16 regist;                                                      //寄存變量

  30.   GPIOA->ODR |= 0x06;                                                           //設(shè)置PA1-PA2為高電平
  31.   GPIOA->ODR &= ~0x04;                                                          //設(shè)置PA2位低電平,準(zhǔn)備掃描第二行

  32.   OS_Delay(0x02);                                                               //等待IO穩(wěn)定
  33.   regist = GPIOD->IDR;                                                          //獲取第二行的狀態(tài)
  34.   GPIOA->ODR |= 0x06;                                                           //設(shè)置PA1-PA2為高電平
  35.   GPIOA->ODR &= ~0x02;                                                          //設(shè)置PA1位低電平,準(zhǔn)備掃描第一行

  36.   regist >>= 0x02;                                                              //進(jìn)行按鍵處理同時等待IO穩(wěn)定
  37.   regist <<= 0x03;                                                              //進(jìn)行按鍵處理同時等待IO穩(wěn)定
  38.   regist |= 0xFFC0;                                                             //進(jìn)行按鍵處理同時等待IO穩(wěn)定
  39.   regist |= ((GPIOD->IDR) >> 0x02);                                             //獲取第一行的狀態(tài)
  40.   regist = ~regist;                                                             //低電平有效轉(zhuǎn)高位有效

  41.   return regist;                                                                //返回按鍵狀態(tài)
  42. }

  43. /*
  44. *函數(shù)名:MCU_GetButtonvalhigh( void )
  45. *入?yún)ⅲ簾o
  46. *返回值:按下的按鍵狀態(tài)
  47. *作用域:本地
  48. *線程訪問:回調(diào)
  49. *函數(shù)作用:獲取當(dāng)前鍵盤中被按下的按鍵高32位
  50. */
  51. unsigned int32 MCU_GetButtonvalhigh( void )
  52. {
  53.   return 0x00;
  54. }
復(fù)制代碼
MCU_ButtonIOInit函數(shù)中對狀態(tài)線PD2-PD4初始化為上拉輸入,且不開啟中斷功能,那么這三個IO就相當(dāng)于是一個高阻輸入的IO再加一個上拉電阻,用來捕獲按鍵的按下狀態(tài),而對掃描線PA1-PA2初始化為開漏輸出,之所以設(shè)置為開漏輸出是為了保證沒有高電平輸出,高電平由輸入口的上拉電阻提供而不是由單片機(jī)的推挽輸出提供,因?yàn)槿绻存I有時候會多個按鍵同時按下,一但PA1和PA2直接導(dǎo)通則會燒毀IO口,開漏輸出由于沒有高電平(扇出電流)輸出所以不會導(dǎo)致IO的燒毀。另外我的板子上只有6個按鍵,所以沒有必要使用高32位的驅(qū)動函數(shù),只需要使用低32位的驅(qū)動函數(shù)來捕獲按鍵狀態(tài)既可。
MCU_GetButtonvallower函數(shù)里包含了矩陣按鍵的掃描方法,首先將置低PA2掃描第二行,因?yàn)槲覀儾捎玫氖亲笠频姆绞絹硖幚恚葤呙璧陌存I值會更大,第一次掃描需要進(jìn)行一些延時來等待IO狀態(tài)穩(wěn)定,OS_Delay這個函數(shù)也是一個系統(tǒng)函數(shù),但是這個函數(shù)只是粗略延時,延時時長為:(參數(shù)*3)個時鐘周期。而在第二次掃描的時候就可以進(jìn)行regist變量的處理來模擬延時,同時也可以先進(jìn)行一部分的處理工作,提高驅(qū)動的效率。當(dāng)驅(qū)動寫完后,則按鍵的鍵值編碼如下:第一行(PA1)的第一個(PD2)為1、第二個(PD3)為2、第三個(PD3)為3;第二行第一個
(PD2)為4、第二個(PD3)為5、第三個(PD3)為6。
當(dāng)需要進(jìn)行按鍵檢測的時候調(diào)用函數(shù)OS_GetKey或OS_GetChar即可獲取到當(dāng)前的按鍵狀態(tài),該函數(shù)的函數(shù)原型為:

  1. /*
  2. *函數(shù)名:OS_GetKey( void )
  3. *入?yún)ⅲ簾o
  4. *返回值:當(dāng)前按下的鍵值
  5. *作用域:本地
  6. *線程訪問:安全
  7. *函數(shù)作用:獲取當(dāng)前鍵盤的鍵值,該函數(shù)不會阻塞線程,如沒有按鍵按下則返回0,如為長按則最高位為1
  8. */
  9. unsigned char8 OS_GetKey( void );

  10. /*
  11. *函數(shù)名:OS_GetChar( void )
  12. *入?yún)ⅲ簾o
  13. *返回值:獲取當(dāng)前按下的按鍵
  14. *作用域:本地
  15. *線程訪問:安全
  16. *函數(shù)作用:獲取當(dāng)前的按鍵情況,該函數(shù)會阻塞線程,如果是長按則返回值的最高位為1
  17. */
  18. unsigned char8 OS_GetChar( void );
復(fù)制代碼
上述兩個函數(shù)均可獲取按鍵的按鍵值,不同之處在于OS_GetKey不會阻塞當(dāng)前的線程,如果沒有按鍵按下則返回0,而
OS_GetChar會阻塞線程,如果沒有按鍵按下則一直在本函數(shù)中等待,直到按鍵按下為止,而如果發(fā)生了長按則兩個函數(shù)返回值的最高位(位7)均為1,低7位則是鍵值,鍵值對應(yīng)關(guān)系為1~32為MCU_GetButtonvallower驅(qū)動函數(shù)返回值的0~31位,而33~64為MCU_GetButtonvalhigh驅(qū)動函數(shù)返回值的0~31位。
我在例程中使用的函數(shù)為
OS_GetKey來獲取按鍵值,并且根據(jù)按鍵的值改變流水燈的移動速度,代碼如下:
  1. #include "myos.h"
  2. #include "osdemo.h"



  3. /*
  4. *函數(shù)名:OS_ApplicationMainThread(void *arg)
  5. *入?yún)ⅲ?br />
  6.   arg:線程運(yùn)行參數(shù)
  7. *返回值:無
  8. *作用域:本地
  9. *線程訪問:安全
  10. *函數(shù)作用:應(yīng)用程序主線程
  11. */
  12. void OS_ApplicationMainThread(void *arg)
  13. {
  14.   unsigned char8 key = 0x00;                                                    //按鍵寄存
  15.   unsigned char8 regist = 0x00;                                                 //寄存變量
  16.   unsigned short16 delay = 1000;                                                //延時寄存

  17.   GPIOC->DDR = 0x1E;                                                            //設(shè)置PC1-PC4為輸出模式
  18.   GPIOC->CR1 = 0x1E;                                                            //設(shè)置PC1-PC4為推挽輸出
  19.   GPIOC->CR2 = 0x1E;                                                            //設(shè)置PC1-PC4位10MHZ輸出

  20.   while(true){
  21.     regist &= 0x0F;                                                             //只取4位有效位
  22.     regist = (regist == 0x00) ? 0x01 : (regist << 0x01);                        //流水燈移動及越界判定

  23.     GPIOC->ODR = (~regist << 0x01);                                             //LED燈點(diǎn)亮賦值

  24.     key = OS_GetKey();                                                          //獲取鍵值
  25.     if(key > 0x00){                                                             //有按鍵按下
  26.       delay = key & 0x7F;                                                       //去除長按標(biāo)識
  27.       delay *= 200;                                                             //計(jì)算延時時間
  28.     }

  29.     OS_ThreadDelay(delay);                                                      //系統(tǒng)提供的延時函數(shù)
  30.   }

  31.   OS_ThreadExit();                                                              //線程結(jié)束退出
  32. }
復(fù)制代碼
OK,今天的帖子到此為止,下一個帖子的內(nèi)容是SPI(串行外設(shè)接口)的科普帖。


按鍵驅(qū)動接口

按鍵驅(qū)動接口
回復(fù)

使用道具 舉報(bào)

ID:229155 發(fā)表于 2022-9-29 19:25 | 顯示全部樓層
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表