如何利用STM32和迪文串口屏以及WIFI模组进行数据交互

Posted 三明治开发社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何利用STM32和迪文串口屏以及WIFI模组进行数据交互相关的知识,希望对你有一定的参考价值。

简介:本文将通过介绍如何实现屏和App实时显示温湿度和光照度采集数据,以及通过控制屏和App去控制GPIO口电平翻转来带大家了解STM32和迪文串口屏以及Wi-Fi模组进行数据交互。

程序下载路径:demo程序

一.迪文屏简介

显示控制部分采用的是迪文的4.3寸串口屏。

  • 正面图:

  • 背面图:

  • 接口图:

此次设计中界面设计的界面效果如下图:

  • 温湿度界面效果展示:

  • 光照度界面效果展示:

  • 控制界面效果展示:

MCU和显示屏通过串口通信,来实现控制和显示。

二.迪文屏界面和程序设计

STM32通过串口1和迪文屏进行通信,波特率115200。

1.界面设计

首先采用PS软件做出自己需要的图片,然后保存成800*480分辨率的BMP图片格式。接着采用迪文的一款上位机软件进行显示和控制设计。如何设计参考

迪文官方资料《T5L DGUSII 应用开发指南》。

  • 温湿度界面:

  • 光照度界面:

  • 节点控制界面:

控制屏界面设计完整工程:点此下载

2.驱动程序设计

  • 调用WriteDataToLCD对串口屏写入数据:
/*******************************************************************************
** Function Name  :void WriteDataToLCD(uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length)
** Description    : 数据写入触摸屏变量寄存器
** Input          : uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length
** Output         : None
** Return         : None
** Attention            : 
*******************************************************************************/
void WriteDataToLCD(uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length)
{
  /*命令的长度由帧头(2个字节)+数据长度(1个字节)+指令(1个字节)+起始地址(2个字节)+数据(长度为length)*/
    uint8_t i;
    usart1_txBuf[0]=0x5a;
    usart1_txBuf[1]=0xa5;
    usart1_txBuf[2]=length+3;
    usart1_txBuf[3]=0x82;
    usart1_txBuf[4]=(uint8_t)((startAddress>>8)&0xff);//起始地址
    usart1_txBuf[5]=(uint8_t)(startAddress&0XFF);//起始地址
    for(i=0;i<length;i++)
    {
        usart1_txBuf[i+6]=((SEND_BUF[i+return_data_start_addr]));
    }
    HAL_UART_Transmit(&huart1, usart1_txBuf, length+6, 20);
}
  • 调用ReadDataFromLCD读取串口屏数据:
/*******************************************************************************
** Function Name  :void ReadDataFromLCD(uint16_t startAddress,uint8_t readWordLength)
** Description    : 读变量存储器数据
** Input          : uint16_t startAddress,uint8_t readWordLength
** Output         : None
** Return         : None
** Attention            : 
*******************************************************************************/
void ReadDataFromLCD(uint16_t startAddress,uint16_t readWordLength)
{
  //命令的长度由帧头(2个字节)+数据长度(1个字节)+指令(1个字节)+起始地址(2个字节)+读取的字长度(1个字节)
    usart1_txBuf[0]=0x5a;
    usart1_txBuf[1]=0xa5;
    usart1_txBuf[2]=0x04;
    usart1_txBuf[3]=0x83;
    usart1_txBuf[4]=(uint8_t)((startAddress>>8)&0xff);//起始地址
    usart1_txBuf[5]=(uint8_t)(startAddress&0xff);//起始地址
    usart1_txBuf[6]=readWordLength;//读取长度
​
    HAL_UART_Transmit(&huart1, usart1_txBuf, 7 , 20);
}
  • 调用void send_tz控制页面跳转:
  • /*******************************************************************************
    ** Function Name  :void send_tz(void))
    ** Description    : 跳转页面函数
    ** Input          : None
    ** Output         : None
    ** Return         : None
    ** Attention            : 
    *******************************************************************************/
    void send_tz(void)
    {
        uint8_t i;
        usart1_txBuf[0]=0x5a;
        usart1_txBuf[1]=0xa5;
        usart1_txBuf[2]=0x07;
        usart1_txBuf[3]=0x82;
        usart1_txBuf[4]=0x00;
        usart1_txBuf[5]=0x84;
        usart1_txBuf[6]=0x5a;
        usart1_txBuf[7]=0x01;
        for(i=0;i<2;i++)
        {
            usart1_txBuf[i+8]=((SEND_BUF[i]));
        }
        HAL_UART_Transmit(&huart1, usart1_txBuf, 10, 20);
    }
    ​

3.STM32和串口屏进行通信

(1)功能函数介绍

  • 串口屏和APP显示:

单片机读取温湿度和光照度数据之后,把数据送到串口屏和APP,APP和串口屏实时显示这些传感器的数据。

void Deal_Data_Display(void)
{
  uint8_t i;
  uint16_t  light;
  double Tem_val,Hum_val;
  uint8_t dat[2] = {0}; 
  uint8_t Buffer[30]={0};   
  
​
      HAL_Delay(1000);
    if(SHT3x_Get_Humiture_periodic(&Tem_val,&Hum_val) == 0)
            {
                memcpy(Buffer,(double*)(&Tem_val),8);       
                memcpy(Buffer+8,(double*)(&Hum_val),8);
       for(i=0;i<8;i++)
          {
              SEND_BUF[i] = Buffer[7-i];     
          }
            WriteDataToLCD(0X1110,0,8);
           for(i=0;i<8;i++)
          {
              SEND_BUF[i] = Buffer[15-i];    
          }
              WriteDataToLCD(0X1118,0,8);
                
                mcu_dp_value_update(DPID_TEMPERATURE,Tem_val*100); //温度数据上报;
                mcu_dp_value_update(DPID_HUMIDITY,Hum_val*100);    //湿度数据上报;
                printf("temperature=%6.2lf,humidity=%6.2lf\\r\\n",Tem_val,Hum_val);       
            }
        else
            printf("Get_Humiture ERR\\r\\n");
        
              HAL_Delay(180);
        if(HAL_OK == BH1750_Read_Dat(dat))
        {
                      light=BH1750_Dat_To_Lx(dat);
                      memcpy(Buffer+16, (uint16_t*)(&light), sizeof((uint16_t*)(&light)));
                     for(i=0;i<2;i++)
              {
                 SEND_BUF[i] = Buffer[17-i];     
              }
                      WriteDataToLCD(0X1120,0,2);
              delay_ms(5);
            printf("illuminance: %5d lx\\r\\n", light);
                      mcu_dp_value_update(DPID_ILLUMINANCE,light*100); //光照度数据上报;        
        }
        else
        {
            printf("recv fail");
        }  
}
​
  • 串口屏控制GPIO口电平:

在串口1中断处理函数中对IO电平进行翻转,大家可以把这个函数重新写,尽量不要在中断处理函数中处理较多的数据。

void USART1_IRQHandler(void)
{
    uint8_t usart1_data;
    uint8_t send[2]={0x5a,0xa5};
    uint16_t addr=0,data=0;//定义地址及数据
    //uint16_t len=0;       //定义长度 
  uint8_t usart1_counter=0;
  if((USART1->ISR & 1<<5) == 1<<5)//接收寄存器数据不为空
    {
        usart1_data=USART1->RDR;
    usart1_rxBuf[usart1_counter] = usart1_data; 
    if(usart1_counter < 2)
    {   
        if(usart1_rxBuf[usart1_counter]==send[usart1_counter])
        {
            usart1_counter++;
        }
        else
        {
            usart1_counter=0;
        }
    }
    else
    {
        usart1_counter++;
    }
    if(usart1_counter>=(usart1_rxBuf[2]+3))
    {
            addr = usart1_rxBuf[4]*256+usart1_rxBuf[5];             //获取lcd控件寄存器地址
            //len =  usart1_rxBuf[6];                                                   //获取接收的数据字个数
            data = usart1_rxBuf[7]*256+usart1_rxBuf[8];             //获取第一个字数据的值
        switch(addr)
         {
             case 0x1000:       
                 if(data==0x01)     
                  {
                   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
                  }
                else if(data==0x00)     
                  {
                     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
                  }
                        break;  
       case 0x1001:             
                    if(data==0x01)      
                        {
                         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
                        }
                    else if(data==0x00)
                     {  
                         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);  
                     }  
                break;  
           case 0x1002:             
                    if(data==0x01)      
                    {
                     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
                    }
               else if(data==0x00)
                {   
                    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);   
                }       
                break;  
            case 0x1003:                
                    if(data==0x01)      
                    {
                     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
                    }
               else if(data==0x00)
                {   
                    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);   
                }       
                break;  
      default :
                        break;                  
           }
      usart1_counter=0;         
    }
 }
    if((USART1->ISR & (1<<3)) == (1<<3))//ORE
    {
        USART1->ICR =1<<3;
    }
}
  • APP控制:

调用以下DP处理函数,APP对串口屏和GPIO进行控制:

/*****************************************************************************
函数名称 : dp_download_switch_1_handle
功能描述 : 针对DPID_SWITCH_1的处理函数
输入参数 : value:数据源数据
        : length:数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERROR
使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
*****************************************************************************/
static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
{
    //示例:当前DP类型为BOOL
    unsigned char ret;
    //0:关/1:开
    unsigned char switch_1;
    
    switch_1 = mcu_get_dp_download_bool(value,length);
    if(switch_1 == 0)
         {
                //开关关
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
            
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x00; 
                WriteDataToLCD(0x1000,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET); 
        }
        else 
        {
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
​
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x01; 
                WriteDataToLCD(0x1000,0,2);
                HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
               //开关开
      }
  
    //处理完DP数据后应有反馈
    ret = mcu_dp_bool_update(DPID_SWITCH_1,switch_1);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}
/*****************************************************************************
函数名称 : dp_download_switch_2_handle
功能描述 : 针对DPID_SWITCH_2的处理函数
输入参数 : value:数据源数据
        : length:数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERROR
使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
*****************************************************************************/
static unsigned char dp_download_switch_2_handle(const unsigned char value[], unsigned short length)
{
    //示例:当前DP类型为BOOL
    unsigned char ret;
    //0:关/1:开
    unsigned char switch_2;
    
    switch_2 = mcu_get_dp_download_bool(value,length);
    if(switch_2 == 0) {
              
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
​
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x00; 
                WriteDataToLCD(0x1001,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET); 
        //开关关
    }else {
                    
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
                
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x01; 
                WriteDataToLCD(0x1001,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET); 
        //开关开
    }
  
    //处理完DP数据后应有反馈
    ret = mcu_dp_bool_update(DPID_SWITCH_2,switch_2);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}
/*****************************************************************************
函数名称 : dp_download_switch_3_handle
功能描述 : 针对DPID_SWITCH_3的处理函数
输入参数 : value:数据源数据
        : length:数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERROR
使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
*****************************************************************************/
static unsigned char dp_download_switch_3_handle(const unsigned char value[], unsigned short length)
{
    //示例:当前DP类型为BOOL
    unsigned char ret;
    //0:关/1:开
    unsigned char switch_3;
    
    switch_3 = mcu_get_dp_download_bool(value,length);
    if(switch_3 == 0) {
                    
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
                
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x00; 
                WriteDataToLCD(0x1002,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); 
        //开关关
    }else {
            
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
​
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x01; 
                WriteDataToLCD(0x1002,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET); 
        //开关开
    }
  
    //处理完DP数据后应有反馈
    ret = mcu_dp_bool_update(DPID_SWITCH_3,switch_3);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}
/*****************************************************************************
函数名称 : dp_download_switch_4_handle
功能描述 : 针对DPID_SWITCH_4的处理函数
输入参数 : value:数据源数据
        : length:数据长度
返回参数 : 成功返回:SUCCESS/失败返回:ERROR
使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
*****************************************************************************/
static unsigned char dp_download_switch_4_handle(const unsigned char value[], unsigned short length)
{
    //示例:当前DP类型为BOOL
    unsigned char ret;
    //0:关/1:开
    unsigned char switch_4;
    
    switch_4 = mcu_get_dp_download_bool(value,length);
    if(switch_4 == 0) {
               
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
                
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x00; 
                WriteDataToLCD(0x1003,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET); 
        //开关关
    }else {
            
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x06; 
                send_tz();
            
                SEND_BUF[0]=0x00;
                SEND_BUF[1]=0x01; 
                WriteDataToLCD(0x1003,0,2);
              HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET); 
        //开关开
    }
  
    //处理完DP数据后应有反馈
    ret = mcu_dp_bool_update(DPID_SWITCH_4,switch_4);
    if(ret == SUCCESS)
        return SUCCESS;
    else
        return ERROR;
}

(2)主程序设计

主函数循环体中调用联网函数,WIFI串口处理函数,数据显示函数。

int main(void)
{
 
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick.*/
  HAL_Init();
​
  /* Configure the system clock */
  SystemClock_Config();
​
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
    MX_USART3_UART_Init();
    wifi_protocol_init();       //wifi协议初始化
  MX_I2C2_Init();
  MX_I2C1_Init();
    
    MX_TIM3_Init(10000-1,8000-1); //定时器3初始化,定时1s
    
  SHT3x_Reset();
    if( 0 == SHT3x_Init())
        printf("SHT3x_Init OK \\r\\n");
    else
        printf("SHT3x_Init ERR \\r\\n");
    
​
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
          Connect_Wifi();   
            wifi_uart_service();//wifi串口数据处理服务  
        
   if(1 == Display_Flag)
        {
          Deal_Data_Display();  
            Display_Flag=0;
      }         
  }
}

(3)如何降低功耗

可以通过指令对触摸屏进行背光待机控制。详细指令参考《T5L DGUSII 应用开发指南》。

(4)样机实物展示

通过APP和串口屏实时显示温湿度和光照度数据,操作串口屏和APP可以实时控制GPIO的电平翻转。

可以通过APP控制串口屏和GPIO口的电平。

以上是关于如何利用STM32和迪文串口屏以及WIFI模组进行数据交互的主要内容,如果未能解决你的问题,请参考以下文章

stm32如何将4G模块挂载成网卡

如何快速使用STM32 HAL库和涂鸦Wi-Fi模组进行通信

利用WiFi模块对于ESP32开发程序

STM32天气数据获取

LM401STM32WLE5+SPI接口驱动 2.66inch e-paper 墨水屏

物联网无线串口WiFi模块,智能生活无线应用,无线WiFi模组技术