GD32F30x系列USART数据帧可以通过全双工或半双工、同步或异步进行传输,且支持DMA功能,目前我们这里先不使用DMA,下一节再使用DMA与其对比。
其他的原理与解析就不再赘述,大家可以自行搜索相关资料,要多看数据手册。
1、创建一个usart.c文件和usart.h文件到对应的文件夹中,如下图所示:
将usart.c文件和gd32f30x_usart.c、gd32f30x_misc.c库文件添加到项目工程中,如下图所示:
2、实现串口的初始化,以及串口发送数据,串口中断接收。–这里我们以USART2为例进行初始化和数据接收与发送。
//usart.c文件
#include "usart.h"
uint8_t g_usart_recv_data[100];//用来保存串口接收到的数据,暂时只缓存100个
uint16_t g_usart_recv_count=0;//用来保存当前串口接收到的数据个数
/*
串口初始化--中断模式
这里以USART2为例,
*/
void gd32_usart_init(void)
{
usart_deinit(USART2);
usart_disable(USART2);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_USART2);//使能时钟
/* connect port to USARTx_Tx */
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);//IO口复用
/* connect port to USARTx_Rx */
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);//IO口配置
nvic_irq_enable(USART2_IRQn,1,0);//中断配置
usart_interrupt_enable(USART2,USART_INT_RBNE);//接收中断
usart_baudrate_set(USART2,38400);//波特率设置
usart_parity_config(USART2,USART_PM_NONE);//校验位设置
usart_word_length_set(USART2,USART_WL_8BIT);//数据位设置
usart_stop_bit_set(USART2,USART_STB_1BIT);//停止位设置
usart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE);//
usart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE);//硬件l流控设置
usart_data_first_config(USART2,USART_MSBF_LSB);//发送模式--LSB
usart_transmit_config(USART2,USART_TRANSMIT_ENABLE);//发送使能
usart_receive_config(USART2,USART_RECEIVE_ENABLE);//接收使能
usart_enable(USART2);//使能串口
}
/*
USART2 串口发送数据
p_buff 要发送的数据数组
data_len 发送的数据长度
*/
void gd32_usart_send(uint8_t *p_buff,uint32_t data_len)
{
uint32_t i = 0;
while(data_len--)
{
usart_data_transmit(USART2,p_buff[i]);
while(usart_flag_get(USART2,USART_FLAG_TBE) == RESET);
i++;
}
}
/*
串口接收中断函数
*/
void USART2_IRQHandler(void)
{
if(usart_interrupt_flag_get(USART2,USART_INT_FLAG_ERR_ORERR) != RESET
||usart_interrupt_flag_get(USART2,USART_INT_FLAG_ERR_NERR) != RESET
||usart_interrupt_flag_get(USART2,USART_INT_FLAG_ERR_FERR) != RESET)
{
usart_interrupt_flag_clear(USART2,USART_INT_FLAG_ERR_ORERR);
usart_interrupt_flag_clear(USART2,USART_INT_FLAG_ERR_NERR);
usart_interrupt_flag_clear(USART2,USART_INT_FLAG_ERR_FERR);
return;
}
if(g_usart_recv_count>=100)
{
g_usart_recv_count = 0;
}
if(usart_interrupt_flag_get(USART2,USART_INT_FLAG_RBNE) != RESET)
{
usart_interrupt_flag_clear(USART2,USART_INT_FLAG_RBNE);
g_usart_recv_data[g_usart_recv_count++] = (uint8_t)usart_data_receive(USART2);
}
}
//usart.h文件
#ifndef __USART_H__
#define __USART_H__
#include "gd32f30x.h"
void gd32_usart_init(void);
void gd32_usart_send(uint8_t *p_buff,uint32_t data_len);
#endif
3、在main.c文件的main函数中调用串口的初始化,并循环调用串口发送,这里循环1S发送字符“1234567890”,连接好硬件板和电脑后,编译下载程序到硬件板中,点击调试运行,如下图所示:
4、连接好电脑的串口工具和硬件板,并打开串口调试工具,运行程序即可接收到程序发送出来的字符串,如下图所示:
5、使用电脑的串口助手发送字符串到硬件板,设置断点查看接收的数据是否正确,如下图所示:
数据发送完成后设置断点,查看到当前systick为2114,如下图所示:
我们的systick是1ms中断一次,即1ms当前的systick增加1,因此连续发送200字节的数据消耗CPU的时间为2114-2058=56ms的时间。后续我们在使用DMA发送来验证一下需要多少时间。
注:这里再拓展一个小知识,就是我们之前每1S发送一次数据使用的是delay_1ms(1000)函数,这个函数的话CPU是一直在等待时间到达的,并没有去处理其他的事情(除了中断),这里我们可以使用systick,来实现1S发送一次数据,但是CPU不用一直等待而可以去执行其他的事情,这对软件开发来说是可以大大提高CPU的利用率的,而且正常的软件开发中,非特殊需要都不会使用delay_1ms()这种一直等待函数。
直接在main函数中实现即可,后续有这种延时的需求也可以使用这种方式,例如LED闪烁等。文章来源:https://www.toymoban.com/news/detail-529863.html
int main(void)
{
uint32_t usart_delay_time=0;
systick_config();
gd32_gpio_init();
gd32_usart_init();
while(1)
{
uint8_t data[]="1234567890";
if(systick_distance_get(usart_delay_time)>1000)
{
gd32_usart_send(data,sizeof(data));
usart_delay_time = systick_get();
}
}
return 0;
}
这里我们可以看到效果与之前的代码是一样的,如下图所示:
文章来源地址https://www.toymoban.com/news/detail-529863.html
到了这里,关于GD32F30x系列---串口通信(USART)基础配置(中断接收模式)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!