萤火工场GD32VW553-IOT开发板评测-第二弹:串口中断
分享作者:wx17393370997111
作者昵称:DeepDeep
评测品牌:萤火工场
评测型号:GD32VW553-IOT
发布时间:2025-04-07 14:43:08
0
前言
中断方式串口收发通信
开源口碑分享内容

之前发过LED点灯测试,这次再来个串口通信的。

硬件、软件、资料等信息,iCEasy官方已经整理的很详细了,我就不做过多介绍了。

https://www.iceasy.com/cloud/RISC-V?pid=1907770165638025220

工程的流程也不再赘述了,注意选对芯片就好: HMQ7

不会新建工程的朋友可以参考我以前发的LED点灯测评中的【新建工程】部分。

https://www.iceasy.com/review/1894699606296567809


新建好工程之后,IDE默认生成的.c和.h里的内容是与兆易创新官方的EVAL开发板适配的,EVAL开发板有板载的测试LED和测试按键,而我们的iot开发板是没有这些板载资源的,所以,默认生成的.c和.h里面跟EVAL相关的东西使用起来要注意。


新建好工程后,要做以下修改:

1、删除main.h

2、修改main.c:

#include "gd32vw55x.h"
#include "systick.h"
#include <stdio.h>
#include <string.h>
#include "gd32vw553h_eval.h"

#define TX_BUFFER_SIZE  1024
#define RX_BUFFER_SIZE  1024

/* transmit buffer and receive buffer */
uint8_t tx_buffer[TX_BUFFER_SIZE];
uint8_t rx_buffer[RX_BUFFER_SIZE];
/* counter of transmit buffer and receive buffer */
__IO uint16_t tx_count = 0, rx_count = 0;

/* result of the transfer */
__IO ErrStatus transfer_result = ERROR;

void nvic_config(void);

/*!
 \brief      main function
 \param[in]  none
 \param[out] none
 \retval     none
 */
int main(void)
{
	/* USART interrupt configuration */
	eclic_irq_enable(USART0_IRQn, 1, 0);
	systick_config();

	/* initialize the USART */
	gd_eval_com_init(EVAL_COM0);

	//初始发送,跟上位机打个招呼
	strcpy(tx_buffer,
			"Hello Serial. This is GD32VW553-ioT,Please send me some text, and then I'll send it back to you.");

	/* enable USART TBE interrupt */
	usart_interrupt_enable(EVAL_COM0, USART_INT_TBE);
	
	while (RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TC))
		;

    //循环:等待上位机发送来的数据,每条消息以换行符结束。每收到一条信息,就立马回传给上位机,加上“rx:”方便区分单片机消息。
	while (1)
	{

		/* enable USART RBNE interrupt */
		usart_interrupt_enable(EVAL_COM0, USART_INT_RBNE);
		/* wait until USART receive the rx_buffer */
		while (SET == usart_flag_get(EVAL_COM0, USART_INT_RBNE))
			;
		sprintf(tx_buffer, "rx: %s", rx_buffer);
		/* enable USART TBE interrupt */
		usart_interrupt_enable(EVAL_COM0, USART_INT_TBE);
		while (RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TC))
			;
	}
}

3、修改中断头文件gd32vw55x_it.h

#ifndef GD32VW55X_IT_H
#define GD32VW55X_IT_H

#include "gd32vw55x.h"

/* function declarations */
void eclic_mtip_handler(void);
/* this function handles USART2 exception */
void USART0_IRQHandler(void);

#endif /* GD32VW55X_IT_H */

4、修改中断源文件gd32vw55x_it.c

#include "gd32vw55x_it.h"
#include "systick.h"
#include <string.h>
#include "gd32vw553h_eval.h"

extern uint8_t tx_buffer[];
extern uint8_t rx_buffer[];
extern uint32_t rx_buffer_size, tx_buffer_size;
extern uint16_t tx_count, rx_count;

void eclic_mtip_handler(void)
{
	ECLIC_ClearPendingIRQ(CLIC_INT_TMR);
	delay_decrement();
}

/*!
 \brief      this function handles USART RBNE interrupt request and TBE interrupt request
 \param[in]  none
 \param[out] none
 \retval     none
 */
