嵌入式技术论坛
直播中

草帽王路飞

4年用户 147经验值
擅长:可编程逻辑 MEMS/传感技术 嵌入式技术 模拟技术 EDA/IC设计 接口/总线/驱动 控制/MCU
私信 关注
[经验]

「必看干货」如何利用STM32和迪文串口屏以及WIFI模组进行数据交互?

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

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

正面图:

背面图:

接口图:

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

温湿度界面效果展示:

光照度界面效果展示:

控制界面效果展示:

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

二.迪文屏界面和程序设计
STM32通过串口1和迪文屏进行通信,波特率115200。

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

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

温湿度界面:


光照度界面:


节点控制界面:


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

2.驱动程序设计
调用WriteDataToLCD对串口屏写入数据:
  1. /*******************************************************************************
  2. ** Function Name  :void WriteDataToLCD(uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length)
  3. ** Description    : 数据写入触摸屏变量寄存器
  4. ** Input          : uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length
  5. ** Output         : None
  6. ** Return         : None
  7. ** Attention            :
  8. *******************************************************************************/
  9. void WriteDataToLCD(uint16_t startAddress,uint16_t return_data_start_addr,uint16_t length)
  10. {
  11.   /*命令的长度由帧头(2个字节)+数据长度(1个字节)+指令(1个字节)+起始地址(2个字节)+数据(长度为length)*/
  12.     uint8_t i;
  13.     usart1_txBuf[0]=0x5a;
  14.     usart1_txBuf[1]=0xa5;
  15.     usart1_txBuf[2]=length+3;
  16.     usart1_txBuf[3]=0x82;
  17.     usart1_txBuf[4]=(uint8_t)((startAddress>>8)&0xff);//起始地址
  18.     usart1_txBuf[5]=(uint8_t)(startAddress&0XFF);//起始地址
  19.     for(i=0;i
  20.     {
  21.         usart1_txBuf[i+6]=((SEND_BUF[i+return_data_start_addr]));
  22.     }
  23.     HAL_UART_Transmit(&huart1, usart1_txBuf, length+6, 20);
  24. }

    • 调用ReadDataFromLCD读取串口屏数据:

    1. /*******************************************************************************
    2. ** Function Name  :void ReadDataFromLCD(uint16_t startAddress,uint8_t readWordLength)
    3. ** Description    : 读变量存储器数据
    4. ** Input          : uint16_t startAddress,uint8_t readWordLength
    5. ** Output         : None
    6. ** Return         : None
    7. ** Attention            :
    8. *******************************************************************************/
    9. void ReadDataFromLCD(uint16_t startAddress,uint16_t readWordLength)
    10. {
    11.   //命令的长度由帧头(2个字节)+数据长度(1个字节)+指令(1个字节)+起始地址(2个字节)+读取的字长度(1个字节)
    12.     usart1_txBuf[0]=0x5a;
    13.     usart1_txBuf[1]=0xa5;
    14.     usart1_txBuf[2]=0x04;
    15.     usart1_txBuf[3]=0x83;
    16.     usart1_txBuf[4]=(uint8_t)((startAddress>>8)&0xff);//起始地址
    17.     usart1_txBuf[5]=(uint8_t)(startAddress&0xff);//起始地址
    18.     usart1_txBuf[6]=readWordLength;//读取长度

    19.     HAL_UART_Transmit(&huart1, usart1_txBuf, 7 , 20);
    20. }
    • 调用void send_tz控制页面跳转:

  1. /*******************************************************************************
  2. ** Function Name  :void send_tz(void))
  3. ** Description    : 跳转页面函数
  4. ** Input          : None
  5. ** Output         : None
  6. ** Return         : None
  7. ** Attention            :
  8. *******************************************************************************/
  9. void send_tz(void)
  10. {
  11.     uint8_t i;
  12.     usart1_txBuf[0]=0x5a;
  13.     usart1_txBuf[1]=0xa5;
  14.     usart1_txBuf[2]=0x07;
  15.     usart1_txBuf[3]=0x82;
  16.     usart1_txBuf[4]=0x00;
  17.     usart1_txBuf[5]=0x84;
  18.     usart1_txBuf[6]=0x5a;
  19.     usart1_txBuf[7]=0x01;
  20.     for(i=0;i<2;i++)
  21.     {
  22.         usart1_txBuf[i+8]=((SEND_BUF[i]));
  23.     }
  24.     HAL_UART_Transmit(&huart1, usart1_txBuf, 10, 20);
  25. }
3.STM32和串口屏进行通信
(1)功能函数介绍
串口屏和APP显示:
单片机读取温湿度和光照度数据之后,把数据送到串口屏和APP,APP和串口屏实时显示这些传感器的数据。
  1. void Deal_Data_Display(void)
  2. {
  3.   uint8_t i;
  4.   uint16_t  light;
  5.   double Tem_val,Hum_val;
  6.   uint8_t dat[2] = {0};
  7.   uint8_t Buffer[30]={0};   
  8.   

  9.       HAL_Delay(1000);
  10.     if(SHT3x_Get_Humiture_periodic(&Tem_val,&Hum_val) == 0)
  11.             {
  12.                 memcpy(Buffer,(double*)(&Tem_val),8);      
  13.                 memcpy(Buffer+8,(double*)(&Hum_val),8);
  14.        for(i=0;i<8;i++)
  15.           {
  16.               SEND_BUF[i] = Buffer[7-i];     
  17.           }
  18.             WriteDataToLCD(0X1110,0,8);
  19.            for(i=0;i<8;i++)
  20.           {
  21.               SEND_BUF[i] = Buffer[15-i];   
  22.           }
  23.               WriteDataToLCD(0X1118,0,8);
  24.                
  25.                 mcu_dp_value_update(DPID_TEMPERATURE,Tem_val*100); //温度数据上报;
  26.                 mcu_dp_value_update(DPID_HUMIDITY,Hum_val*100);    //湿度数据上报;
  27.                 printf("temperature=%6.2lf,humidity=%6.2lfrn",Tem_val,Hum_val);      
  28.             }
  29.         else
  30.             printf("Get_Humiture ERRrn");
  31.         
  32.               HAL_Delay(180);
  33.         if(HAL_OK == BH1750_Read_Dat(dat))
  34.         {
  35.                       light=BH1750_Dat_To_Lx(dat);
  36.                       memcpy(Buffer+16, (uint16_t*)(&light), sizeof((uint16_t*)(&light)));
  37.                      for(i=0;i<2;i++)
  38.               {
  39.                  SEND_BUF[i] = Buffer[17-i];     
  40.               }
  41.                       WriteDataToLCD(0X1120,0,2);
  42.               delay_ms(5);
  43.             printf("illuminance: %5d lxrn", light);
  44.                       mcu_dp_value_update(DPID_ILLUMINANCE,light*100); //光照度数据上报;        
  45.         }
  46.         else
  47.         {
  48.             printf("recv fail");
  49.         }  
  50. }

串口屏控制GPIO口电平:
在串口1中断处理函数中对IO电平进行翻转,大家可以把这个函数重新写,尽量不要在中断处理函数中处理较多的数据。
  1. void USART1_IRQHandler(void)
  2. {
  3.     uint8_t usart1_data;
  4.     uint8_t send[2]={0x5a,0xa5};
  5.     uint16_t addr=0,data=0;//定义地址及数据
  6.     //uint16_t len=0;       //定义长度
  7.   uint8_t usart1_counter=0;
  8.   if((USART1->ISR & 1<<5) == 1<<5)//接收寄存器数据不为空
  9.     {
  10.         usart1_data=USART1->RDR;
  11.     usart1_rxBuf[usart1_counter] = usart1_data;
  12.     if(usart1_counter < 2)
  13.     {   
  14.         if(usart1_rxBuf[usart1_counter]==send[usart1_counter])
  15.         {
  16.             usart1_counter++;
  17.         }
  18.         else
  19.         {
  20.             usart1_counter=0;
  21.         }
  22.     }
  23.     else
  24.     {
  25.         usart1_counter++;
  26.     }
  27.     if(usart1_counter>=(usart1_rxBuf[2]+3))
  28.     {
  29.             addr = usart1_rxBuf[4]*256+usart1_rxBuf[5];             //获取lcd控件寄存器地址
  30.             //len =  usart1_rxBuf[6];                                                   //获取接收的数据字个数
  31.             data = usart1_rxBuf[7]*256+usart1_rxBuf[8];             //获取第一个字数据的值
  32.         switch(addr)
  33.          {
  34.              case 0x1000:      
  35.                  if(data==0x01)     
  36.                   {
  37.                    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
  38.                   }
  39.                 else if(data==0x00)     
  40.                   {
  41.                      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
  42.                   }
  43.                         break;  
  44.        case 0x1001:            
  45.                     if(data==0x01)      
  46.                         {
  47.                          HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
  48.                         }
  49.                     else if(data==0x00)
  50.                      {  
  51.                          HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);  
  52.                      }  
  53.                 break;  
  54.            case 0x1002:            
  55.                     if(data==0x01)      
  56.                     {
  57.                      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  58.                     }
  59.                else if(data==0x00)
  60.                 {   
  61.                     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);   
  62.                 }      
  63.                 break;  
  64.             case 0x1003:               
  65.                     if(data==0x01)      
  66.                     {
  67.                      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
  68.                     }
  69.                else if(data==0x00)
  70.                 {   
  71.                     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);   
  72.                 }      
  73.                 break;  
  74.       default :
  75.                         break;                  
  76.            }
  77.       usart1_counter=0;         
  78.     }
  79. }
  80.     if((USART1->ISR & (1<<3)) == (1<<3))//ORE
  81.     {
  82.         USART1->ICR =1<<3;
  83.     }
  84. }




