【GD32H757Z海棠派开发板使用手册】第九讲 USART-printf打印实验

发布者:清新风华最新更新时间:2024-12-03 来源: elecfans关键字:USART 手机看文章 扫描二维码
随时随地手机看文章

9.1实验内容

通过本实验主要学习以下内容:

  • 串口简介

  • GD32H757串口工作原理

  • 使用printf打印信息

9.2实验原理

9.2.1串口简介

串口,从广义上看,指所有串行通信接口,比如RS232、RS422、RS485、SPI、IIC等。串行通讯是指仅用一根接收线和一根发送线就能将数据以位进行传输的通讯方式。和串行通讯相对应的是并行通讯,并行通信指一个传输接口可以传输8个bit即一个byte(有时甚至更多),虽然串行通信比并行通信慢,但是串口可以在仅仅使用两根线的情况下就能实现数据的传输。

对于GD32H757来说,串口一般特指USART(通用同步异步收发器 )和UART(通用异步收发器 )。USART/UART提供了一个灵活方便的串行数据交换接口,数据帧可以通过全双工或半双工,同步或异步的方式进行传输。海棠派开发板搭载的GD32H757最多有8个串口(USART+UART), 对于一般应用来说足够使用了。

9.2.2串口通信帧介绍

GD32H757的串口通信只需要3条线组成,分别为TX(发送线)、RX(接收线)和GND,对于两个通信结点,TX和RX需要交叉连接,如下示例:

wKgZomZBdHiABIwiAAHgknaaCew303.png?imageView2/2/w/1000

下面来介绍下串口数据帧组成。

以下为一个标准的串口通信帧:

wKgZomZBdIWACJN4AAGZCDszKEQ933.png?imageView2/2/w/1000

一个串口帧由空闲、起始位、数据位、校验位以及停止位组成,传输的数据地位在前,高位再后。

空闲:串口TX或RX数据线上没有传输任何数据时,则该线处于为空闲状态。空闲是TX和RX都是处于高电平。

起始位:占一个bit时间,标志数据起始,由一个逻辑0(低电平)的数据位表示。当发送方开始发送一帧数据时,起始位会最先发送,而对于接收方来说,检测到起始位后,即使自己的接收时钟与发送方的数据同步。

数据位:数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定,对于GD32H757来说,数据位一般只有8位。

校验位:校验位占一bit时间,GD32H757可以设置校验位为:奇校验、偶校验或无校验。校验位是为了保证通信的可靠性,如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位,如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。以传输传输数据A:0x01000001为例,如果设置了奇校验,则需要在校验位传输“1”,如果是偶检验,则传输“0”。奇偶校验是由硬件处理的,当设置好校验位后,硬件会自动根据需要传输的数据自动插入校验位。

注意:GD32H757的数据位可设置为8bit和9bit两种方式,当设置了奇校验或偶校验,一定要将数据位设置为9bit;而设置了无校验时,需要将数据位设置为8bit。

停止位:它是一帧数据的结束标志,可以是1bit、1.5bit、2bit个逻辑“1”。

9.2.3串口波特率

波特率是串口通信中一个非常重要的参数,串口通信传输双方必须要设置一样的串口波特率,否则通讯就会出错。波特率可以认为是比特率,即每秒传输的位数。一般波特率可以是9600、19200、115200等等,如果设置波特率为9600,设置通信帧为1bit起始位+8bit数据帧+无校验+1bit停止位,那么每秒钟最多可以传输9600bit/10bit = 960个字节。

现在重点介绍下GD32H757串口接收器的工作原理。GD32H757串口接收器支持16倍(默认)过采样和8倍过采样,16位过采样即发送方发送数据后,GD32470串口接受器会将每个bit采样16次,如果是8倍过采样,则采用8次。下图为16位过采样的示意图:

wKgZomZELdmAQ3R4AAB9zxqzB34755.png?imageView2/2/w/1000

在默认情况下,接收器通过获取三个采样点的值来估计该位的值,其中16倍过采样选取采样点为第7、8、9点,而8倍过采样为第3、4、5采样点。如果在3个采样点中有2个或3个为0,该数据位被视为0,否则为1。如果3个采样点中有一个采样点的值与其他两个不同,不管是起始位,数据位,奇偶校验位或者停止位,都将产生噪声错误(NERR)。

9.2.4GD32H757串口设置步骤

串口设置的一般步骤为:

  1. GPIO时钟开启、串口时钟开启

  2. GPIO设置,发送和接受都要设置为AF模式,且需要设置为正确的AF号

  3. 串口复位

  4. 串口参数配置,主要为波特率、数据位长度、校验位设置、停止位长度

  5. 依据是否需要使用中断或DMA进行中断配置或DMA配置

  6. 使能串口

  7. 编写中断处理函数

9.3硬件设计

海棠派开发板的P1接口将USART0——PA9、PA10引出,读者可以通过P1口使用USART0:

wKgZomZBdSWAAhvxAADKvexuyl4120.png?imageView2/2/w/1000

9.4代码解析

9.4.1在driver_uart.c中定义了串口初始化函数driver_uart_init。

C
void driver_uart_init(typdef_uart_struct *uartx)
{
rcu_periph_clock_enable(uartx->rcu_uart_x);
/* USART configure */
usart_deinit(uartx->uart_x);

driver_gpio_general_init(uartx->uart_rx_gpio);
driver_gpio_general_init(uartx->uart_tx_gpio);

if(uartx->uart_mode_rx==MODE_DMA)
{
if(uartx->uart_rx_dma!=NULL)
{
driver_dma_com_init(uartx->uart_rx_dma,(uint32_t)&USART_RDATA(uartx->uart_x),NULL,DMA_Width_8BIT,DMA_PERIPH_TO_MEMORY);
usart_interrupt_enable(uartx->uart_x,USART_INT_IDLE);
}
}

if(uartx->uart_mode_tx==MODE_DMA)
{
if(uartx->uart_tx_dma!=NULL)
{
driver_dma_com_init(uartx->uart_tx_dma,(uint32_t)&USART_TDATA(uartx->uart_x),NULL,DMA_Width_8BIT,DMA_MEMORY_TO_PERIPH);
// usart_interrupt_enable(uartx->uart_x,USART_INT_TC);
}
}

usart_baudrate_set(uartx->uart_x, uartx->baudrate);
usart_receive_config(uartx->uart_x, USART_RECEIVE_ENABLE);
usart_transmit_config(uartx->uart_x, USART_TRANSMIT_ENABLE);
usart_word_length_set(uartx->uart_x, uartx->data_length);
usart_parity_config(uartx->uart_x, uartx->parity);

usart_enable(uartx->uart_x);
}

9.4.2重定向函数int fputc(int ch, FILE *f)

要使用Printf,重定向函数fputc是必须的。在C 语言标准库中,fputc函数是printf 函数内部的一个函数,功能是将字符ch写入到文件指针file所指向文件的当前写指针位置,简单理解就是把字符写入到特定文件中。我们使用USART函数重新修改fputc函数内容,达到类似“写入”的功能。

fputc定义在bsp_uart.c中

C
int fputc(int ch, FILE *f)
{
driver_uart_transmit_byte(&BOARD_UART,(uint8_t)ch);
return ch;
}

这个函数比较简单,就是调用了接口driver_uart_transmit_byte,该接口定义在driver_uart.c中:

C
Drv_Err driver_uart_transmit_byte(typdef_uart_struct *uartx,uint8_t data)
{
__IO uint64_t timeout = driver_tick;
while(uartx->uart_control.Com_Flag.Bits.SendState==1){
if((timeout+UART_TIMEOUT_MS) <= driver_tick) {              
uartx->uart_control.Com_Flag.Bits.SendState=0;
return DRV_ERROR;
}
}

Drv_Err uart_state=DRV_SUCCESS;
uartx->uart_control.Com_Flag.Bits.SendSuccess=0;
uartx->uart_control.Com_Flag.Bits.SendState=1;

uart_state=driver_uart_flag_wait_timeout(uartx,USART_FLAG_TBE,SET);

usart_data_transmit(uartx->uart_x,data);


uartx->uart_control.Com_Flag.Bits.SendSuccess=1;
uartx->uart_control.Com_Flag.Bits.SendState=0;

return uart_state;
}

这段代码作用是,循环去读串口的TBE标志位,并且将待发送的数据写到串口寄存器中。

9.4.3main函数实现

串口初始化完成并定义好fputc重定向函数后,就可以通过printf函数往电脑上打印数据了。以下main函数:

C
int main(void)
{
//延时和公共驱动部分初始化
driver_init();
//串口初始化,DMA模式开启
BOARD_UART.uart_mode_tx=MODE_DMA;
bsp_uart_init(&BOARD_UART);
bsp_led_init(&LED2);
//打开对应串口的中断
nvic_irq_enable(USART0_IRQn,2,0);
while(1)
{
//printg标准打印(轮训)
printf_log('rndelay 1s rn');
delay_ms(1000);
bsp_led_toggle(&LED2);
printf_log('printf:system driver_tick is %lld rn',driver_tick);

//轮训方式打印
memset(uart_poll_buff,0,50);//清零buff
sprintf((char*)uart_poll_buff,'poll transmit:system driver_tick is %lld rn',driver_tick);//格式化字符串
driver_uart_poll_transmit(&BOARD_UART,uart_poll_buff,strlen((const char*)uart_poll_buff));
printf_log('%s',uart_poll_buff);


//中断方式打印
memset(uart_int_buff,0,50);
sprintf((char*)uart_int_buff,'int transmit:system driver_tick is %lld rn',driver_tick);
driver_uart_int_transmit(&BOARD_UART,uart_int_buff,strlen((const char*)uart_int_buff));
printf_log('%s',uart_int_buff);


//DMA方式打印
memset(uart_dma_buff,0,50);
sprintf((char*)uart_dma_buff,'dma transmit:system driver_tick is %lld rn',driver_tick);
driver_uart_dma_transmit(&BOARD_UART,uart_dma_buff,strlen((const char*)uart_dma_buff));
printf_log('%s',uart_dma_buff);

}
}

