立创·天空星开发板-GD32F407VE-USART

2024-06-08 04:28

本文主要是介绍立创·天空星开发板-GD32F407VE-USART,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文以 立创·天空星开发板-GD32F407VET6-青春版 作为学习的板子,记录学习笔记。

立创·天空星开发板-GD32F407VE-USART

    • 基础通信概念
      • 同步通信 & 异步通信
      • 串行通信 & 并行通信
      • 双工 & 单工
      • 通讯速率
        • 码元
    • 串口通信
      • 数据帧
    • 串口封装

基础通信概念

通信协议是网络中(包括互联网)设备之间交换信息时所必须遵守的规则的正式描述。

同步通信 & 异步通信

  • 分类依据:通信过程中发送方和接收方是否使用相同的时钟频率。
  • 同步通信(Synchronous Communication):发送方和接收方使用相同的时钟频率,数据以比特流(数据帧)的形式连续传输。数据帧包括同步字符、数据部分和校验码等。
  • 异步通信(Asynchronous Communication):发送方和接收方使用各自的时钟频率,数据以字符为单位进行传输。每个字符数据前有一个起始位,后有停止位,用于标识字符的开始和结束。

故而,同步通信和异步通信的最大区别在于传输数据时是否需要时钟信号同步。有钟为同,无钟为异。

串行通信 & 并行通信

  • 分类依据:数据在传输线上的传输方式。
  • 串行通信(Serial Communication):数据的各个位在同一根数据线上逐位发送和接收。串行通信传输速度慢,但传输距离远,适合远距离通信。
  • 并行通信(Parallel Communication):数据的各个位同时在多根数据线上发送或接收。并行通信传输速度快,但成本高,适合短距离通信。

故而,串行通信和并行通信的最大区别在于传输数据时数据线的根数。单根为串,多根为并。

双工 & 单工

  • 分类依据:通信双方的信息传输方向。
  • 双工(Duplex)
    • 全双工(Full-Duplex):通信双方可以同时发送和接收数据。
    • 半双工(Half-Duplex):通信双方可以相互发送和接收数据,但不能同时进行。
  • 单工(Simplex):通信是单向的,一方只能发送数据,另一方只能接收数据。

故而,双工和单工的最大区别在于传输方向是否是双向的。双传为双工,单传为单工。

通讯速率

衡量通讯性能的一个非常重要的参数就是通讯速率

  • 比特率:每秒钟传输的二进制位数,单位为(bit/s)
  • 波特率:每秒钟传输了多少个码元
码元

码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。

如果在通讯传输中,用 0V 表示数字 0,5V 表示数字 1,那么一个码元可以表示两种状态 0 和 1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致。

如果在通讯传输中,有 0V、2V、4V 以及 6V 分别表示二进制数 00、01、10、11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半。

因为很多常见的通讯中一个码元都是表示两种状态(0和1),所以常常直接以波特率来表示比特率。

串口通信

Universal Asynchronous Receiver Transmitter 即 : 通用异步收发器

串口通信是一种通用的串行的异步通信总线,该总线有两条数据线,可以实现全双工的发送和接收,在嵌入式系统中常用于主机与辅助设备之间的通信。

数据帧

  • 在串口通信中,数据帧是传输数据的单元。
  • 一帧数据包含多个组成部分,以确保数据的正确传输和接收。
    数据帧
    以传递一个字母 k 为例,若数据为采用八位,并使用低位先行的方式进行传输。过程大致如下:
  • 字母 k 的二进制为 01101011
  • 采用低位先行的传输方式的话,其传输顺序应该是 11010110
  • 传输波形大致如下所示:
    串口数据发送波形

串口封装

天空星开发板的 PA9 和 PA10 对应的是 USART0 的 TX 和 RX 功能。
运用库函数,封装代码如下:

  • ExtendedUSART.h
#ifndef __EXTENDED_USART_H__
#define __EXTENDED_USART_H__#include "gd32f4xx.h"
#include <stdio.h>// 发送配置
#define USART_TX_RCU        RCU_GPIOA
#define USART_TX_PORT       GPIOA
#define USART_TX_PIN        GPIO_PIN_9
#define USART_TX_ALT        GPIO_AF_7
// 接收配置
#define USART_RX_RCU        RCU_GPIOA
#define USART_RX_PORT       GPIOA
#define USART_RX_PIN        GPIO_PIN_10
#define USART_RX_ALT        GPIO_AF_7
// 中断配置
#define USART_RCU           RCU_USART0
#define USART_NUM           USART0
#define USART_IRQ           USART0_IRQn
#define USART_IRQ_Handler   USART0_IRQHandler/*!\brief    初始化串口 0\param[in]  b  : [uint8_t] 一个字节的数据\param[out] none\retval     none
*/
void USART0_config();/*!\brief    往串口 0 发送1个字节数据\param[in]  b  : [uint8_t] 一个字节的数据\param[out] none\retval     none
*/
void USART0_send_byte(uint8_t b);/*!\brief    往串口 0 发送多个字节数据\param[in]  dat  : [uint8_t*] 字节数据首元素地址\param[in]  len  : [uint32_t] 字节数据的长度\param[out] none\retval     none
*/
void USART0_send_data(uint8_t* dat, uint32_t len);/*!\brief    往串口 0 发送发送字符串 (结尾标记\0)\param[in]  dat  : [char*] 字符串首字符地址\param[out] none\retval     none
*/
void USART0_send_string(char *dat);#endif
  • ExtendedUSART.c