APP控制:
调用以下DP处理函数,APP对串口屏和GPIO进行控制:
  1. /*****************************************************************************
  2. 函数名称 : dp_download_switch_1_handle
  3. 功能描述 : 针对DPID_SWITCH_1的处理函数
  4. 输入参数 : value:数据源数据
  5.         : length:数据长度
  6. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  7. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  8. *****************************************************************************/
  9. static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
  10. {
  11.     //示例:当前DP类型为BOOL
  12.     unsigned char ret;
  13.     //0:关/1:开
  14.     unsigned char switch_1;
  15.    
  16.     switch_1 = mcu_get_dp_download_bool(value,length);
  17.     if(switch_1 == 0)
  18.          {
  19.                 //开关关
  20.                 SEND_BUF[0]=0x00;
  21.                 SEND_BUF[1]=0x06;
  22.                 send_tz();
  23.             
  24.                 SEND_BUF[0]=0x00;
  25.                 SEND_BUF[1]=0x00;
  26.                 WriteDataToLCD(0x1000,0,2);
  27.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
  28.         }
  29.         else
  30.         {
  31.                 SEND_BUF[0]=0x00;
  32.                 SEND_BUF[1]=0x06;
  33.                 send_tz();

  34.                 SEND_BUF[0]=0x00;
  35.                 SEND_BUF[1]=0x01;
  36.                 WriteDataToLCD(0x1000,0,2);
  37.                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
  38.                //开关开
  39.       }
  40.   
  41.     //处理完DP数据后应有反馈
  42.     ret = mcu_dp_bool_update(DPID_SWITCH_1,switch_1);
  43.     if(ret == SUCCESS)
  44.         return SUCCESS;
  45.     else
  46.         return ERROR;
  47. }
  48. /*****************************************************************************
  49. 函数名称 : dp_download_switch_2_handle
  50. 功能描述 : 针对DPID_SWITCH_2的处理函数
  51. 输入参数 : value:数据源数据
  52.         : length:数据长度
  53. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  54. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  55. *****************************************************************************/
  56. static unsigned char dp_download_switch_2_handle(const unsigned char value[], unsigned short length)
  57. {
  58.     //示例:当前DP类型为BOOL
  59.     unsigned char ret;
  60.     //0:关/1:开
  61.     unsigned char switch_2;
  62.    
  63.     switch_2 = mcu_get_dp_download_bool(value,length);
  64.     if(switch_2 == 0) {
  65.               
  66.                 SEND_BUF[0]=0x00;
  67.                 SEND_BUF[1]=0x06;
  68.                 send_tz();

  69.                 SEND_BUF[0]=0x00;
  70.                 SEND_BUF[1]=0x00;
  71.                 WriteDataToLCD(0x1001,0,2);
  72.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
  73.         //开关关
  74.     }else {
  75.                     
  76.                 SEND_BUF[0]=0x00;
  77.                 SEND_BUF[1]=0x06;
  78.                 send_tz();
  79.                
  80.                 SEND_BUF[0]=0x00;
  81.                 SEND_BUF[1]=0x01;
  82.                 WriteDataToLCD(0x1001,0,2);
  83.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
  84.         //开关开
  85.     }
  86.   
  87.     //处理完DP数据后应有反馈
  88.     ret = mcu_dp_bool_update(DPID_SWITCH_2,switch_2);
  89.     if(ret == SUCCESS)
  90.         return SUCCESS;
  91.     else
  92.         return ERROR;
  93. }
  94. /*****************************************************************************
  95. 函数名称 : dp_download_switch_3_handle
  96. 功能描述 : 针对DPID_SWITCH_3的处理函数
  97. 输入参数 : value:数据源数据
  98.         : length:数据长度
  99. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  100. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  101. *****************************************************************************/
  102. static unsigned char dp_download_switch_3_handle(const unsigned char value[], unsigned short length)
  103. {
  104.     //示例:当前DP类型为BOOL
  105.     unsigned char ret;
  106.     //0:关/1:开
  107.     unsigned char switch_3;
  108.    
  109.     switch_3 = mcu_get_dp_download_bool(value,length);
  110.     if(switch_3 == 0) {
  111.                     
  112.                 SEND_BUF[0]=0x00;
  113.                 SEND_BUF[1]=0x06;
  114.                 send_tz();
  115.                
  116.                 SEND_BUF[0]=0x00;
  117.                 SEND_BUF[1]=0x00;
  118.                 WriteDataToLCD(0x1002,0,2);
  119.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
  120.         //开关关
  121.     }else {
  122.             
  123.                 SEND_BUF[0]=0x00;
  124.                 SEND_BUF[1]=0x06;
  125.                 send_tz();

  126.                 SEND_BUF[0]=0x00;
  127.                 SEND_BUF[1]=0x01;
  128.                 WriteDataToLCD(0x1002,0,2);
  129.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
  130.         //开关开
  131.     }
  132.   
  133.     //处理完DP数据后应有反馈
  134.     ret = mcu_dp_bool_update(DPID_SWITCH_3,switch_3);
  135.     if(ret == SUCCESS)
  136.         return SUCCESS;
  137.     else
  138.         return ERROR;
  139. }
  140. /*****************************************************************************
  141. 函数名称 : dp_download_switch_4_handle
  142. 功能描述 : 针对DPID_SWITCH_4的处理函数
  143. 输入参数 : value:数据源数据
  144.         : length:数据长度
  145. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  146. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  147. *****************************************************************************/
  148. static unsigned char dp_download_switch_4_handle(const unsigned char value[], unsigned short length)
  149. {
  150.     //示例:当前DP类型为BOOL
  151.     unsigned char ret;
  152.     //0:关/1:开
  153.     unsigned char switch_4;
  154.    
  155.     switch_4 = mcu_get_dp_download_bool(value,length);
  156.     if(switch_4 == 0) {
  157.                
  158.                 SEND_BUF[0]=0x00;
  159.                 SEND_BUF[1]=0x06;
  160.                 send_tz();
  161.                
  162.                 SEND_BUF[0]=0x00;
  163.                 SEND_BUF[1]=0x00;
  164.                 WriteDataToLCD(0x1003,0,2);
  165.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
  166.         //开关关
  167.     }else {
  168.             
  169.                 SEND_BUF[0]=0x00;
  170.                 SEND_BUF[1]=0x06;
  171.                 send_tz();
  172.             
  173.                 SEND_BUF[0]=0x00;
  174.                 SEND_BUF[1]=0x01;
  175.                 WriteDataToLCD(0x1003,0,2);
  176.               HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
  177.         //开关开
  178.     }
  179.   
  180.     //处理完DP数据后应有反馈
  181.     ret = mcu_dp_bool_update(DPID_SWITCH_4,switch_4);
  182.     if(ret == SUCCESS)
  183.         return SUCCESS;
  184.     else
  185.         return ERROR;
  186. }



