【STC库函数】UART异步串口通信的使用

今天来看看UART的使用。

串口是嵌入式领域最常用的通讯方式之一了。

STC32G12K128有俩异步串口,串口三和串口四。

STC8G1K08A是只有一个串口,虽然表格没写是哪个,但是我查了一下,是串口一。

关于串口大家应该都比较熟悉了,所以我们直接讲如何使用STC库函数来使用串口。

以下都是以STC32为例,STC8需要自行去对应手册查,不过流程大差不差。

我们一般就使用8位数据位,1位停止位,无校验位。

STC的UART有两种工作模式。

因为我们使用8位数据位,所以一般采用模式0。

剩下我们要确定的就是波特率了。

有俩定时器可以用,不过我们优先使用定时器3,因为串口2(同步串口)只能使用定时器2,为了避免冲突,我们使用定时器3,不过如果你确定用不到串口2的话使用定时器2也是可以的。

波特率计算公式就如同上表,虽然不复杂,但我也懒得计算,好在我们使用库函数的话不用我们自己去算。

我们需要把STC32G_UART.cSTC32G_UART_Isr.c两个文件加入到我们的工程里。

接着使用下面这个函数UART_Configuration来配置串口。

参数一指定串口,参数二是结构体变量的指针,用来进行具体配置。

从上往下依次是:

串口模式,刚刚有提了,我们就用模式0,可变波特率8位数据位,UART_8bit_BRTx

波特率发生器,也就是指定使用的时钟,我们使用定时器3,BRT_Timer3,我这边假设使用的是串口3,不过如果我们使用的是串口4,那么我们就只能用定时器4。或者使用定时器2,这是所有串口都能用的,不过不使用的理由刚刚也说了,串口2只能用定时器2,只有在确定用不到串口2的时候我们才能用定时器2。

波特率,我们直接填写数值就行,范围是110 ~ 115200,可以超过范围,但是没必要。

是否多机通讯,一般不用,我们选择DISABLE

是否接收,如果要接收的话选择ENABLE,如果只需要串口发送数据,那么可以DISABLE

是否波特率加倍,这个直接DISABLE,用不着,并且只有串口1能用。

配置完之后有俩函数可以发送数据,分别是发送字节和发送字符串的。

懂了发送,那我们还需要懂的接收。

关于接收,我们直接搬官方的的示例代码即可,因为在串口的中断函数里已经帮我们把收到的数据收好了,我们只需要学着示例代码把东西取出来即可。

cpp 复制代码
	while (1)
	{
		delay_ms(1);
		if(COM3.RX_TimeOut > 0)		//超时计数
		{
			if(--COM3.RX_TimeOut == 0)
			{
				if(COM3.RX_Cnt > 0)
				{
					for(i=0; i<COM3.RX_Cnt; i++)	TX3_write2buff(RX3_Buffer[i]);	//收到的数据原样返回
				}
				COM3.RX_Cnt = 0;
			}
		}
	}

上面是示例代码中main函数里的主循环,接下来我就简单分析一下代码。

首先是COM3,就是代表串口3的结构体,库函数里定义好的。

RX_TimeOut就是等待时间,在中断函数里(详情可以自行去库函数里看),接收到数据的时候就会把它设为5,然后在上面代码里是当这个等待时间大于5,我们进入一次第一层的if语句,接着如果减一之后它等于0了,我们进入第二层if语句。

RX_Cnt就是接收缓冲区里收到数据的大小,TX3_write2buff就是串口3的发送缓冲区,RX3_Buffer就是串口3的接收缓冲区,上面就是把收到的数据再发送回去。

由于我们的主循环是1ms执行一下这一坨代码,所以每个等待时间就是1ms,上面代码的意思就是如果串口收到数据了,那么我等它5ms,每收到一次数据,就会在中断函数里把等待时间刷新为5,我在main函数里每隔1ms把等待时间减1,如果我能够把它减到0,那么表示至少是5ms没有收到数据了,那我就把数据取出来发送回去。

上面听不明白没关系,我们只需要把这段代码复制下来,把最里面的一层if语句里的逻辑改改就能够自行处理接收到的数据了。

接下里就是最后一个问题。

串口的引脚。

每个串口至少有两组引脚可以供我们选择。

所以我们需要设置我们使用的是哪一组引脚。

我们需要包含一个头文件STC32G_Switch.h,坑人的是库函数手册里没有介绍这个头文件,我还是去翻官方示例代码的时候看到的。

我们使用这个

cpp 复制代码
    UART3_SW(UART3_SW_P00_P01);

或者这个

cpp 复制代码
    UART3_SW(UART3_SW_P50_P51);

就可以设置串口3的引脚了,其他串口只需要把上面函数名(实际上是宏定义)里的数字改掉就行,包括GPIO也是一样的。

然后记得给使用的GPIO配置一下,TXD就给推挽输出,RXD就给高阻输入,或者直接两个都设置为准双向口也可以。

最后的最后,串口输出的可能是乱码,这不一定是代码的问题,我们需要在Keil里改个设置。

其实官方手册里有建议这样设置,但是我在这个系列的第一篇环境配置的时候没有提这个,因为我当时没发觉有什么差别。

然而如果不把这个配置好的话,就算代码没问题也还是会出问题。

cpp 复制代码
#include <STC32G.H>
#include "STC32G_GPIO.h"
#include "STC32G_Delay.h"
#include "STC32G_UART.h"
#include "STC32G_NVIC.h"
#include "STC32G_Switch.h"

void GPIO_Init(void){
    P0_MODE_OUT_PP(GPIO_Pin_1);
    P0_MODE_IN_HIZ(GPIO_Pin_0);
}

void UART_Init(void){
    COMx_InitDefine initer;
    initer.BaudRateDouble = DISABLE;
    initer.Morecommunicate = DISABLE;
    initer.UART_BaudRate = 115200;
    initer.UART_BRT_Use = BRT_Timer3;
    initer.UART_Mode = UART_8bit_BRTx;
    initer.UART_RxEnable = ENABLE;

    UART_Configuration(UART3, &initer);
    NVIC_UART3_Init(ENABLE, Priority_1);

    UART3_SW(UART3_SW_P00_P01);
}

void main(void){
    uint8 i = 0;
    WTST = 0;		//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXSFR();		//扩展SFR(XFR)访问使能 
    CKCON = 0;      //提高访问XRAM速度
    
    GPIO_Init();
    UART_Init();
    EA = 1;
    
    PrintString3("Hello World\r\n");

    while(1){
        delay_ms(1);
        if(COM3.RX_TimeOut > 0){	//超时计数
			if(--COM3.RX_TimeOut == 0){
				if(COM3.RX_Cnt > 0){
					for(i=0; i<COM3.RX_Cnt; i++)	TX3_write2buff(RX3_Buffer[i]);	//收到的数据原样返回
				}
				COM3.RX_Cnt = 0;
			}
		}
    }
    return ;
}

顺带一提,STC的烧录软件里自带串口助手,我更爱STC了。

然后更屌的是我们可以直接使用printf,只需要把stdio.h的头文件加上就行了。

唯一需要改的地方在这里。

PRINTF_SELECT的宏定义改成我们要用的串口就行。

因为在库函数里帮我们重写了putchar函数,而printf底层用的就是putchar,所以等于变相改写了printf。

相关推荐
无垠的广袤1 小时前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟3 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞3 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲4 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up4 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技13 小时前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
单片机日志14 小时前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣15 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
小曹要微笑1 天前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
XINVRY-FPGA1 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga