ARM32开发——串口输出

🎬 秋野酱:《个人主页》

🔥 个人专栏:《Java专栏》《Python专栏》

⛺️心若有所向往,何惧道阻且长

文章目录

需求

串口循环输出内容到PC机。

串口数据发送

添加Usart功能。

首先,选中Firmware,鼠标右键,点击Manage Project Items

接着,将gd32f4xx_usart.c添加到依赖中

最后,观察Firmware

csharp 复制代码
static void USART_config() {
    /************** gpio config **************/
    // 配置时钟
    rcu_periph_clock_enable(RCU_GPIOA);
    // 配置模式
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_10);
    // 配置复用功能
    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);
    // 配置输出参数
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    /************** usart config **************/
    // 串口时钟
    rcu_periph_clock_enable(RCU_USART0);
    // USART复位
    usart_deinit(USART0);
    // 波特率
    usart_baudrate_set(USART0, 115200);
    // 校验位
    usart_parity_config(USART0, USART_PM_NONE);
    // 数据位数
    usart_word_length_set(USART0, USART_WL_8BIT);
    // 停止位
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    // 先发送高位还是低位
    usart_data_first_config(USART0, USART_MSBF_LSB);
    // 发送功能配置
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    // 使能串口
    usart_enable(USART0);
}
csharp 复制代码
//发送一byte数据
static void send_byte(uint8_t data) {
    //通过USART发送
    usart_data_transmit(USART0, data);
    //判断缓冲区是否已经空了
    //FlagStatus state = usart_flag_get(USART_NUM,USART_FLAG_TBE);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}
csharp 复制代码
// 发送多个byte数据
void send_data_array(uint8_t* data, uint32_t len) {
    while(data && len--) {
        send_byte(*data);
        data++;
    }
}
csharp 复制代码
//发送字符串
static void send_string(char *data){
	//满足: 1.data指针不为空  2.发送的数据不是\0结束标记
	while(data && *data){
		send_byte((uint8_t)(*data));
		data++;
	}
}

串口打印实现

csharp 复制代码
int fputc(int ch, FILE *f){
	send_byte((uint8_t)ch);
	return ch;
}

复用功能

串口为PA9和PA10,通过文档查询复用功能。

串口发送流程(了解)

寄存器与电路。

  1. 数据发送缓存寄存器
  2. 状态寄存器
    数据发送的流程,就是向发送缓冲区里放数据,这个发送缓存区寄存器只要有数据,就会触发电路,电路就按照这个数据模拟出高低电平往外发数据。
    发送缓存区寄存器有个特点:"小",只有一个byte,但是超快,寄存器在芯片内部寸土寸金。
    但是存在一个问题,如果发送大量数据,这个寄存器的数据还没发送完成,会覆盖掉,这时候有一个状态寄存器记录了当前发送缓冲去是否是闲置的。(GD32是USART_FLAG_TBE,STM32是UART_FLAG_TXE)

串口的标志位

关心的内容

将代码进行抽取

csharp 复制代码
static void USART_config() {
    uint32_t usartx_tx_rcu = RCU_GPIOA;
    uint32_t usartx_tx_port = GPIOA;
    uint32_t usartx_tx_pin = GPIO_PIN_9;
    uint32_t usartx_tx_af = GPIO_AF_7;

    uint32_t usartx_rx_rcu = RCU_GPIOA;
    uint32_t usartx_rx_port = GPIOA;
    uint32_t usartx_rx_pin = GPIO_PIN_10;
    uint32_t usartx_rx_af = GPIO_AF_7;

    uint32_t usartx = USART0;
    uint32_t usartx_rcu = RCU_USART0;

    uint32_t usartx_p_baudrate = 115200;
    uint32_t usartx_p_parity = USART_PM_NONE;
    uint32_t usartx_p_wl = USART_WL_8BIT;
    uint32_t usartx_p_stop_bit = USART_STB_1BIT;
    uint32_t usartx_p_data_first = USART_MSBF_LSB;

    /************** gpio config **************/
    // tx
    rcu_periph_clock_enable(usartx_tx_rcu);	// 配置时钟
    gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
    gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
    gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);
    // rx
    rcu_periph_clock_enable(usartx_rx_rcu); // 配置时钟
    gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
    gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);
    gpio_output_options_set(usartx_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_rx_pin);

    /************** usart config **************/
    // 串口时钟
    rcu_periph_clock_enable(RCU_USART0);
    // USART复位
    usart_deinit(usartx);

    usart_baudrate_set(usartx, usartx_p_baudrate);	// 波特率
    usart_parity_config(usartx, usartx_p_parity); // 校验位
    usart_word_length_set(usartx, usartx_p_wl); // 数据位数
    usart_stop_bit_set(usartx, usartx_p_stop_bit); // 停止位
    usart_data_first_config(usartx, usartx_p_data_first); // 先发送高位还是低位

    // 发送功能配置
    usart_transmit_config(usartx, USART_TRANSMIT_ENABLE); 
    // 使能串口
    usart_enable(usartx); 
}

总结起来:

GPIO引脚配置

csharp 复制代码
uint32_t usartx_tx_rcu = RCU_GPIOA;
uint32_t usartx_tx_port = GPIOA;
uint32_t usartx_tx_pin = GPIO_PIN_9;
uint32_t usartx_tx_af = GPIO_AF_7;