(2)主程序设计

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

  1. int main(void)
  2. {

  3.   /* MCU Configuration--------------------------------------------------------*/
  4.   /* Reset of all peripherals, Initializes the Flash interface and the Systick.*/
  5.   HAL_Init();

  6.   /* Configure the system clock */
  7.   SystemClock_Config();

  8.   /* Initialize all configured peripherals */
  9.   MX_GPIO_Init();
  10.   MX_USART1_UART_Init();
  11.   MX_USART2_UART_Init();
  12.     MX_USART3_UART_Init();
  13.     wifi_protocol_init();       //wifi协议初始化
  14.   MX_I2C2_Init();
  15.   MX_I2C1_Init();
  16.    
  17.     MX_TIM3_Init(10000-1,8000-1); //定时器3初始化,定时1s
  18.    
  19.   SHT3x_Reset();
  20.     if( 0 == SHT3x_Init())
  21.         printf("SHT3x_Init OK rn");
  22.     else
  23.         printf("SHT3x_Init ERR rn");
  24.    

  25.   /* Infinite loop */
  26.   /* USER CODE BEGIN WHILE */
  27.   while (1)
  28.   {
  29.           Connect_Wifi();   
  30.             wifi_uart_service();//wifi串口数据处理服务  
  31.         
  32.    if(1 == Display_Flag)
  33.         {
  34.           Deal_Data_Display();  
  35.             Display_Flag=0;
  36.       }         
  37.   }
  38. }

(3)如何降低功耗

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


(4)样机实物展示

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






可以通过APP控制串口屏和GPIO口的电平。
[url=https://auth.tuya.com/?_source=7c8653b7bd61bf9239a1a6c12e52124d]理论不及实践,戳我立即免费体验[/url]


长按下方二维码回复电子发烧友”即可免费领取 3 块联网模组哦~还能与全国开发者在线交流!▼▼

更多回帖

发帖
×
20
完善资料,
赚取积分