什么是串口
串口是一种在数据通讯中广泛使用的通讯接口,通常我们叫做UART
(通用异步收发传输器Universal Asynchronous Receiver/Transmitter),其具有数据传输速度稳定、可靠性高、适用范围广等优点。在嵌入式系统中,串口常用于与外部设备进行通讯,如传感器、液晶显示屏、WiFi模块、蓝牙模块等。
串口通信中的 TXD(Transmit Data)和 RXD(Receive Data)是串口通信中的两个重要信号。
TXD是指串口发送端的数据信号,而RXD是指串口接收端的数据信号。在串口通信中,发送端把要发送的数据发送到TXD引脚上,接收端则通过RXD引脚来接收这些数据。
TXD 发送端数据信号 RXD 接收端数据信号
TXD和RXD信号的实现方式取决于使用的芯片或模块。一般来说,它们都是通过芯片或模块的串口功能来实现的,这需要将相应的引脚连接到芯片或模块的串口引脚上。
在发送数据时,需要将要发送的数据通过串口的发送缓冲区发送到TXD引脚上,接收端通过RXD引脚接收这些数据并放入接收缓冲区中。在接收端收到完整的数据后,可以通过相应的处理进行数据的解析和处理。
需要注意的是,TXD和RXD的电平标准也需要一致,一般常见的有TTL电平和RS232电平,如果不一致则需要进行电平转换。同时,在编写程序时也需要注意串口波特率、数据位、停止位等参数的设置,以保证通信的稳定和可靠
以下是STC8H的芯片引脚介绍图
其中有4组Uart通讯口:
串口 | RXD | TXD |
UART1 | P3.0 | P3.1 |
P3.6 | P3.7 | |
P1.6 | P1.7 | |
P4.3 | P4.4 | |
UART2 | P1.0 | P1.1 |
P4.6 | P4.7 | |
UART3 | P0.0 | P0.1 |
P5.0 | P5.1 | |
UART4 | P0.2 | P0.3 |
P5.2 | P5.3 |
串口TTL通讯协议
串口 TTL 通讯协议通常是指通过串行通信接口(TTL UART)进行数据传输的协议。这种协议通常用于连接微控制器、传感器、单片机等设备,以实现数据的收发和控制。串口 TTL 通讯协议通常包括以下几个方面:
-
物理连接:串口 TTL 通常使用一根或多根导线将设备连接在一起,这些导线通常包括信号线(如TX、RX)、地线(GND)和可能的控制线(如RTS、CTS)
-
数据格式:包括数据帧的格式,如起始位、停止位、数据位和校验位。常见的配置包括 8 位数据位、1 位停止位和无校验。
-
波特率:指数据传输的速率,通常以每秒传输的位数(bps)来表示,常见的波特率包括 9600、115200 等。
-
控制协议:有时候需要额外的控制信号或命令来启动、停止或配置通讯。这些控制信号可能包括流量控制(如硬件流控)、命令传输等。
-
异步串行通信:串口 TTL 使用异步串行通信协议,通过将数据分成数据帧并在首尾加上起始位和停止位来传输数据。
-
TTL 电平:串口 TTL 使用 TTL 电平进行数据传输,其电压范围一般是 0 到 5V,需要注意不同设备之间 TTL 电平的兼容性。
TX 用于发送数据,RX 用于接收数据,它们是串口 TTL 通信中最基本的信号
根据具体的应用场景和设备,串口 TTL 通讯协议可能会有所不同,但是通常遵循上述基本原则。例如,一些设备可能需要特定的数据格式或控制信号来实现特定的功能。
串口转USB
串口转USB是一种常见的设备,用于连接使用串口通信协议的设备到计算机或其他设备的USB接口。这种设备通常被称为串口转USB适配器或串口转USB转换器。它的作用是将串口设备的信号转换成USB信号,使得串口设备可以通过USB接口与计算机进行通信。
串口转USB适配器通常包括以下几个部分:
-
串口接口:用于连接串口设备的端口,通常是RS-232或TTL接口。
-
USB接口:用于连接计算机或其他设备的USB端口。
-
转换芯片:用于将串口信号转换成USB信号,以实现串口与USB之间的数据转换和通信。
-
驱动程序:有些串口转USB适配器需要安装特定的驱动程序才能在计算机上正常工作,这些驱动程序通常由适配器的制造商提供。
使用串口转USB适配器可以方便地将传统的串口设备连接到现代的计算机或其他设备上,实现数据传输和通信。这在很多场景下都是非常有用的,特别是在需要连接老旧设备或嵌入式系统时。
STC8H核心板串口调试
原理图
D+
D-
对应的usb口,和pc主机连接P3.1
P3.0
对应的芯片- `采用CH340将串口和USB之间进行转换
需求:通过串口调试工具,发送消息给开发板,开发板原封不动的将消息传回。
开发步骤:
- 新建项目
- 导入库函数
- 编写逻辑
串口调试实现
-
新建项目。新建
main.c
文件 -
导入函数库。拷贝以下函数库文件到项目目录:
-
代码编写(发送)
#include "Config.h"
#include "GPIO.h"
#include "UART.h"
#include "Delay.h"
#include "NVIC.h"
#include "Switch.h"
/************* 功能说明 **************
双串口全双工中断方式收发通讯程序。
通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回, 默认波特率:115200,N,8,1.
通过开启 UART.h 头文件里面的 UART1~UART4 定义,启动不同通道的串口通信。
******************************************/
/******************* IO配置函数 *******************/
void GPIO_config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P3,&GPIO_InitStructure); //初始化
}
/*************** 串口初始化函数 *****************/
void UART_config(void)
{
COMx_InitDefine COMx_InitStructure; //结构定义
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer1; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
UART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
UART1_SW(UART1_SW_P30_P31); //UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}
/**********************************************/
void main(void)
{
// EAXSFR(); /* 扩展寄存器访问使能 */
GPIO_config();
UART_config();
EA = 1;
TX1_write2buff(0x23); // #
printf("STC8H8K64U UART1 Test Programme!\r\n"); //UART1发送一个字符串
PrintString1("STC8H8K64U UART1 Test Programme!\r\n"); //UART1发送一个字符串
while (1)
{
TX1_write2buff(0x2F); // /
delay_ms(250);
delay_ms(250);
delay_ms(250);
delay_ms(250);
}
}
代码编写(接收并回写)
#include "Config.h"
#include "GPIO.h"
#include "UART.h"
#include "Delay.h"
#include "NVIC.h"
#include "Switch.h"
void GPIO_config(void) {
GPIO_InitTypeDef GPIO_InitStructure; //结构定义
GPIO_InitStructure.Pin = GPIO_Pin_0 | GPIO_Pin_1; //指定要初始化的IO, P30, P31
GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);//初始化
}
void UART_config(void) {
COMx_InitDefine COMx_InitStructure; //结构定义
COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
COMx_InitStructure.UART_BRT_Use = BRT_Timer1; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
UART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
UART1_SW(UART1_SW_P30_P31); //UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}
void on_uart1_recv() {
u8 i;
// RX_Cnt收到的数据个数(字节u8 - unsigned char)
// 将收到的数据, 按字节逐个循环
for(i=0; i<COM1.RX_Cnt; i++) {
u8 dat = RX1_Buffer[i]; // 1 1 1 1 0 0 0 0 -> 0xF0
TX1_write2buff(dat); //收到的数据原样返回
}
}
/**
开启串口调试,接收数据,把收到的数据原样返回
**/
void main() {
// 初始化IO
GPIO_config();
// 初始化UART
UART_config();
// 开启中断(全局)必须要写!
EA = 1;
// 写一个字节
TX1_write2buff(0x23);
// 通过PrintString1输出字符串
PrintString1("STC8H8K64U UART1 Test Programme!\r\n"); //UART1发送一个字符串
// 通过printf输出字符串
printf("STC8H8K64U UART1 Test Programme!\r\n"); //UART1发送一个字符串
while(1) {
// 超时计数
// 一旦收到了一个字节数据,RX_TimeOut会初始化一个值(例如:5)
if((COM1.RX_TimeOut > 0) && (--COM1.RX_TimeOut == 0))
{
if(COM1.RX_Cnt > 0)
{
// 收到数据了,on_uart1_recv();
on_uart1_recv();
}
// 处理完数据,将数据个数清零
COM1.RX_Cnt = 0;
}
// 注意这里delay代码的位置,属于while
delay_ms(10);
}
}
调试
使用STC-ISP
调试工具进行调试。切换好串口助手,选择正确的串口,设置和代码中相同的波特率。
通过发送区进行数据发送,通过接收区观察接收内容。
串口调试重难点
功能配置
- 配置IO的工作模式:如果不配置工作模式,会导致串口不工作。(UART1的当前代码中的引脚
P3.0
和P3.1
默认是准双向口,可以不配置,但是不要存在侥幸心理,导致其他的串口使用中没有配置准双向口) - 配置UART的串口工作模式
UART_Mode
:
-
UART_ShiftRight
同步移位输出:按位传输,效率低,通常不用。UART_8bit_BRTx
8位数据,可变波特率:常用。发送和接收的数据为8位。UART_9bit
9位数据,固定波特率,即无法在运行时动态更改波特率。UART_9bit_BRTx
9位数据,可变波特率:发送和接收的数据为9位。最后一位为奇偶校验位。
- 配置UART的波特率
RaudRate
:根据实际情况来定,波特率越高,传输越快,但是出现丢帧的概率越高。通常115200
就够用。单位是bit/s
- 配置UART的波特率发生器
BRT_Use
:系统提供了4个发生器,通常一一对应。
-
BRT_Timer1
BRT_Timer2
BRT_Timer3
BRT_Timer4
- 配置UART是否接收
RxEnable
:可以获取RXD接收的数据。 - 配置UART波特率加倍
BaudRateDouble
:默认不加倍,配置加倍会导致波特率是设定的双倍,过高会导致丢帧。 - 配置UART中断
Interrupt
和优先级Priority
:UART的数据收发是通过中断实现的,如果不配置,则无法对外发送数据,TXD和RXD不工作。 - 配置UART的端口
P_SW
:串口通道可以通过几组引脚来实现,但是需要指明是哪一组。
中断开启
由于uart中的发送是通过中断实现的,需要开启,但是STC8还提供了一个总的开关,如果总开关不打开,一样不起作用。
EA = 1;
UART的接收与发送
关于接收
接收是通过接收缓冲区进行接收。
在死循环中,间隔一定时间到缓冲区中去取数据,有数据,说明就是接收了
关于发送
发送是通过发送缓冲区进行发送。
发送提供了单个字节发送的API:
TX1_write2buff(byte)
发送提供了字符串发送的API:
PrintString1(str)