void USART0_IRQHandler(void)
{
	if (RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_RBNE))
	{
		/* receive data */
		rx_buffer[rx_count] = usart_data_receive(EVAL_COM0);
		if (rx_buffer[rx_count] == '\n')
		{
			usart_interrupt_disable(EVAL_COM0, USART_INT_RBNE);
			rx_count=0;
		}
		else
		{
			rx_count++;
		}
	}

	if (RESET != usart_interrupt_flag_get(EVAL_COM0, USART_INT_FLAG_TBE))
	{
		/* transmit data */
		usart_data_transmit(EVAL_COM0, tx_buffer[tx_count++]);
		if (tx_count >= strlen(tx_buffer))
		{
			usart_interrupt_disable(EVAL_COM0, USART_INT_TBE);
			tx_count=0;
		}
	}
}

5、修改gd32vw553h_eval.h

前面说过,这个是IDE默认适配EVAL开发板的,里面定义了一些EVAL板载LED、按键相关的东西,要么我们只留串口com相关的东西,要么我们也在硬件上添加LED和按键。我是只为了测试串口中断,就删掉了LED和按键的东西。

#ifndef GD32VW55X_EVAL_H
#define GD32VW55X_EVAL_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "gd32vw55x.h"

#define COMn                             1U
#define EVAL_COM0                        USART0
#define EVAL_COM0_CLK                    RCU_USART0

#define EVAL_COM0_TX_PIN                 GPIO_PIN_15
#define EVAL_COM0_RX_PIN                 GPIO_PIN_8

#define EVAL_COM0_TX_GPIO_PORT           GPIOB
#define EVAL_COM0_TX_GPIO_CLK            RCU_GPIOB
#define EVAL_COM0_TX_AF                  GPIO_AF_8

#define EVAL_COM0_RX_GPIO_PORT           GPIOA
#define EVAL_COM0_RX_GPIO_CLK            RCU_GPIOA
#define EVAL_COM0_RX_AF                  GPIO_AF_2

/* configure COM port */
void gd_eval_com_init(uint32_t com);


#ifdef __cplusplus
}
#endif

#endif /* GD32VW55X_EVAL_H */

6、修改gd32vw553h_eval.c,跟5一样,也要针对我们的iot开发板做一些适配,去掉跟EVAL开发板相关的东西

#include "gd32vw553h_eval.h"

/* private variables */
static rcu_periph_enum COM_CLK[COMn] = {EVAL_COM0_CLK};
static uint32_t COM_TX_PIN[COMn] = {EVAL_COM0_TX_PIN};
static uint32_t COM_RX_PIN[COMn] = {EVAL_COM0_RX_PIN};

/*!
    \brief      configure COM port
    \param[in]  COM: COM on the board
      \arg        EVAL_COM0: COM on the board
    \param[out] none
    \retval     none
*/
void gd_eval_com_init(uint32_t com)
{
    /* enable GPIO clock */
    uint32_t COM_ID = 0U;
    if(EVAL_COM0 == com)
    {
        COM_ID = 0U;
    }

    rcu_periph_clock_enable(EVAL_COM0_TX_GPIO_CLK);
    rcu_periph_clock_enable(EVAL_COM0_RX_GPIO_CLK);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[COM_ID]);

    /* connect port to USARTx_Tx */
    gpio_af_set(EVAL_COM0_TX_GPIO_PORT, EVAL_COM0_TX_AF, COM_TX_PIN[COM_ID]);

    /* connect port to USARTx_Rx */
    gpio_af_set(EVAL_COM0_RX_GPIO_PORT, EVAL_COM0_RX_AF, COM_RX_PIN[COM_ID]);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(EVAL_COM0_TX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_TX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM0_TX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, COM_TX_PIN[COM_ID]);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(EVAL_COM0_RX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_RX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM0_RX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, COM_RX_PIN[COM_ID]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com, 115200U);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);
    usart_enable(com);
}

7、systick.h和systick.c无所谓,里面就是延时用的,我们这里没用到,想删就删,想留就留

代码修改完之后,编译生成,烧录,这里也不做赘述了

烧录完成后,boot跳线设置好,串口ttl连接电脑,注意我们代码里用的是iot的com0,所以:

ttl_tx——》iot的PA8(UART0.rx)

ttl_rx——》iot的PB15(UART0.tx)

连好GND和供电,电脑端打开常用的串口调试工具,打开串口,iot复位,电脑端串口调试工具会先收到iot发来的打招呼信息,之后,上位机无论发什么内容,iot都会将消息回传给电脑端串口调试工具

上位机串口调试工具窗口视频效果:

【萤火工场GD32VW553-IOT开发板 中断模式串口收发通信】

https://www.bilibili.com/video/BV1HuZoYjEqx/?share_source=copy_web&vd_source=2a3cb18c475b8e2d2601f09cd41a561e

全部评论
暂无评论
0/144