uint32_t usartx_rx_rcu = RCU_GPIOA;
uint32_t usartx_rx_port = GPIOA;
uint32_t usartx_rx_pin = GPIO_PIN_10;
uint32_t usartx_rx_af = GPIO_AF_7;

串口配置

csharp 复制代码
uint32_t usartx = USART0;
uint32_t usartx_rcu = RCU_USART0;

uint32_t usartx_p_baudrate = 115200;
uint32_t usartx_p_parity = USART_PM_NONE;
uint32_t usartx_p_wl = USART_WL_8BIT;
uint32_t usartx_p_stop_bit = USART_STB_1BIT;
uint32_t usartx_p_data_first = USART_MSBF_LSB;

完整示例

csharp 复制代码
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"


static void USART_config() {
    uint32_t usartx_tx_rcu = RCU_GPIOA;
    uint32_t usartx_tx_port = GPIOA;
    uint32_t usartx_tx_pin = GPIO_PIN_9;
    uint32_t usartx_tx_af = GPIO_AF_7;

    uint32_t usartx_rx_rcu = RCU_GPIOA;
    uint32_t usartx_rx_port = GPIOA;
    uint32_t usartx_rx_pin = GPIO_PIN_10;
    uint32_t usartx_rx_af = GPIO_AF_7;

    uint32_t usartx = USART0;
    uint32_t usartx_rcu = RCU_USART0;

    uint32_t usartx_p_baudrate = 115200;
    uint32_t usartx_p_parity = USART_PM_NONE;
    uint32_t usartx_p_wl = USART_WL_8BIT;
    uint32_t usartx_p_stop_bit = USART_STB_1BIT;
    uint32_t usartx_p_data_first = USART_MSBF_LSB;

    /************** gpio config **************/
    // tx
    rcu_periph_clock_enable(usartx_tx_rcu);	// 配置时钟
    gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
    gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
    gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);
    // rx
    rcu_periph_clock_enable(usartx_rx_rcu); // 配置时钟
    gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
    gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);
    gpio_output_options_set(usartx_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_rx_pin);

    /************** usart config **************/
    // 串口时钟
    rcu_periph_clock_enable(RCU_USART0);
    // USART复位
    usart_deinit(usartx);

    usart_baudrate_set(usartx, usartx_p_baudrate);	// 波特率
    usart_parity_config(usartx, usartx_p_parity); // 校验位
    usart_word_length_set(usartx, usartx_p_wl); // 数据位数
    usart_stop_bit_set(usartx, usartx_p_stop_bit); // 停止位
    usart_data_first_config(usartx, usartx_p_data_first); // 先发送高位还是低位

    // 发送功能配置
    usart_transmit_config(usartx, USART_TRANSMIT_ENABLE); 
    // 使能串口
    usart_enable(usartx); 
}

//发送一byte数据
void send_byte(uint8_t data) {
    //通过USART发送
    usart_data_transmit(USART0, data);
    //判断缓冲区是否已经空了
    //FlagStatus state = usart_flag_get(USART_NUM,USART_FLAG_TBE);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}

// 发送多个byte数据
void send_data(uint8_t* data, uint32_t len) {
    while(data && len--) {
        send_byte(*data);
        data++;
    }
}

//发送字符串
void send_string(char *data){
	//满足: 1.data指针不为空  2.发送的数据不是\0结束标记
	while(data && *data){
		send_byte((uint8_t)(*data));
		data++;
	}
}

int fputc(int ch, FILE *f){
	send_byte((uint8_t)ch);
	return ch;
}

int main(void)
{
    systick_config();
    USART_config();
    uint8_t cnt;
    while(1) {
        //      send_byte(cnt++);
        //		send_string("hello\r\n");
        //		printf("hello %d\r\n", cnt++);
        delay_1ms(1000);
    }
}
相关推荐
Zwawa2 小时前
两根线怎么挂住一堆设备:I2C 协议原理
c语言·单片机·嵌入式
倔强的胡萝卜4 小时前
基于STM32F103C8T6的温度报警器设计
stm32·单片机·嵌入式硬件
缘来是你远去是我4 小时前
ZYNQ 系列芯片中断机制详解:类型、处理过程与中断处理函数
单片机·嵌入式硬件
LCG米6 小时前
STM32 定时器主从模式输出精确脉冲数实测:TRGO 触发链拆解、多发一脉冲根因与干净停止时序落地
stm32·单片机·嵌入式硬件·嵌入式
青梅味猪大肠6 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统
ChaseVLSI7 小时前
FPGA与ASIC的区别详解:内部结构、开发成本与适用场景,项目选型到底该选哪个
嵌入式硬件·fpga开发·硬件架构·硬件工程
东莞市壹星自动化设备有限公司7 小时前
透明圆瓶内部特征怎样定位:折射追踪与近远相位分支
嵌入式硬件·自动化·需求分析·几何学·骨骼绑定
Dev_XH7 小时前
【成品设计】基于物联网的配电箱智能防护系统设计
stm32·单片机·嵌入式硬件·物联网
Dev_XH9 小时前
【成品设计】基于单片机的工厂设备能耗监控与优化系统
stm32·单片机·嵌入式硬件·物联网
不脱发的程序猿9 小时前
STM32制作单手鼠标键盘
stm32·嵌入式硬件·计算机外设·usb·qmk