立创·天空星开发板-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 中没有定义,照样能回显数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/24489.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python编程学习第一篇——Python零基础快速入门(五)—变量

在上一节中讲的元组和元组操作中&#xff0c;经常看到 tup (1, 2, 3) 这样的代码&#xff0c;这里面其实涉及了编程语言中一个重要的概念就是变量&#xff0c;前面的等式中tup是变量&#xff0c;(1, 2, 3) 是赋与变量的值。前面的一些文章的代码中也都有用到变量&#xff0c;下…

STM32F103实现双击、长按、短按后续

经过上次(上一篇文章)的bug&#xff0c;这次进行了修改&#xff0c;基本原理就是使用基本定时器的计数功能&#xff0c;根据计算赋值合适的arr&#xff08;预装载值&#xff09;以及psc&#xff08;预装载系数&#xff09;&#xff0c;使其实现100ms计时一次&#xff0c;在封装…

校园生活服务平台的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;跑腿管理&#xff0c;文娱活动管理&#xff0c;活动申请管理&#xff0c;备忘录管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff…

正确挑选百兆超薄款工业级网络/脉冲变压器(网络隔离滤波器)

Hqst华强盛&#xff08;石门盈盛电子&#xff09;导读&#xff1a;工业级百兆超薄款网络变压器的生产要特殊的超薄磁芯配正确线径的铜线&#xff0c;使用符合相应防潮标准的凝固胶水。 一 ̖ 首先来看下商业级的超薄款的百兆网络变压器&#xff1a; 商业级&#xff08;消费级&…

麒麟操作系统运维工程师(KYCP)课程,实现职业突破

在IT行业中&#xff0c;掌握先进的技能和知识是实现职业突破的关键。如果你希望在麒麟操作系统上成为一名卓越的运维工程师&#xff0c;那么麒麟操作系统运维工程师&#xff08;KYCP&#xff09;课程将是你的理想全面提升学员在麒麟操作系统环境下的运维能力。课程内容涵盖安全…

mac读不出来ntfs mac硬盘读不出来盘

新买的Mac电脑由于需要导入旧电脑的数据&#xff0c;因此通常会读取备份硬盘&#xff0c;通过硬盘进行导入。不过由于各种原因&#xff0c;有些mac用户反馈无法正常读取或写入NTFS移动硬盘&#xff0c;下面就通过本篇教程&#xff0c;简单讲述当mac读不出来ntfs&#xff0c;mac…

开关电源中电感设计

开关电源设计中电感 只有充分理解电感在DC/DC电路中发挥的作用,才能更优的设计DC/DC电路。本文还包括对同步DC/DC及异步DC/DC概念的解释。 在开关电源的设计中电感的设计为工程师带来的许多的挑战。工程师不仅要选择电感值,还要考虑电感可承受的电流,绕线电阻,机械尺寸等…

监控易监测对象及指标之:全面监控华为FusionInsight实例

在大数据时代&#xff0c;华为FusionInsight作为一款高性能的大数据处理平台&#xff0c;承载着企业关键业务数据的处理和分析任务。为了确保FusionInsight实例的稳定运行&#xff0c;对其进行全面监控显得尤为重要。本文基于监控易工具&#xff0c;对华为FusionInsight实例的监…

产气荚膜梭菌定植与婴儿食物过敏之间的关联

谷禾健康 牛奶蛋白过敏&#xff08;CMPA&#xff09;是婴儿最常见的食物过敏类型之一。粪便病原菌培养显示产气荚膜梭菌阳性率超过30%&#xff0c;明显高于其他细菌。因此推测产气荚膜梭菌定植可能是婴儿牛奶蛋白过敏的发病因素之一。 一项真实世界的研究&#xff0c;杨敏团队从…

Linux操作系统:MongoDB在虚拟机环境下的安装及部署

上传 MongoDB 安装包 将从官网下载好的 MongoDB 上传到要安装的服务器目录中&#xff0c;建议目录为&#xff1a;/usr/local/ 解压 MongoDB 安装包 cd /usr/local/ tar -zxvf mongodb-linux-x86_64-4.0.0.tgz mv mongodb-linux-x86_64-4.0.0 mongodb 创建 MongoDB 必要目录 …

高通CSIPHY combo mode介绍

目录 使用MIPI Switch 使用高通平台CSIPHY的Combo Mode YYYY使用Combo Mode电路图如下: 如何设置combo PHY mode CSIInfo configuration when camera works in normal mode 平台SoC一般都有多个CSIPHY以满足当前手机相机设计多摄的情况,但是一款SoC CSIPHY的个数也是一定…

【python】错误SyntaxError: invalid syntax的解决方法总结

解决Python报错&#xff1a;【Python】错误SyntaxError: invalid syntax的解决方法总结 SyntaxError是Python编程中常见的错误之一&#xff0c;它表明代码中有语法错误。这种错误可能由多种原因引起&#xff0c;包括但不限于拼写错误、错误的缩进、缺少括号等。本文将介绍几种常…

Python 机器学习 基础 之 【常用机器学习库】 scikit-learn 机器学习库

Python 机器学习 基础 之 【常用机器学习库】 scikit-learn 机器学习库 目录 Python 机器学习 基础 之 【常用机器学习库】 scikit-learn 机器学习库 一、简单介绍 二、scikit-learn 基础 1、安装 scikit-learn 2、导入 scikit-learn 3、数据准备 4、数据分割 5、训练模…

使用Gitblit软件开启git服务器

文章目录 使用Gitblit软件开启git服务器&#xff0c;供局域网其他电脑当做git仓库服务1. java依赖环境安装2. Mac系统操作2.1 下载Gitblit、配置参数2.2 启动服务2.3 终止服务&#xff1a;停止脚本即可 3. window系统操作3.1 下载Gitblit、配置参数3.2 启动服务3.3 终止服务&am…

Einstein Summation 爱因斯坦求和 torch.einsum

Einstein Summation 爱因斯坦求和 torch.einsum flyfish 理解爱因斯坦求和的基本概念和语法&#xff0c;这对初学者来说可能有一定难度。对于不熟悉该表示法的用户来说&#xff0c;可能不如直接的矩阵乘法表达式易于理解。 整个思路是 向量的点积 -》矩阵乘法-》einsum 向…

揭秘抖音矩阵号低成本高效运作批量账号的秘诀!

在当今互联网时代,抖音矩阵号搭建已经成为了许多企业和个人追求高效率媒介管理的重要方式,但是高效、低成本地运作这些账号却是一个相当具有挑战性的任务。 在这篇文章中,我将从抖音矩阵账号准备,如何低成本制作视频以及在进行内容制作时,如何高效运作批量账号等大家比较…

翻译软件就用DT浏览器

翻译软件就用DT浏览器

GUI GUIDER、LVGL、LCD驱动关系

理解GUI Guider、LVGL和LCD驱动之间的关系对于开发嵌入式图形用户界面&#xff08;GUI&#xff09;非常重要。以下是它们之间关系的详细说明&#xff1a; 1. LVGL&#xff08;Light and Versatile Graphics Library&#xff09; 简介&#xff1a;LVGL 是一个轻量级、灵活的嵌…

LeetCode 7- 整数反转

给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [-231, 231 - 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例 1&#xff1a; 输入&…

最长递增子序列 - LeetCode 热题 87

大家好&#xff01;我是曾续缘&#x1f496; 今天是《LeetCode 热题 100》系列 发车第 87 天 动态规划第 7 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组…