1. 电脑串口调试乐升串口屏
2. STM32程序配置
2.1. CRC计算处理
2.2. UART串口配置
2.3. 主函数编写进行指令传输
2.4. 串口通讯连接
3. 串口调试工具(UI_Debugger-II)使用说明
3.1. 软件主界面
3.1.1. 指令编辑区
3.1.2. 信息区
3.1.3. 功能区
3.1.4. 配置信息区
3.1.5. 循环配置区
3.1.6. 信息操作区
3.1.7. 指令行处右键呼出菜单项
3.1.8. 在 Select 列右键点击可以全选或全不选指令,如下图
3.2. 指令发送使用教程
3.2.1. 发送单条指令
3.2.2. 一次发送多条指令与循环发送指令
3.3. 指令文档说明
3.4. 指令信息文档说明
通过串口助手和串口转USB模块可以实现电脑对乐升串口屏的串口调试。首先需要将串口转USB模块的RXD和TXD引脚同串口屏的RXD和TXD引脚交叉相连,GND与GND连接形成共地。将串口转USB模块插入电脑USB口(需要提前安装串口转USB模块的相应驱动,具体请自行咨询购买商家或厂家)。打开串口调试助手,识别到串口接入的COM口后选择对应COM口,波特率改为115200,打开串口,选择16进制显示和16进制发送。在下方窗口输入串口指令即可对串口屏进行调试,上方大窗口为串口屏反馈内容。
具体设置如图所示:
接下来演示通过串口调试助手进行串口屏切页操作,选择切页到第2页,串口指令为5a a5 07 10 70 00 00 02 7e c2,输入指令框后点击右侧发送图标,串口屏成功接收传回反馈,如下图所示:
选择切页到第1页,串口指令为5a a5 07 10 70 00 00 01 3e c3,输入指令框后点击右侧发送图标,串口屏成功接收传回反馈,如下图所示:
注意:具体指令内容可到 串口调试工具(UI_Debugger-II)使用说明中查看
STM32F103系列MCU和乐升串口屏可以通过串口指令进行交互,下面演示如何进行代码编写实现串口屏的切页操作。
通过 UI_Debugger 指令文档得到切页指令为 0x10 0x7000 0xXXXX,其中0x10为CMD写指令,0x7000为变量地址,代码中赋值给数组时需拆分为高位0x70和低位0x00,0xXXXX为切页的页数,如切页到第一页为0x0001,代码中赋值时也需要拆分为0x00和0x01。
代码中给数组赋值切页指令时,数组组合顺序为:
帧头:0xXXXX (2 byte)
长度:0xXX (1 byte)
CMD指令:0xXX (1 byte)
变量地址:0x0000 ~ 0x5FFF (2 byte)
写入内容:0xXXXX (2*n byte)
CRC校验:0xXXXX (2 byte)
长度根据CMD指令到CRC校验的长度确认。注意,对于串口写数据指令,单次发送的数据最多为 250 Bytes.
CRC校验的计算代码如下:
#include "stm32f10x.h" // Device header
/*****************************CRC 校验*****************************/
//高位字节的 CRC 值
const uint8_t auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40};
//低位字节的 CRC 值
const char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40};
unsigned short CRC16(uint8_t *puchMsg,uint16_t usDataLen)
/* 函数以 unsigned short 类型返回 CRC */
{
uint8_t uchCRCHi = 0xFF ; /* CRC 的高字节初始化 */
uint8_t uchCRCLo = 0xFF ; /* CRC 的低字节初始化 */
uint16_t uIndex ; /* CRC 查询表索引 */
while (usDataLen--) /* 完成整个报文缓冲区 */
{
uIndex = uchCRCLo ^ *puchMsg++ ; /* 计算 CRC */
uchCRCLo = uchCRCHi ^ auchCRCHi[uIndex] ;
uchCRCHi = auchCRCLo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo);
演示使用的MCU型号为STM32F103RCT6,通过数据手册得到STM32F103RCT6的PA9、PA10引脚分别为USART1_TX和USART1_RX引脚。本次演示只进行写指令操作因此只需要使用PA9引脚与串口屏的RXD1引脚进行连接即可实现切页操作。
UART串口输出配置如下:
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
void Uart_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
uint16_t UART_SendByte(uint8_t Byte)
{
USART_SendData(USART1, Byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
uint16_t UART_SendData(uint8_t *send_buf, uint16_t Length)
{
uint16_t ret;
uint32_t i;
for (i = 0; i < Length; i ++)
{
ret = UART_SendByte(send_buf[i]);
}
return ret;
}
主函数编写如下:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Uart.h"
#include "CRC.h"
uint8_t SCI_C0 = 0x5A;
uint8_t SCI_C1 = 0xA5;
uint8_t uart_data_buf[256];
uint8_t len;
uint8_t CRC_Enable_Flag = 1;
uint8_t CRC_Feedback_Flag = 1;
void LT_SendData_CRC_Frame(uint8_t *buf, uint8_t len1) //len1为CMD、变量地址和写入内容三者的长度之和
{
uint16_t TxToPc_crc;
uint8_t crc[2] = {0};
*(buf + 0) = SCI_C0;
*(buf + 1) = SCI_C1;
if (CRC_Enable_Flag)
{
TxToPc_crc = CRC16(buf + 3, len1);
crc[0] = (uint8_t)(TxToPc_crc & 0x00ff);
crc[1] = (uint8_t)((TxToPc_crc >> 8) & 0x00ff);
len1 += 2;
*(buf + len1 + 1) = crc[0];
*(buf + len1 + 2) = crc[1];
}
*(buf + 2) = len1;
len = len1 + 3;
}
int main()
{
Uart_Init();
uint16_t ret;
uint8_t cmd = 0x10;
uart_data_buf[3] = cmd;
uart_data_buf[4] = 0x70;
uart_data_buf[5] = 0x00;
uart_data_buf[6] = 0x00;
uart_data_buf[7] = 0x01;
while (1)
{
LT_SendData_CRC_Frame(uart_data_buf, 5);
ret = UART_SendData(uart_data_buf, len);
Delay_ms(1000);
}
}
指令的填写在主函数进行,下图所示依次分别为帧头(0x5A,0xA5)、放置指令的数组、指令长度(len)、cmd指令、变量地址(0x7000)、写入数据(0x0001).
此处演示为切页到页面1(0x0001),可根据需要自行修改。
MCU与串口屏的连接需要将两边的 TXD 和 RXD 引脚交替链接,GND互连共地。
串口调试工具UI_Debugger 必须使用 UI_Editor-II 压缩包解压出来的,位于软件目录下。
打开软件后,其主界面如下图所示。具体软件版本以下载到的软件为主。软件主界面主要包括以下内容:
Description:描述项,可在此处添加关于指令的描述。
Select:勾选项,勾选后的指令可以进行 Send All、Star Loop 操作。
CMD:指令项,10 表示写入数据、03 表示读取数据,长度为 1 Byte。
Addr:地址项,目的变量地址,即对该地址读或者写。长度 2 Bytes。
Data:数据项,需要写入的数据或者是操作的参数。长度是 2*n Bytes。
CRC:校验码项,用于检验数据。长度 2 Bytes。(填写指令项、地址项和数据项后自动生成)。
Send:发送按钮,点击发送此行的指令。
收发指令都可以在此查看。黑色指令为发送出的指令,蓝色指令为接收到的指令。
NO:信息排序。
Header:帧头项。长度 2 Bytes。
Length:长度项,指令长度。长度 2 Bytes。
CMD:指令标志项。长度为 1 Byte。
Addr:目标地址。
Data:数据项,返回数据。长度是 2*n Bytes。若是上面发的是写指令则返回的数据为 0xFF,
若上面发 的是读指令,则读反馈指令数据为 0xFF,读指令返回指令的数据为读指令的所需要的数据长度+变量地址 对应的数据。
CRC:校验码项,用于检验数据。长度 2 Bytes。
从左到右分别为,
Com Port:选择通信端口。
Baudrate:选择波特率,需要与工程设置的波特率对应,支持用户自定义波特率,如下图,选择 custom 选项可以填写用户自定义波特率。
Parity:奇偶校验,需要与工程设置的 Parity 相同。
CRC Enable:是否进行 CRC 校验,若工程勾选 No CRC,此处不用勾选。
CMD Header:通信帧头,需要与工程设置的 User Start Bytes 相同。
Open Com Port:开启端口。开启端口后才能发送指令。
Send selected items:按照从上到下的顺序发送全部 select 项已勾选的指令
Cycle Delay:循环发送时每次循环之间的时间间隔。
Interval Time:循环时相邻指令之间发送的时间间隔。
Auto Send:按照从上到下的顺序循环发送全部 select 项已勾选的指令。
Clear Message:清空信息接收区的信息。
Save Message:保存信息接收区的信息为 txt 文档。
insert:在所选指令行上方插入一行空白的指令行。
clone:在选中指令行的下方克隆一行选中的指令。
delete:删除所选指令行。
up:将所选指令行上移。
down:将所选指令行下移。
Delay:在所选指令行上方插入发送延时行(时间单位为 ms)。
其步骤如下:
(1)配置信息,选择对应端口、对应的波特率以及奇偶校验,确定帧头对应,勾选 CRC Enable,然后打开端口(Open Com Port)。
(2)添加指令,双击指令行的单元格,对指令进行编辑。或点击右上角的载入已有的指令 txt 文件。
(3)发送指令,单击发送,即可发送单条指令。
(4)随后可在信息区获取到发送与接收指令的信息。
其步骤如下:
(1)右键调整指令上下位置(指令是按从上到下的顺序发送的)。
(2)在 Select 项勾选所要发送的指令。
(3)点击 Send selected items 或 Auto Send,即可一次发送多条指令与循环发送指令。
(4)若要调整循环发送的时间间隔,可调整 Circle Delay 与 interval。
(5)在 loop 模式下,可以自定义添加 delay 时间,其中++为 delay 标志(不可修改),可在 data 栏添加间隔时间(ms),希望启用该延时需勾选该行的 select 项。
延时时间为 10 进制,单位为 ms。延时指令只由指令标志 “++” 和延时时间组成,其他部分不需要填写。延时指令穿插在两条正常指令之间,延时时间 + Interval Time 是两条指令之间的发送间隔。
指令在指令文档内的格式如下表,可以在 UI_Debugger-II 内编辑后导出,也该指令可以在 txt 文档手动编辑, 需注意编辑指令文档时不可留下空白行。指令示例如下:
点击 Save Message 可将信息区的指令收发记录保存为 txt 文档,文档内的指令均为完整指令,包括帧头、长度等部分。注意该文档不能重新导入 UI_Debugger-II 。文档内容示例如下: