Try   HackMD

[W11] [STM32] I/O & interupt

(零) IDE & board

STM32 board:NUCLEO-F207ZG
https://hackmd.io/uJrNrB3rTgKHdyLhTJY74Q

online IDE操作、ST-Link驅動安裝、Tera Term設置
https://hackmd.io/@Kirashi/SJR-2slKt

(一) Basic

Mbed API list

  • 在網路搜尋Mbed API,會找到網站
    https://os.mbed.com/docs/mbed-os/v6.15/apis/index.html
    通常開發函數庫(Library)或板子(Board)的開發者,會提供使用者API,讓使用者不需要了解函數的實作細節,只需要知道函數如何使用,以提高使用者的編程效率。

  • Mbed API 提供I/O、Serial等周邊設備的控制方法、函數的輸入輸出、函數使用範例等。


DigitalOut Class

  • API:https://os.mbed.com/docs/mbed-os/v6.15/apis/digitalout.html

  • DigitalOut (PinName pin)
    讓DigitalOut物件能與實際腳位連結,PinName參照Pinout圖。

  • write (int value)
    輸出高準位(1)或低準位(0)。

  • is_connected ()
    確認物件是否與實際腳位有連結了。

  • DigitalOut& operator= (int value)
    例如:testled = 1;
    其中testled是DigitalOut物件


Example 1-1

  • 實驗目標:使用DigitalOut使LED閃爍

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 使用 Member Function 方法,實現LED Blink
#include "mbed.h"

DigitalOut blinkled(LED1);

int main()
{
    // Blink LED
    while(1) {
        blinkled.write(1);
        wait(1);
        
        blinkled.write(0);
        wait(1);
    }
}
  • 使用operator方法,實現LED Blink
#include "mbed.h"

DigitalOut blinkled(LED1);

int main()
{
    // Blink LED
    while(1) {
        blinkled = !blinkled;
        wait(1);
    }
}

LAB 1-1

  • 實驗目標:以LED1~3實現單向跑馬燈

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


DigitalIn Class

  • API:https://os.mbed.com/docs/mbed-os/v6.15/apis/digitalin.html

  • DigitalIn (PinName pin)
    讓DigitalIn物件能與實際腳位連結,PinName參照Pinout圖。(設定數位輸入接腳用)

  • int read ()
    讀取pin電壓準位。回傳1或0。(高準位或低準位)。

  • is_connected ()
    確認物件是否與實際腳位有連結了。

  • mode(PinMode pull)
    設定輸入模式。pull={PullUp, PullDown, PullNone, OpenDrain}

  • operator int()
    An operator shorthand for read()

如果button是DigitalIn,led是DigitalOut,下列兩個敘述等價:

led = button;
led.write(button.read());


Example 2-1

  • 實驗目標:讀取USER_BUTTON,若開關被按下令LED1發光;開關放開則LED1不發光。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 使用memeber function方法
#include "mbed.h"

DigitalIn  button(USER_BUTTON); //the button on your board
DigitalOut led(LED1);

int main()
{
    // 檢查物件button是否完成pin連結
    if(button.is_connected()) {
        printf("button is connected and initialized! \n\r");
    }
    
    button.mode(PullNone); // 浮接
    
    while(1) {
        led.write(button.read()); // member function expression
        wait(0.25);
    }
}
  • 使用operator寫法
#include "mbed.h"

DigitalIn  button(USER_BUTTON); //the button on your board
DigitalOut led(LED1);

int main()
{    
    button.mode(PullNone); // 浮接
    
    while(1) {
        led = button; // operator expression
        wait(0.25);
    }
}

LAB 2-1

  • 實驗目標:承LAB1-1之跑馬燈,在USER_BUTTON被按下時停止,放開時往反方向運行跑馬燈

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Serial Class

  • API:https://os.mbed.com/docs/mbed-os/v5.15/apis/rawserial.html
  • Serial (PinName tx, PinName rx, int baud)
    建構Serial物件,tx與rx填上有支援UART的pin腳位代號,baud預設為9600。
  • baud (int baudrate)
    如果沒有在建構式上設定鮑率,可以使用member function設定。
  • printf(char* string)
    向螢幕輸出字串
  • putc(int c)
    tx端輸出
  • getc(int c)
    rx端接受字元

Tera Term設定

  1. Setup -> Serial Port
  2. Port : 選擇連接Mbed的port
  3. Speed : 鮑率選擇9600
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

Example 3-1

  • 實驗目標:通過Tera Term,將鍵盤每次輸入的字元顯示到螢幕上

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

#include "mbed.h"
 
RawSerial pc(USBTX, USBRX); // tx, rx
 
int main() {
    pc.printf("Hello World!\n\r");
    while(1) {
        pc.putc(pc.getc()); // echo input back to terminal
    }
}

