Rath-HAL - USART 串口输出

器材

  • 1x Tequila Nano + RA_LINK 调试器

电路连接

不需要进行额外连线

原理

USART 是一种常见的通讯模式。我们使用的 RA-LINK 中自带一个电脑 USB 至 USART 串口的转换器。因此,我们只需要在 Tequila Nano 上设置好串口参数并启用对应的针脚即可实现和电脑的通讯连接。

我们设置串口的波特率为 115200,即串口速率为 115200 bit/s,并且启用与 RA-LINK 相连的 PA9 和 PA10 针脚作为串口输出针脚。这样,在程序中我们就可以使用 printf 来向串口输出数据。

在电脑上,我们可以用 VS Code Pio 自带的串口监视器,或其他串口通讯软件,来接收并显示 Tequila Nano 输出的数据。

需要注意的是,因为某些未知 Bug,当 printf 不带格式化参数,只提供第一个字符串参数的时候 (如 printf("字符串\n");),结果不会正确地输出换行。所以,当只需输出纯字符串,不需要格式化参数的时候,建议使用 printf("字符串\n", 0); 的形式,即可正确输出换行符。

代码

/**
 * @file main.c
 * @version 1.0
 * @date 2021-07-27
 * 
 */

#include "rath_hal.h"

static void AG_RCU_init(void);
static void AG_GPIO_init(void);
static void AG_USART0_init(void);

int main(void) {
  AG_RCU_init();
  AG_GPIO_init();
  AG_USART0_init();

  uint32_t counter = 0;

  while (1) {
    /* print some text and the counter value */
    printf("hello world: %lu\n", counter);

    counter += 1;

    /* delay for 0.1 second */
    HAL_delay(100);
  }
}

static void AG_RCU_init(void) {
  HAL_RCU_resetPeriphClock(RCU_GPIOA);
  HAL_RCU_resetPeriphClock(RCU_USART0);

  HAL_RCU_enablePeriphClock(RCU_GPIOA);
  HAL_RCU_enablePeriphClock(RCU_USART0);
}

static void AG_GPIO_init(void) {
  GPIO_InitTypeDef GPIO_init;
  
  GPIO_init.pin = GPIO_PIN_9;
  GPIO_init.mode = GPIO_MODE_AF_PP;
  GPIO_init.speed = GPIO_SPEED_50MHZ;
  GPIO_init.pull = GPIO_PULL_NONE;
  HAL_GPIO_init(GPIOA, &GPIO_init);
  
  GPIO_init.pin = GPIO_PIN_10;
  GPIO_init.mode = GPIO_MODE_INPUT;
  GPIO_init.speed = GPIO_SPEED_NONE;
  GPIO_init.pull = GPIO_PULL_NONE;
  HAL_GPIO_init(GPIOA, &GPIO_init);
}

static void AG_USART0_init(void) {
  HAL_USART_disable(USART0);
  
  USART_InitTypeDef USART0_init;

  USART0_init.mode = USART_MODE_TX_RX;
  USART0_init.baudrate = 115200UL;
  USART0_init.word_length = USART_WORDLENGTH_8BIT;
  USART0_init.stop_bits = USART_STOPBITS_1BIT;
  USART0_init.parity = USART_PARITY_NONE;
  USART0_init.hw_control = USART_HWCONTROL_NONE;
  HAL_USART_init(USART0, &USART0_init);

  HAL_USART_enable(USART0);
}

#include "gd32vf103.h"
#include 

void init_uart0(void) {    
  /* enable GPIO clock */
  rcu_periph_clock_enable(RCU_GPIOA);
  /* enable USART clock */
  rcu_periph_clock_enable(RCU_USART0);

  /* connect port to USARTx_Tx */
  gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
  /* connect port to USARTx_Rx */
  gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

  /* USART configure */
  usart_deinit(USART0);
  usart_baudrate_set(USART0, 115200U);
  usart_word_length_set(USART0, USART_WL_8BIT);
  usart_stop_bit_set(USART0, USART_STB_1BIT);
  usart_parity_config(USART0, USART_PM_NONE);
  usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
  usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
  usart_receive_config(USART0, USART_RECEIVE_ENABLE);
  usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
  usart_enable(USART0);

  usart_interrupt_enable(USART0, USART_INT_RBNE);
}

// retarget the C library printf function to USART0
int _put_char(int ch) {
     usart_data_transmit(USART0, (uint8_t) ch );
     while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET){
     }
     return ch;
}

/**
 * delay a time in milliseconds.
 * 
 * @param t time to wait, in milliseconds
 */
void delay(uint32_t t) {
  // Don't start measuruing until we see an mtime tick
  uint64_t tmp = get_timer_value();
  uint64_t start_mtime = get_timer_value();
  while (start_mtime == tmp) {
    start_mtime = get_timer_value();
  } 

  uint64_t delta_mtime = get_timer_value() - start_mtime;
  while(delta_mtime < (SystemCoreClock / 4000.0 * t )) {
    delta_mtime = get_timer_value() - start_mtime;
  }
}


/**
 * main function
 */
int main(void) {
  init_uart0();

  while(1) {
    printf("Hello World\r\n");
    delay(100);
  }
}

你可能感兴趣的:(Rath-HAL - USART 串口输出)