本例程main函数首先进行了延时函数初始化,并设置了一个LED灯用来提示代码运行。while(1)循环中先延时1s,再翻转一次LED状态,接着使用printf函数打印系统运行tick时间。

本例程也同步做了printf打印在LCD屏幕的功能,将LCD屏接在海棠派开发板上后,打印信息将同步在显示屏上显示。

9.5实验结果

使用USB转TTL串口的连接线后,配置好串口调试助手,即可看到每秒钟串口打印的数据了。


关键字:USART 引用地址:【GD32H757Z海棠派开发板使用手册】第九讲 USART-printf打印实验

上一篇:【GD32H757Z海棠派开发板使用手册】第十三讲 SDIO-SD卡读写实验
下一篇:关于采用GD32E230系列MCU设计TWS耳机充电盒方案的介绍和应用

推荐阅读最新更新时间:2026-03-25 10:13

GD32H757Z海棠开发板使用手册】第六讲 TIMER_3路PWM输出实验
6.1实验内容 通过本实验主要学习以下内容: TIMER PWM输出原理 TIMER 定时中断 6.2实验原理 6.2.1IO口设置 本例程中,使用TIMER0输出前三个通道的占空比,这三个通道分别为PA8、PA9和PA10,从datasheet中我们可以看到这三个引脚的定义: 所以需要将这三个引脚配置为AF模式并选择正确的AF号: 6.2.2TIMER输出PWM原理 TIMER计数方式有两种:边沿计数和中央计数,其中边沿计数分为向上计数和向下计数。 在向上计数模式下,需要配置TIMER的重载值,当TIMER开始工作后,计数值从0开始递增,当达到重载值后计数值变为0重新开始计数; 向下计数模式和向上模式类似,只是计
[单片机]
【<font color='red'>GD32H757Z</font><font color='red'>海棠</font><font color='red'>派</font><font color='red'>开发板</font>使用手册】第六讲 TIMER_3路PWM输出<font color='red'>实验</font>
GD32H757Z海棠开发板使用手册】第一讲 GPIO-流水灯实验
1.GPIO-流水灯实验 1.1实验内容 通过本实验主要学习以下内容: GPIO结构及原理; GPIO输出功能实现; LED驱动原理。 1.2实验原理 1.2.1GPIO外设原理 GD32H7系列MCU最多支持135个通用I/O引脚(GPIO),分别为PA0 ~ PA10,PA13 ~ PA15,PB0 ~ PB15,PC0 ~ PC15,PD0 ~ PD15,PE0 ~ PE15,PF0 ~ PF15,PG0 ~ PG15,PH0 ~ PH15,PJ8 ~ PJ11,PK0 ~ PK2。各片上设备用其来实现逻辑输入/输出功能。每个GPIO端口有相关的控制和配置寄存器以满足特定应用的需求。片上设备GPIO引脚的外部中断由E
[单片机]
【<font color='red'>GD32H757Z</font><font color='red'>海棠</font><font color='red'>派</font><font color='red'>开发板</font>使用手册】第一讲 GPIO-流水灯<font color='red'>实验</font>
GD32H757Z海棠开发板使用手册】第四讲 FMC-片内Flash擦写读实验
4.1实验内容 通过本实验主要学习以下内容: FMC控制器原理; FMC擦写读操作; 4.2实验原理 4.2.1FMC控制器原理 FMC即Flash控制器,其提供了片上Flash操作所需要的所有功能,在GD32H7XX系列MCU中,具有高达3840KB字节的片上闪存可用于存储指令或数据。FMC也提供了扇区擦除和整片擦除操作以及编程操作。 Flash读取可以支持64字节双字、32位整字、16位半字或字节读操作;Flash编程可以支持64位双字、32位整字编程;Flash擦除支持扇区擦除和整片擦除操作。 Flash具有仅执行的专用代码读保护区域,便于芯片代码保护以及二次合作开发。 FMC框图如下所示,FMC支持用以访问代码或数据
[单片机]
【<font color='red'>GD32H757Z</font><font color='red'>海棠</font><font color='red'>派</font><font color='red'>开发板</font>使用手册】第四讲 FMC-片内Flash擦写读<font color='red'>实验</font>
GD32H757Z海棠开发板使用手册】第二讲 GPIO-按键查询检测实验
2.1实验内容 通过本实验主要学习以下内容: GPIO输入功能原理; 按键查询输入检测原理; 2.2实验原理 2.2.1GPIO输入功能原理 GD32H7XX系列MCU GPIO输入配置结构如下图所示,输入可配置上下拉电阻,通过施密特触发器后可通过备用功能输入或者通过输入状态寄存器进行读取。 输入状态寄存器为GPIOx_ISTAT,其状态位定义如下图所示,每个控制位对应相应引脚的输入电平状态。 GPIO引脚输入电平判断阈值如下图所示,当输入电平小于0.3VDD时,可被内部有效识别为低电平;当输入电平大于0.7VDD时,可被内部有效识别为高电平。 2.3硬件设计 GD32H7海棠派派开发板具有两个按键,对应电路图如
[单片机]
【<font color='red'>GD32H757Z</font><font color='red'>海棠</font><font color='red'>派</font><font color='red'>开发板</font>使用手册】第二讲 GPIO-按键查询检测<font color='red'>实验</font>
GD32H757Z海棠开发板使用手册】第十一讲 SPI-SPI NOR FLASH读写实验
11.1实验内容 通过本实验主要学习以下内容: SPI简介 GD32H7 SPI简介 SPI NOR FLASH——GD25Q128ESIGR简介 使用GD32H7 SPI接口实现对GD25Q128ESIGR的读写操作 11.2实验原理 11.2.1SPI简介 SPI(Serial Peripheral interface),顾名思义是串行外设接口,和UART不同的是,SPI是同步通讯接口,所以带有时钟线,而UART是异步通讯接口,不需要时钟线。 SPI通常使用4根线,分别为SCK、MOSI、MISO、NSS(CS): SCK:串列时脉,由主机发出 MOSI:主机输出从机输入信号(数据由主机发出) MISO:主机输
[单片机]
【<font color='red'>GD32H757Z</font><font color='red'>海棠</font><font color='red'>派</font><font color='red'>开发板</font>使用手册】第十一讲 SPI-SPI NOR FLASH读写<font color='red'>实验</font>
[STM32]USART与串口通信进阶教程(第二部分)
前言 本笔记内容,为本人依据B站UP主“铁头山羊”视频内容(本人为其粉丝),归纳整理总结而来,如有侵权,联系立即删除,同时有想详细了解的也可进行观看bilibili铁头山羊 。 硬件:STM32F103C8T6 软件:Keil 4-2 USART与串口通信(2) 数据发送过程 双缓冲与连续发送 TDR(发送数据寄存器) 移位寄存器 数据发送过程中的问题 问题1:数据发送过快导致的覆盖问题 问题2:数据什么时候发送完成的问题 数据接收过程 TXE标志位(发送数据寄存器空) 含义:Transmit Date Register Empty 发送数据寄存器空 状态 TXE == 0:TDR寄存器为有数据
[单片机]
[STM32]<font color='red'>USART</font>与串口通信进阶教程(第二部分)
USART波特率 vs SPI速率--学习笔记
  本篇文章将与大家探讨USART波特率 vs SPI速率。这里提出一个问题,为什么USART的波特率是内核时钟的1/8或者1/16,而SPI最快的频率可以是内核时钟的1/2。   请大家带着这个问题来阅读本文。      串口和SPI内部时钟   在回答上面问题之前,需要先了解STM32内部时钟的概念,尤其是串口和SPI的内部时钟。   STM32里包含有系统时钟、AHB时钟和APB时钟。APB时钟来源于AHB,AHB时钟来源于系统时钟。      从上图中可以看出,时钟就像流水一样,从时钟源汇聚到系统时钟上,再从系统时钟继续分频或者说是继续分发到AHB、APB。   通常我们谈论的MCU能跑到多少M、主频多少M,其
[单片机]
<font color='red'>USART</font>波特率 vs SPI速率--学习笔记
STM32 USART与USB接收不定数据方法,标准库、HAL库都适用
很多时候,我们使用串口或USB接收数据时,往往不知道PC端会发多长的数据下来, 为了解决这个不定数据接收问题,在此各提供一个解决思路。 串口数据不定接收: 由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据, 由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。 IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一 次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以 叫做一包数据。 还有一个RXNE中断,当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就 会产生IDLE中断。比如给单片机一次性发送8个字
[单片机]
STM32 <font color='red'>USART</font>与USB接收不定数据方法,标准库、HAL库都适用
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved