大彩串口屏与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
    含义 帧头 指令 指令参数 帧尾

    真实切屏指令;

    读取文本控件后单片机获取的指令:

    1.2 硬件连接与程序下载

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

    2 串口屏例程移植到STM32G070CBT6

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

    打开cubemx后,选择STM32G070CBT6作为主控,串口配置如下,注意波特率要跟串口屏中的波特率一致,这里设置为119200,串口屏的也为119200
    同时必须勾选上中断:

    此处可设置中断的优先级,这里设置成1。

    这里还配置了一个PC13引脚,用来控制led灯的闪烁。
    之后就可以配置生成代码:

    2.2 大彩demo程序移植

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


    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 <stdio.h>
    					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,用文本模式接收

    3 总结

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

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

    物联沃分享整理
    物联沃-IOTWORD物联网 » 大彩串口屏与STM32G070CBT6通讯调试指南

    发表评论