对串口屏基本功能不作过多介绍。主要讲解一下指令格式和硬件连接。
对串口屏基本功能不作过多介绍。主要讲解一下指令格式和指令集。
一条完整的无 CRC 校验指令帧格式如表所示。具体指令集解析可看官方大彩串口屏指令集。链接: link
指令 | EE | XX | XX XX… | FF FC FF FF |
---|---|---|---|---|
含义 | 帧头 | 指令 | 指令参数 | 帧尾 |
大彩屏与单片机硬件接线图如下。在 VisualTFT中设计好界面,编译通过后,可通过USB转串口将程序下载至串口屏,接线参考如下。如果不确定一开始串口屏中程序的波特率,可通过VisualTFT联机设备查看一开始串口屏中的波特率。
打开cubemx后,选择STM32G070CBT6作为主控,串口配置如下,注意波特率要跟串口屏中的波特率一致,这里设置为119200,串口屏的也为119200:
同时必须勾选上中断:
此处可设置中断的优先级,这里设置成1。
这里还配置了一个PC13引脚,用来控制led灯的闪烁。
之后就可以配置生成代码:
先到大彩官网去下载对应的例程。本文选择的是如下例程做的移植。
1、首先将STM32_KEIL5\STM32\DCDEMO7\src里面的**cmd_queue.c、hmi_driver.c**
两个.c文件复制到proj1\Core\Src中(这里的pro1是我配置cubemx的时候设置的项目名称Project Name,看自己设置的名称)。然后再打开STM32_KEIL5\STM32\DCDEMO7\inc,把**cmd_process.h、cmd_queue.h、hmi_driver.h,**
三个头文件复制到proj1\Core\Inc中。
具体操作也可参看链接: link
这个博主写得很详细,是基于STM32F407。本文这部分是参考了这一篇。
2、把cmd_queue.c中的#include "ulitity.h"注释掉。
3、将hmi_driver.h中的#include "hmi_user_uart.h"改为自己的#include “usart.h”(如果用cubemx生成的代码,就是改成usart.h这个头文件)。
接着,找到官方程序里的hmi_user_uart.h
头文件。首先#include "stm32f10x_it.h"
不需要;接着将里面的宏定义全部复制到#include "usart.h"
(自己的串口头文件);然后串口初始化函数也不需要(hall会自己生成初始化函数,要改波特率直接在里面改就行了);最后void SendChar(uchar t);
这个函数要移植到自己的串口文件。
这里注重讲一下SendChar
这和函数,在自己项目usart.c
文件中定义代码如下:
/*!
* \brief 发送1个字节
* \param t 发送的字节
*/
void SendChar(uint8_t t)
{
HAL_UART_Transmit(&huart2,&t,1, 20);
while(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_TC)!=SET);//等待发送结束
}
接着在usart.h头文件中声明一下这个函数:void SendChar(uint8_t t);
4、最后是main.c
头文件的修改。要把例程里main.c的头文件,变量,函数等复制过来。头文件只需要复制三个(#include "hmi_driver.h",#include "cmd_queue.h",#include "cmd_process.h"
);变量声明全部复制;最后函数则图上的位置开始,一直复制到main.c
的最后。把这些复制到自己的main.c
文件中。
5、如果要正常接受到串口屏发来的指令,必须重新写一下串口的回调函数(注意要把cubemx自动生成的回调函数注释掉-在proj1\Drivers\STM32G0xx_HAL_Driver\Src\stm32g0xx_hal_uart.c文件中,搜索HAL_UART_RxCpltCallback)。
在main.c中重定义如下:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback can be implemented in the user file.
*/
if(huart->Instance==USART2)
{
queue_push(uart2_rx_buf);
HAL_UART_Receive_IT(&huart2,&uart2_rx_buf, 1);
}
}
**其中uart2_rx_buf定义在usart.c中uint8_t uart2_rx_buf;
,在usart.h中extern uint8_t uart2_rx_buf;
6、最后可在main函数中加入自己的代码了。至此应该可以正常通讯了。
在开始必须 HAL_UART_Receive_IT(&huart2,&uart2_rx_buf, 1);
开启中断,并且在回调函数里重新开启。
ps:在调试的时候发现进入ProcessMessage( PCTRL_MSG msg, uint16 size )
函数里后,处理uint16 screen_id = PTR2U16(&msg->screen_id);
这条语句发现会卡死,原因还没有弄清楚。这条语句的作用是将画面ID这个16位的变量高低八位互换了一下位置。所以重新加了一个函数,交换高低位位置。改了以后就没有问题了。
其中Convert函数为16位的高低八位互换函数,用移位计算实现,(引用链接: link)具体代码如下:
unsigned short Convert(unsigned short s) {
char right, left;
right = s& 0XFF;//低八位
left = s >> 8;//高八位 右移8位
s = right * 256 + left;
return s;
}
7、在这里我们还将数据通过另一个串口,即串口1,发送到电脑串口调试工具上显示。硬件接线就是单片机通过一个usb转串口与电脑相连。这里只对屏幕界面切换,和画面ID4中文本控件某个数值做响应,在电脑调试工具中显示对触摸屏做的改变。
首先在void NotifyText(uint16 screen_id, uint16 control_id, uint8 *str)
函数中加入代码如下,实现最高电压value的值发给电脑:
void NotifyText(uint16 screen_id, uint16 control_id, uint8 *str)
{
if(screen_id==4) //画面ID2:文本设置和显示
{
int32 value=0;
sscanf(str,"%ld",&value); //把字符串转换为整数
if(control_id==2) //最高电压
{
//限定数值范围(也可以在文本控件属性中设置)
if(value<0)
{
value = 0;
}
else if(value>380)
{
value = 380;
}
SetTextInt32(4,2,value,0,1); //更新最高电压
SetTextInt32(4,5,value/2,1,1); //更新最高电压/2
//下面就是加入的代码
sprintf(tx_buffer,"value = %ld ",value);//把最高电压value的值,通过sprintf函数放在tx_buffer中。要包含头文件:#include
HAL_UART_Transmit(&huart1,(uint8_t*)tx_buffer,sizeof(tx_buffer), 20);//通过串口1把数据发送出去
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);//等待发送结束
}
}
}
在画面切换调动的函数NotifyScreen(screen_id);
中加入代码,实现切屏信息发送给串口助手。
//进入音乐画面自动播放
if(current_screen_id == 17)
{
uint8 buffer[6] = {0x90,0x01 ,0x00 ,0x01 ,0x01};
SetButtonValue(17,3,1);
PlayMusic(buffer); //播放音乐
}
**//就在这个函数最后,加入的代码**
sprintf(tx_buffer,"current_screen_id = %d ",current_screen_id);
HAL_UART_Transmit(&huart1,(uint8_t*)tx_buffer,sizeof(tx_buffer), 20);
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET);
//
}
效果如下,此处串口1波特率设置的是115200,用文本模式接收:
本次调试的一般流程如下。
1、首先通过VisualTFT联机设备,确定串口屏有无问题,并把官方的串口屏程序通过串口下载进去。下载完成以后,可以通过电脑的串口助手接收串口屏发送来的指令格式是否正确。注意波特率要一致。
2、使用cubemx生成代码,生成后首先验证单片机的串口是否能正常通信,这里可参考链接: link ,单片机通过USB转串口连接电脑,电脑上的串口助手发给单片机什么数据,单片机就返回什么数据。
3、根据移植步骤移植大彩提供的demo到自己的项目里。通讯不上的话,一般是串口中断那块代码有问题:程序一开始没有打开串口接收中断;在回调函数中写压指令函数,还有回调函数中必须重新开启中断;这里指令处理函数ProcessMessage
中的PTR2U16(&msg->screen_id);
和PTR2U16(&msg->control_id);
会跳入死循环,暂时不知道原因,重写一下交换高低位函数就好了。
以上是一些我的调试过程与总结,水平有限,如有错误,希望大家指正。