如何利用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 HAL库和涂鸦Wi-Fi模组进行通信