目录
USART串口将是我们接触的第一个通信协议,也是最常用的通信协议。在项目开发中,我们常常用串口来打印单片机的运行日志,在查找一些运行时异常时特别有用,如果能通过串口日志打印来找出运行时的异常,肯定就不需要再debug了,省去了很多时间。
下面是GD32串口的结构框图,咋一看非常复杂,但其实日常我们只使用了其中一小部分。

GD32中的串口支持大概下面几种模式——全双工异步通信、智能卡模式、同步通信模式、硬件流操作、串行红外编解码功能、LIN模式、半双工通信模式
但并不是GD32中所有的串口都支持这些模式,USART0/1/2支持所有的功能,UART3/4仅支持全双工异步通信。
上面USART0/1/2和UART3/4并不是笔误,USART和UART的区别在于中间的“S”,这个“S”是英文Synchronous(同步)的缩写,因为UART3/4不支持同步传输模式,因此缩写中也就没有加“S”。
因为日常几乎只使用到全双工异步通信模式,所以下面只介绍这个模式。
满血版的串口有5个引脚,但在全双工异步通信模式下只需要用到RX和TX引脚进行通信。

下面是全双工异步通讯时序图。

通讯开始后,发送一个起始位,起始位后紧跟每一个位的数据,最后一位,即bit7有可能为校检位,取决于用户的选择,但一般来说我们不需要使用校检位,最后会以一个停止位来结束一次通信。
停止位的时间长度并不一定是一个时间单位,不同的模式要设置不同的停止位长度。
| 停止位长度(位) | 功能描述 |
|---|---|
| 1 | 默认值 |
| 0.5 | 智能卡模式接收 |
| 2 | 标准USART,单线及调制解调模式 |
| 1.5 | 智能卡模式发送和接收 |
使用全双工异步通信时,使用1位停止位即可。
下图为串口发送的时序图。

串口发送的简要步骤:
说明:
TBE,全称Transfer Buffer Empty,“发送缓冲区空”标志位,当发送缓冲区为空该标志位置位,反之。
TC,全称Transfer Complete,“发送完成”标志位,当串口发送完成该标志位置位,很快后会硬件清零
串口接收的简要步骤:
说明:
RBNE,全称Read Buffer Not Empty,“接收缓冲区非空”标志位,当接收缓冲区非空时该标志位置位,反之。
usart.c文件
#include "usart.h"
void USART_Config(void)
{
/* 初始化GPIO外设 */
rcu_periph_clock_enable(RCU_GPIOA);
/* TX管脚,PA9,复用推挽输出,速度50MHz */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
/* RX管脚,PA10,下拉输入,速度50MHz */
gpio_init(GPIOA, GPIO_MODE_IPD, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
/* 初始化USART外设 */
rcu_periph_clock_enable(RCU_USART0); // 使能串口0时钟
usart_baudrate_set(USART0, 115200); // 波特率115200
usart_parity_config(USART0, USART_PM_NONE); // 无校检
usart_word_length_set(USART0, USART_WL_8BIT); // 8位数据位
usart_stop_bit_set(USART0, USART_STB_1BIT); // 1位停止位
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); // 使能串口发送
usart_receive_config(USART0, USART_RECEIVE_ENABLE); // 使能串口接收
usart_enable(USART0); // 使能串口
}
///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口 */
usart_data_transmit(USART0, (uint8_t)ch);
/* 等待发送完毕 */
while (usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
return (ch);
}
///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (usart_flag_get(USART0, USART_FLAG_RBNE) == RESET);
return (int)usart_data_receive(USART0);
}
上面的例程代码我们使用GD32的USART0外设,对于USART0我们需要初始化PA9和PA10这两个管脚,每个串口外设都有对应的管脚。
串口外设对应的发送接收管脚可以参考下表。
| 串口 | 发送管脚(TX) | 接收管脚(RX) |
|---|---|---|
| USART0 | PA9 | PA10 |
| USART1 | PA2 | PA3 |
| USART2 | PB10 | PB11 |
串口的发送和接收例程中分别封装在fputc和fgetc函数中,重定义这两个函数,使用这两个函数需包含头文件“stdio.h”,我们在向串口发送数据就可以直接用printf函数,向串口接收数据时就可以用scanf函数,十分符合我们平时的习惯。
但大家应该注意到,使用重定向只能固定某一个串口,所以使用重定向最好定义在自己常用的串口上。
串口发送的main.c文件
现象:每秒向串口发送一个“Hello”字符串。
int main(void)
{
systick_config();
USART_Config();
while(1)
{
printf("Hello\n");
delay_ms(1000);
}
}

串口接收的main.c文件
现象:电脑端向GD32串口发送数据,GD32接收后返回所接收的内容。
int main(void)
{
systick_config();
USART_Config();
char buf[20] = {0};
while(1)
{
memset(buf, 0x00, sizeof(buf));
scanf("%s", buf);
printf("received: %s\n", buf);
}
}

这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我正在开发一个Rails应用程序,我需要在其中找到给定特定偏移量或时区的夏令时开始和结束日期。我基本上在我的数据库中保存了从用户浏览器接收到的时区偏移量(“+3”,“-5”),我想在它出现时修改它由于夏令时的变化。我知道Time实例变量有dst?和isdst方法,如果存储在它们中的日期在夏令时与否。>Time.new.isdst=>true但是使用它来查找夏令时的开始和结束日期会占用太多资源,而且我还必须为我拥有的每个时区偏移量执行此操作。我想知道更好的方法。 最佳答案 好的,基于你所说的和@dhouty'sanswer:您希望能够
我有一台生产机器和一台开发机器,都运行ubuntu8.10并且都运行最新的phusionpassenger。当我在osx上的本地开发机器上使用ruby1.9.1时,我想知道外面的人是否已经在使用带有ruby1.9.1甚至1.9.2的phusionpassenger?如果是这样,请告诉我们您的设置!此外,有没有办法在apache上使用phusionpassenger同时运行ruby1.8.7(ree)和1.9.1?感谢您的指点,我在任何地方都找不到任何提示... 最佳答案 是的,从某些2.2.x版本开始就正式支持它,我不记
date_select方法只能设置:start_year,但我想设置开始日期(例如3个月前的日期)(但没有这样的选项)。那么,我可以将开始日期设置为date_select方法吗?或者,要制作这样的选择框,我应该使用select_tag和options_for_select吗?或者,有什么解决办法吗?谢谢, 最佳答案 有可能……例如:start_year–设置年份选择的开始年份。默认为Time.now.year-5参见thisresource. 关于ruby-Rails3-我可以将开始日期
我想从特定索引开始遍历数组。我该怎么做?myj.eachdo|temp|...end 最佳答案 执行以下操作:your_array[your_index..-1].eachdo|temp|###end 关于ruby-从特定索引开始迭代数组,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/44151758/
一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是