LAB3-1

  • 實驗目標:通過Tera Term,完成下列目標
  1. 輸入'G'切換LED1狀態
  2. 輸入'B'切換LED2狀態
  3. 輸入'R'切換LED3狀態
  4. 輸入'1'切換所有LED狀態
  5. 輸入錯誤會顯示錯誤訊息

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Bonus 1

  • 實驗目標:
  1. 一開始跑馬燈以G(LED1)、B(LED2)、R(LED3)、A(外接的LED)順序運行
  2. USER_BUTTON長按進入使用Tera Term輸入指令狀態
  3. 輸入RGBA的不同排列順序改變亮燈順序
  4. 按下Enter後回到跑馬燈狀態並依照先前指令之排列順序運行。
    註1:一開始跑馬燈順序GBRA。
    註2:要能偵測input錯誤並告知使用者。
    註3:可以參考使用如下面提示之物件導向寫法。也歡迎使用其他方法d(`・∀・)b

※有字幕

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Hint:
※以下為Pointer物件導向宣告方式

#include "mbed.h"
/////Variable Declaration/////

DigitalOut *output;
DigitalOut *X[1];

int main(){
    output = new DigitalOut(LED1);
    X[0] = output;
    
    while(1){
        *X[0] = !*X[0];
        wait(0.5);
    }
}


Timer Class

  • API:https://os.mbed.com/docs/mbed-os/v5.15/apis/timer.html

  • start():開始計時。

  • stop():停止計時。

  • reset():重新計時。

  • read():讀取時間,浮點數型態輸出,單位為秒。

  • read_ms():讀取時間,整數型態輸出,單位為毫秒。


Example 4-1

實驗目標:利用Timer計時,並輸出時間到Tera Term

#include "mbed.h"

Timer timer;
float t1;
int t2;

int main()
{    
    timer.start(); // 計時開始
    
    while(1) {
        t1 = timer.read();  // 讀取時間 浮點表示
        t2 = timer.read_ms(); // 讀取時間 整數表示
        
        printf("%f seconds \r\n",t1);
        printf("%d miliseconds \r\n",t2);
        printf("\r\n");
        
        if(t2 > 10000)
            timer.stop(); //計時停止
        
        wait(0.5);          
    }
}

LAB 4-1

實驗目標:使用Timer,消除USER_BUTTON的彈跳現象,然後記錄BUTTON被按下的次數,在USER_BUTTON被按下時輸出次數到Tera Term。(當按鈕被按著不放時,只算一次)

Hint: 使用timer時間差決定按下和放開的情況

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


(二) 中斷(Interrupt)

Interrupt Class

除了能觸發中斷的Timer外,Mbed也提供了另外三種Interupt Class API,給開發者利用。


Example 5-1

實驗目標:使用InterruptIn,實現USER_BUTTON被按下時,切換LED1狀態(亮/不亮),而LED3保持閃爍

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

#include "mbed.h"
 
InterruptIn button(USER_BUTTON);
DigitalOut led(LED1);
DigitalOut blinkled(LED3);
 
void change() {
    led = !led;
}
 
int main() {
    button.rise(&change);  // 上緣觸發執行flip()
    
    // LED3 每2秒亮暗一次
    while(1) {
        blinkled = !blinkled;
        wait(1);
    }
}

Example 5-2

實驗目標:使用Ticker,實現兩個不同頻率的LED Blinking

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

#include "mbed.h"
 
Ticker tick[2];
DigitalOut blinkled[2] = {LED1, LED3};

void change0() {
    blinkled[0] = !blinkled[0];
}

void change1() {
    blinkled[1] = !blinkled[1];
}
 
int main() {
    tick[0].attach(&change0,0.5);
    tick[1].attach(&change1,0.8);
    while(1){ }
}

LAB 5-1

實驗目標:一開始LED1閃爍,使用Timeout 5秒後轉為閃爍LED2。

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


LAB 5-2

實驗目標:實現呼吸燈

  1. 亮暗週期:
    • 由亮至暗 : 2s
    • 由暗至亮 : 2s

Tips:AnalogOut API、Pinout中尋找支援AnalogOut的Pin

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Bonus 2

實驗目標:完成一個簡易碼表。並實現以下目標:

  1. 使用七段顯示器顯示秒數,並且精準到小數2位,並且遵守接下來例如的顯示方式。例如:2.31秒,則顯示[ ][2.][3][1]而不是[0][2.][3][1];0.02秒,則顯示[ ][0.][0][2]。
  2. 碼表初始狀態為停止。並且顯示[ ][0.][0][0]。
  3. 短按開關,則切換碼表狀態(停止/開始)。
  4. 長按開關,則碼表時間歸零。
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →


課後問題:

  • 列出一表簡單表示STM32 NUCLEO-F207ZG與Arduino Uno的規格差異。(例如:震盪器頻率、Pin腳數、Flash memory大小)
  • 簡述Mbed項目的創立目的與可能造成的影響
  • 什麼是API