大彩串口屏与STM32G070CBT6通讯调试

大彩串口屏与STM32G070CBT6通讯调试

  • 1 大彩串口屏
    • 1.1 指令格式和指令集
    • 1.2 硬件连接与程序下载
  • 2 串口屏例程移植到STM32G070CBT6
    • 2.1 STM32CubeMX生成基于STM32G070CBT6的Hall库程序
    • 2.2 大彩demo程序移植
  • 3 总结

本文主要讲解如何将大彩提供的DEMO移植到自己项目的工程文件中。首先通过STM32CubeMX生成基于STM32G070CBT6的Hall库程序;然后将大彩的程序移植到生成的Hall库程序中。

1 大彩串口屏

对串口屏基本功能不作过多介绍。主要讲解一下指令格式和硬件连接。

1.1 指令格式和指令集

对串口屏基本功能不作过多介绍。主要讲解一下指令格式和指令集。
一条完整的无 CRC 校验指令帧格式如表所示。具体指令集解析可看官方大彩串口屏指令集。链接: link

指令 EE XX XX XX… FF FC FF FF
含义 帧头 指令 指令参数 帧尾

真实切屏指令;
大彩串口屏与STM32G070CBT6通讯调试_第1张图片

读取文本控件后单片机获取的指令:
大彩串口屏与STM32G070CBT6通讯调试_第2张图片

1.2 硬件连接与程序下载

大彩屏与单片机硬件接线图如下。在 VisualTFT中设计好界面,编译通过后,可通过USB转串口将程序下载至串口屏,接线参考如下。如果不确定一开始串口屏中程序的波特率,可通过VisualTFT联机设备查看一开始串口屏中的波特率。

大彩串口屏与STM32G070CBT6通讯调试_第3张图片

2 串口屏例程移植到STM32G070CBT6

2.1 STM32CubeMX生成基于STM32G070CBT6的Hall库程序

打开cubemx后,选择STM32G070CBT6作为主控,串口配置如下,注意波特率要跟串口屏中的波特率一致,这里设置为119200,串口屏的也为119200大彩串口屏与STM32G070CBT6通讯调试_第4张图片
同时必须勾选上中断:
大彩串口屏与STM32G070CBT6通讯调试_第5张图片
此处可设置中断的优先级,这里设置成1。
大彩串口屏与STM32G070CBT6通讯调试_第6张图片
这里还配置了一个PC13引脚,用来控制led灯的闪烁。
之后就可以配置生成代码:
大彩串口屏与STM32G070CBT6通讯调试_第7张图片

2.2 大彩demo程序移植

先到大彩官网去下载对应的例程。本文选择的是如下例程做的移植。

大彩串口屏与STM32G070CBT6通讯调试_第8张图片
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"注释掉。
大彩串口屏与STM32G070CBT6通讯调试_第9张图片
3、将hmi_driver.h中的#include "hmi_user_uart.h"改为自己的#include “usart.h”(如果用cubemx生成的代码,就是改成usart.h这个头文件)。
大彩串口屏与STM32G070CBT6通讯调试_第10张图片
接着,找到官方程序里的hmi_user_uart.h头文件。首先#include "stm32f10x_it.h" 不需要;接着将里面的宏定义全部复制到#include "usart.h"(自己的串口头文件);然后串口初始化函数也不需要(hall会自己生成初始化函数,要改波特率直接在里面改就行了);最后void SendChar(uchar t);这个函数要移植到自己的串口文件。
大彩串口屏与STM32G070CBT6通讯调试_第11张图片
这里注重讲一下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文件中。
大彩串口屏与STM32G070CBT6通讯调试_第12张图片
大彩串口屏与STM32G070CBT6通讯调试_第13张图片

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函数中加入自己的代码了。至此应该可以正常通讯了。
大彩串口屏与STM32G070CBT6通讯调试_第14张图片
在开始必须 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位的变量高低八位互换了一下位置。所以重新加了一个函数,交换高低位位置。改了以后就没有问题了。
大彩串口屏与STM32G070CBT6通讯调试_第15张图片
其中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,用文本模式接收
大彩串口屏与STM32G070CBT6通讯调试_第16张图片

3 总结

本次调试的一般流程如下。
1、首先通过VisualTFT联机设备,确定串口屏有无问题,并把官方的串口屏程序通过串口下载进去。下载完成以后,可以通过电脑的串口助手接收串口屏发送来的指令格式是否正确。注意波特率要一致。
2、使用cubemx生成代码,生成后首先验证单片机的串口是否能正常通信,这里可参考链接: link ,单片机通过USB转串口连接电脑,电脑上的串口助手发给单片机什么数据,单片机就返回什么数据。
3、根据移植步骤移植大彩提供的demo到自己的项目里。通讯不上的话,一般是串口中断那块代码有问题:程序一开始没有打开串口接收中断;在回调函数中写压指令函数,还有回调函数中必须重新开启中断;这里指令处理函数ProcessMessage中的PTR2U16(&msg->screen_id);PTR2U16(&msg->control_id); 会跳入死循环,暂时不知道原因,重写一下交换高低位函数就好了。

以上是一些我的调试过程与总结,水平有限,如有错误,希望大家指正。

你可能感兴趣的:(stm32,单片机,嵌入式硬件)