Skip to content
This repository has been archived by the owner on Dec 17, 2021. It is now read-only.

STM32 #3 用UART方式輸出訊息

Shih En edited this page Apr 22, 2018 · 14 revisions

UART是MCU輸出與輸入字串訊息最通用的方法。UART是Universal Asynchronous Receiver/Transmitter的縮寫,即通用非同步收發傳輸器。此範例的目標是從STM32 MCU輸出"Hello world!"字串輸出,透過NUCLEO-STM32F103開發板上ST-Link Debugger的USB to UART功能,轉換成USB訊號,顯示在電腦終端機(terminal)上。

UART是以一定時脈的串行高低電位,8位元為一組,加上可能的start bit/stop bit/parity bit,代表一字元。 常見的UART速率有9600, 115200 baud等,baud即每秒幾位元(bits/s)。最常見的模式是8-N-1,即(8) data bits, no (N) parity bit, and one (1) stop bit。

更多詳細資訊可見成大資工Wiki -- UART

1. 了解NUCLEO-F103RB開發板上UART的電路連接配置

開發板上ST-Link Debugger的USB to UART是接到MCU的GPIO PA2的腳位,即USART2的TX(輸出)。這可以從STM32 Nucleo-64 boards User manual (UM1724)得知。在文件的第25頁寫著:

USART communication The USART2 interface available on PA2 and PA3 of the STM32 microcontroller can be connected to ST-LINK MCU, ST morpho connector or to Arduino connector.

又從p.38 Table.12 可得知其中PA2為USART TX(輸出),PA3為USART RX(輸入)。

2. 撰寫程式

建立兩個檔案,並放在同個資料夾底下,此資料夾與libopencm3又處於同路徑,如:

  • libopencm3
  • 02-usart
    • usart.c
    • Makefile

其檔案內容如下:

usart.c

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <stdio.h>
#include <errno.h>
int _write(int file, char *ptr, int len);

int main (void)
{
    /* Enable peripheral clocks. */
    rcc_periph_clock_enable(RCC_GPIOA);
    rcc_periph_clock_enable(RCC_USART2);

    /* Setup GPIO pin 2 on GPIO port A for transmit. */
    gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
                       GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2);

    /* Setup UART parameters. */
    usart_set_baudrate(USART2, 9600);
    usart_set_databits(USART2, 8);
    usart_set_parity(USART2, USART_PARITY_NONE);
    usart_set_stopbits(USART2, USART_STOPBITS_1);
    usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
    usart_set_mode(USART2, USART_MODE_TX);

    /* Finally enable the USART. */
    usart_enable(USART2);

    printf("Hello World!\r\n");

    while (1)
    {
    }

    return 0;
}

int _write(int file, char *ptr, int len)
{
    if (file == 1)
    {
        int i;
	for (i = 0; i < len; i++) usart_send_blocking(USART2, ptr[i]);
	return i;
    }
    errno = EIO;
    return -1;
}

寫成此程式主要需參考:

此程式所做的依序是:

  1. 令RCC(Reset & Clock Control)開啟GPIOA以及USART2的Clock。

  2. 設定GPIO PA2的模式為Alternate function Push-pull輸出,最高速度10MHz。(參考STM32F103xx Reference Manual p.170)

  3. 設定USART2模式為9600 8N1,TX,並開啟功能。(參考STM32F103xx Reference Manual 第27章)

  4. printf("Hello world!\r\n"); printf會呼叫_write這個函數輸出字元,_write再呼叫usart_send_blocking從USART2輸出。

Makefile

BINARY		:= usart
DEVICE 		:= STM32F103C4T6
OPENOCD_FILE 	:= board/st_nucleo_f103rb.cfg
OPENCM3_DIR 	:= ../libopencm3
OBJS	        += build/usart.o
include ../libopencm3.mk

Makefile設定我們的程式名稱,程式目標檔案,和目標的開發板型號,並引入libopencm3的Makefile自動化程式的編譯。

3. 顯示"Hello world!"

在Makefile路徑處開啟命令列,並執行

$ make

以編譯程式,

$ make flash

就可以上傳程式到MCU。

開啟Serial port檢視程式,(在Windows上 可使用 python-serial-monitor,或是RealTerm) 即可以看到"Hello world!"