久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4324|回復: 3
打印 上一主題 下一主題
收起左側

Myos環境STM8開發持續更新帖

[復制鏈接]
跳轉到指定樓層
樓主
ID:229155 發表于 2018-1-26 22:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    一直以來都想為Myos操作系統寫一個開發者的入門帖,然而因為各種各樣的原因,拖延到現在才開始編寫。
    在這之前也嘗試過很多種其他的方式,比如編寫使用手冊、編寫例程、直播開發過程等等,后來都發現效果不好,還是有很多想要使用Myos的朋友無法真正熟練的使用。

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

Myos_Private_2_4_9.7z

2.53 MB, 下載次數: 27, 下載積分: 黑幣 -5

開發板電路.pdf

83.33 KB, 下載次數: 15, 下載積分: 黑幣 -5

STM8S系列參考手冊.pdf

4.6 MB, 下載次數: 16, 下載積分: 黑幣 -5

評分

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

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復

使用道具 舉報

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

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


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

回復

使用道具 舉報

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

  13. /*
  14. *函數名:MCU_GetButtonvallower( void )
  15. *入參:無
  16. *返回值:按下的按鍵狀態
  17. *作用域:本地
  18. *線程訪問:回調
  19. *函數作用:獲取當前鍵盤中被按下的按鍵低32位
  20. */
  21. unsigned int32 MCU_GetButtonvallower( void )
  22. {
  23.   return 0x00;
  24. }

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

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

  19. /*
  20. *函數名:MCU_GetButtonvallower( void )
  21. *入參:無
  22. *返回值:按下的按鍵狀態
  23. *作用域:本地
  24. *線程訪問:回調
  25. *函數作用:獲取當前鍵盤中被按下的按鍵低32位
  26. */
  27. unsigned int32 MCU_GetButtonvallower( void )
  28. {
  29.   unsigned dshort16 regist;                                                      //寄存變量

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

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

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

  41.   return regist;                                                                //返回按鍵狀態
  42. }

  43. /*
  44. *函數名:MCU_GetButtonvalhigh( void )
  45. *入參:無
  46. *返回值:按下的按鍵狀態
  47. *作用域:本地
  48. *線程訪問:回調
  49. *函數作用:獲取當前鍵盤中被按下的按鍵高32位
  50. */
  51. unsigned int32 MCU_GetButtonvalhigh( void )
  52. {
  53.   return 0x00;
  54. }
復制代碼
MCU_ButtonIOInit函數中對狀態線PD2-PD4初始化為上拉輸入,且不開啟中斷功能,那么這三個IO就相當于是一個高阻輸入的IO再加一個上拉電阻,用來捕獲按鍵的按下狀態,而對掃描線PA1-PA2初始化為開漏輸出,之所以設置為開漏輸出是為了保證沒有高電平輸出,高電平由輸入口的上拉電阻提供而不是由單片機的推挽輸出提供,因為如果按鍵有時候會多個按鍵同時按下,一但PA1和PA2直接導通則會燒毀IO口,開漏輸出由于沒有高電平(扇出電流)輸出所以不會導致IO的燒毀。另外我的板子上只有6個按鍵,所以沒有必要使用高32位的驅動函數,只需要使用低32位的驅動函數來捕獲按鍵狀態既可。
MCU_GetButtonvallower函數里包含了矩陣按鍵的掃描方法,首先將置低PA2掃描第二行,因為我們采用的是左移的方式來處理,先掃描的按鍵值會更大,第一次掃描需要進行一些延時來等待IO狀態穩定,OS_Delay這個函數也是一個系統函數,但是這個函數只是粗略延時,延時時長為:(參數*3)個時鐘周期。而在第二次掃描的時候就可以進行regist變量的處理來模擬延時,同時也可以先進行一部分的處理工作,提高驅動的效率。當驅動寫完后,則按鍵的鍵值編碼如下:第一行(PA1)的第一個(PD2)為1、第二個(PD3)為2、第三個(PD3)為3;第二行第一個
(PD2)為4、第二個(PD3)為5、第三個(PD3)為6。
當需要進行按鍵檢測的時候調用函數OS_GetKey或OS_GetChar即可獲取到當前的按鍵狀態,該函數的函數原型為:

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

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



  3. /*
  4. *函數名:OS_ApplicationMainThread(void *arg)
  5. *入參:
  6.   arg:線程運行參數
  7. *返回值:無
  8. *作用域:本地
  9. *線程訪問:安全
  10. *函數作用:應用程序主線程
  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;                                                            //設置PC1-PC4為輸出模式
  18.   GPIOC->CR1 = 0x1E;                                                            //設置PC1-PC4為推挽輸出
  19.   GPIOC->CR2 = 0x1E;                                                            //設置PC1-PC4位10MHZ輸出

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

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

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

  29.     OS_ThreadDelay(delay);                                                      //系統提供的延時函數
  30.   }

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


按鍵驅動接口.jpg (56.68 KB, 下載次數: 142)

按鍵驅動接口

按鍵驅動接口
回復

使用道具 舉報

地板
ID:229155 發表于 2022-9-29 19:25 | 只看該作者
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人欧美一区二区 | 日韩免费在线观看视频 | 国产一区999 | 欧美激情综合色综合啪啪五月 | 亚洲中午字幕 | 成人午夜影院 | 成年人黄色一级毛片 | 亚洲综合久久精品 | 日韩中文字幕网 | 亚洲精品国产第一综合99久久 | 国产免费一区二区三区网站免费 | 精品一区二区三区在线观看国产 | 久久久91| 91精品国产色综合久久 | 中文字幕久久久 | av在线免费观看网址 | 亚洲日韩中文字幕一区 | 国产精品久久久久久妇女 | 午夜成人在线视频 | 网站黄色在线 | 欧美精品三区 | 日韩欧美一区在线 | 国产区在线 | 欧美黄色免费网站 | 久久精品| 特黄特黄a级毛片免费专区 av网站免费在线观看 | 日本久久精品 | 黄色一级电影免费观看 | 俺去俺来也www色官网cms | 99av成人精品国语自产拍 | 我想看一级黄色毛片 | 日韩一区中文字幕 | av网站在线免费观看 | 久久国产免费看 | 亚洲国产网 | 91中文 | 毛片在线看看 | 久久久精品| 欧美日韩综合一区 | 国产成人综合在线 | 久久久久国产 |