#include "ExtendedUSART.h"// 串口接收缓冲区大小
#define USART_RECEIVE_LENGTH  1024
// 串口接收数据缓冲区
static uint8_t g_recv_buff[USART_RECEIVE_LENGTH];
// 接收到字符的长度
static uint32_t g_recv_length = 0;/*!\brief    初始化串口 0\param[in]  b  : [uint8_t] 一个字节的数据\param[out] none\retval     none
*/
void USART0_config() {// GPIO 配置: TXD, PA9rcu_periph_clock_enable(USART_TX_RCU);gpio_mode_set(USART_TX_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, USART_TX_PIN);gpio_af_set(USART_TX_PORT, USART_TX_ALT, USART_TX_PIN);// GPIO 配置: TXD, PA10rcu_periph_clock_enable(USART_RX_RCU);gpio_mode_set(USART_RX_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, USART_RX_PIN);gpio_af_set(USART_RX_PORT, USART_RX_ALT, USART_RX_PIN);// 启用串口时钟rcu_periph_clock_enable(USART_RCU);// 复位串口usart_deinit(USART_NUM);usart_baudrate_set(USART_NUM, 115200);	            // 波特率usart_parity_config(USART_NUM, USART_PM_NONE);      // 校验位, 无校验(USART_PM_NONE), 偶校验(USART_PM_EVEN), 奇校验(USART_PM_ODD)usart_word_length_set(USART_NUM, USART_WL_8BIT);    // 数据位数usart_stop_bit_set(USART_NUM, USART_STB_1BIT);      // 停止位usart_data_first_config(USART_NUM, USART_MSBF_LSB); // 先发送高位还是低位// 发送功能配置usart_transmit_config(USART_NUM, USART_TRANSMIT_ENABLE);// 接收功能配置usart_receive_config(USART_NUM, USART_RECEIVE_ENABLE);// 接收中断配置nvic_irq_enable(USART_IRQ, 2, 2);// 串口中断能usart_interrupt_enable(USART_NUM, USART_INT_RBNE);usart_interrupt_enable(USART_NUM, USART_INT_IDLE);// 串口使能usart_enable(USART_NUM);
}/*!\brief    往串口 0 发送1个字节数据\param[in]  b  : [uint8_t] 一个字节的数据\param[out] none\retval     none
*/
void USART0_send_byte(uint8_t b) {//通过USART发送usart_data_transmit(USART0, b);//判断缓冲区是否已经空了while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}/*!\brief    往串口 0 发送多个字节数据\param[in]  dat  : [uint8_t*] 字节数据首元素地址\param[in]  len  : [uint32_t] 字节数据的长度\param[out] none\retval     none
*/
void USART0_send_data(uint8_t* dat, uint32_t len) {while(dat && len--) {USART0_send_byte(*dat);dat++;}
}/*!\brief    往串口 0 发送发送字符串 (结尾标记\0)\param[in]  dat  : [char*] 字符串首字符地址\param[out] none\retval     none
*/
void USART0_send_string(char *dat) {//满足: 1.data指针不为空  2.发送的数据不是\0结束标记while(dat && *dat) {USART0_send_byte((uint8_t)(*dat));dat++;}
}int fputc(int ch, FILE *f) {USART0_send_byte((uint8_t)ch);return ch;
}// 声明弱函数, 用于接收来自串口 0 的数据并回显
// 外部可以通过声明同名强函数来覆盖该函数的默认行为
__attribute__((weak)) void USART0_on_received(uint8_t* dat, uint32_t len) {USART0_send_data(dat,len);
}// 串口接收数据的中断处理函数
void USART_IRQ_Handler(void) {if ((usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) == SET) {usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);uint16_t value = usart_data_receive(USART0);g_recv_buff[g_recv_length] = value;g_recv_length++;}if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) == SET) {//读取缓冲区,清空缓冲区usart_data_receive(USART0);g_recv_buff[g_recv_length] = '\0';// g_recv_buff 为接收的数据, g_recv_length 为接收的长度USART0_on_received(g_recv_buff, g_recv_length);g_recv_length = 0;}
}
  • main.c
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"#include "ExtendedUSART.h"void USART0_on_received(uint8_t* dat, uint32_t len) {printf("Received: %s\r\n", dat);
}int main(void) {systick_config();USART0_config();uint8_t cnt = 0;while(1) {USART0_send_byte(cnt++);USART0_send_byte(0x0D); // \rUSART0_send_byte(0x0A); // \nUSART0_send_string("This is string!\r\n");printf("cnt = %d\r\n", cnt);if(cnt > 99) {cnt = 0;}delay_1ms(1000);}
}

额外说明

  1. 如果希望通过 printf 函数将数据打印到串口助手上显示,需要重写 stdio.h 中的 fputc 函数。
  2. 如果希望调用方无论是否定义回调函数都能使得回调函数默认可用,可以采用定义弱函数的方式来实现。也就是我这边提供的 ExtendedUSART.c 文件中的 USART0_on_received 函数的定义方式,即便是在 main.c 中没有定义,照样能回显数据。

这篇关于立创·天空星开发板-GD32F407VE-USART的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041201

相关文章

开发板NFS挂载文件目录

文章目录 序NFS1. 安装 NFS 服务器和客户端在服务器上(NFS 服务器端)在客户端上(NFS 客户端) 2. 配置 NFS 服务器创建共享目录编辑 `/etc/exports` 文件启动 NFS 服务 3. 在客户端挂载 NFS 共享创建挂载点挂载 NFS 共享验证挂载 4. 设置开机自动挂载5. 解决权限问题 序 本节主要实现虚拟机(服务器)与开发板(客户端)通过N

安卓开发板_联发科MTK开发评估套件串口调试

串口调试 如果正在进行lk(little kernel ) 或内核开发,USB 串口适配器( USB 转串口 TTL 适配器的简称)对于检查系统启动日志非常有用,特别是在没有图形桌面显示的情况下。 1.选购适配器 常用的许多 USB 转串口的适配器,按芯片来分,有以下几种: CH340PL2303CP2104FT232 一般来说,采用 CH340 芯片的适配器,性能比较稳定,价

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

龙芯L2K0300开发板综合测试

CPU 查看cpu版本信息 cat /proc/cpuinfo 可以看到cpu是64位的LoongsonArch架构 stress压力测试结果 RAM 久久派板载512MB DDR4-2666内存,查看内存信息 cat /proc/meminfo 可以用memtester进行内存性能测试 memtester <size> <times> memtester测试结果

实操在聆思CSK6大模型开发板的英文评测SDK中自定义添加单词、短语、句子资源

引言 英文评测示例通过对用户语音输入的英文单词进行精准识别,提供 单词、短语、句子 三种类型,用户在选择好类型后,可根据屏幕上的提示进行语音输入,评测算法将对输入的英文语音进行精准识别,并对单词的发音、错读、漏读、多读等方面进行评估。 本文将详细介绍在聆思CSK6大模型语音视觉开发板上,如何替换英文评测示例中的单词、短语和句子,从而让您有更好的AI应用体验。 ·· 获取英文评测SDK 部

【免费分享】嵌入式Linux开发板【入门+项目,应用+底层】资料包一网打尽,附教程/视频/源码...

想要深入学习嵌入式Linux开发吗?现在机会来了!我们为初学者们准备了一份全面的资料包,包括原理图、教程、课件、视频、项目、源码等,所有资料全部免费领取,课程视频可试看(购买后看完整版),让你从零开始,快速掌握嵌入式Linux开发技能。 后台私信小雯老师,回复“嵌入式Linux”即可获取开发板完整资料包。 一、资料内容 开发教程:9大教程,覆盖应用层+底层开发 《Linux基础

AI-Talk开发板之helloword

一、说明         创建第一个应用在AI-Talk开发板上运行,编写一个“Hello World”应用,启动之后在主函数里通过UART0(debug)打印"Hello World"。 官方指导:第一个应用 | 聆思文档中心 (listenai.com) 二、创建工程 1、创建项目 在snap的同级目录下创建examples目录,然后进入examples目录,执行创建项目的命令:

“立创EDA专业版”笔记

目录 二、立创EDA专业版 2.0 整体功能 2.0.1 快捷键 2.1 右侧功能栏 2.1.1 过滤 2.2 PCB设计 2.2.1 切换亮度 2.2.2 偏移 2.2.3 单位切换 2.2.4 检查DRC 2.2.5 重新铺铜 2.2.6 布线 2.2.7 锁定 2.2.8 “过滤”设置锁定 2.3 上方菜单栏 2.3.1 保存文件 2.4 元件库

TQZC706开发板教程:LWIP自环测试

本例程基于ZC706开发板实现LWIP自环通讯测试。使用开发板的网口与电脑或路由器等设备连接,使开发板与电脑在同一局域网内,使用telnet工具连接开发板,进行LWIP自环测试。        LWIP自环测试工程在Hello World项目上进行修改,vivado项目不需要有修改直接打开vitis,如下图所示点击pla...-->Board...-->Mod...-->勾选lw

迅为电子RK3588S开发板第三章Buildroot系统功能测试

iTOP-3588S开发板采用瑞芯微RK3588S处理器,是全新一代AloT高端应用芯片,采用8nm LP制程,搭载八核64位CPU(四核Cortex-A76+四核Cortex-A55架构),集成Mali G610 MP4四核GPU,内置AI加速器NPU,算力达6Tops,支持8K视频硬件编码器和硬件解码器,提供了许多功能强大的嵌入式硬件引擎,性能更强的同时,功耗也能稳稳把控。在各个行业,性能表现