STM32物联网项目——HMI串口屏实现人机互联

文章介绍了如何使用串口HMI与MCU进行交互,通过设计GUI界面控制数码管、步进电机和蜂鸣器。在HMI上设计界面并下载到串口屏,通过解析接收到的键值信息来切换不同功能页面,实现人机交互。数码管计数和步进电机控制等功能代码也进行了展示。
摘要由CSDN通过智能技术生成

程序功能:

  1.  点击数码管,进入数码管界面,开发板上数码管与屏幕数码管界面同时计数
  2.  点击步进电机,进入电机界面,点击相应按钮,控制步进电机(视频这里未插入电机)
  3.  点击Buzzer,进入蜂鸣器界面,控制开发板的蜂鸣器实现警报音
  4. 点击NTC,进入NTC界面,开发板上数码管与屏幕NTC界面显示开发板温度(这里NTC程序发送给串口屏代码的控件号有误,所以NTC界面没有显示温度值)

效果图奉上:

HMI

HMI串口屏介绍

串口HMI就是已经封装好底层功能以后,通过串口与MCU进行交互,虽然价格较贵,但开发难度大大减小,只需要使用相关上位机软件设计好GUI界面,并写好一些命令,再通过串口与MCU实现人机交互。

这里使用的是陶晶驰的串口屏,官方教程网址:http://tjc1688.com/,上位机软件下载包也可在此网站找到。

上位机软件界面认识

讲几个常用或较重要的工具和页面:

  1. 下载:通过串口将设计的界面下载给串口屏 
  2. 工具箱:里面有许多控件令我们挑选,也就是设计自己想要的GUI,例如,点击文本控件,插入到GUI:
  3.  在界面右下角的窗口,可以操作控件的属性,例如:将刚插入的文本控件文本改为“你好”,背景色为蓝色:

 当如,要想写入自己想要的文本,必须要先创建自己的字库,并添加到左下角窗口字库页面

 

4.Page 页面

工具箱里随意按置一个控件都会有按下事件和弹起事件,选择控件后,在命令窗口的弹起事件输入page 1(1是页面的id号,也可改为自己更改后的名字),当使用时,点击控件,就会跳到相应的界面

 勾选“发送键值”,串口屏会发送相应信息给MCU。

设计出了自己想要的GUI界面后,就可以点击左上角的调试功能,实现自己的界面。

实例

设计好自己的GUI界面后,我们就要下载到串口屏上了,首先在硬件上,将串口屏的发送和接收引脚与单片机的串口接收、发送引脚连好,之后,点击Program.s里设置波特率为115200,再点击下载

 代码:

这里只给出部分代码作参考

HMI协议(接收串口屏键值信息)代码:

/*
	* @name   HMI_Protocol
	* @brief  接口协议 - 接收键值信息
	* @param  None
	* @retval None      
*/
static void HMI_Protocol(void) 
{
		uint8_t Temp_Array[7] = {0x00};
		uint8_t i = 0,Index = 0;
	
		//串口1停止DMA接收
		HAL_UART_DMAStop(&huart1);
	
		//读取缓存,一共7个字节,起始值为0x65
		for(i=0;i<HMI_Rec_Buffer_LENGTH;i++)
		{
			//检测起始值0x65
			if(Index == 0)
			{
				if(*(HMI.pucRec_Buffer+i) != 0x65)
					continue;
			}
			
			Temp_Array[Index] = *(HMI.pucRec_Buffer+i);

			//已读取7个字节
			if(Index == Protocol_Data_LEN)
				break;
			
			Index++;
		}
		
		//串口1开启DMA接收
		HAL_UART_Receive_DMA(&huart1,HMI.pucRec_Buffer,(uint16_t)20);
		
		//处理数据
		if(Index == Protocol_Data_LEN)
		{
			//主页面键值信息
			if(Temp_Array[1] == 0x00)
			{
				//控件2弹起
				if((Temp_Array[2] == 0x02) && (Temp_Array[3] == 0x00))
				{
					//切换至数码管界面
					HMI.Page = Page_Display;
					Display.Disp_Clr();
				}
				
				//控件3信息
				if((Temp_Array[2] == 0x03) && (Temp_Array[3] == 0x00))
				{
					//切换至步进电机页面
					HMI.Page = Page_Step_Motor;
					
					Display.Disp_Clr();
					//ÏÔʾµç»úȦÊý
					Display.Disp_HEX(Disp_NUM_6,Unipolar_Step_Motor.Circle,Disp_DP_OFF);
					//ÏÔʾµç»úËÙ¶È
					switch(Unipolar_Step_Motor.Speed)
					{
						case 100: Display.Disp_HEX(Disp_NUM_1,1,Disp_DP_OFF); break;
						case 90:  Display.Disp_HEX(Disp_NUM_1,2,Disp_DP_OFF); break;
						case 80:  Display.Disp_HEX(Disp_NUM_1,3,Disp_DP_OFF); break;
						case 70:  Display.Disp_HEX(Disp_NUM_1,4,Disp_DP_OFF); break;
						case 60:  Display.Disp_HEX(Disp_NUM_1,5,Disp_DP_OFF); break;
						case 50:  Display.Disp_HEX(Disp_NUM_1,6,Disp_DP_OFF); break;
						case 40:  Display.Disp_HEX(Disp_NUM_1,7,Disp_DP_OFF); break;
						case 30:  Display.Disp_HEX(Disp_NUM_1,8,Disp_DP_OFF); break;
						case 20:  Display.Disp_HEX(Disp_NUM_1,9,Disp_DP_OFF); break;
						default: break;
					}
				}
				//控件5弹起
				if((Temp_Array[2] == 0x05) && (Temp_Array[3] == 0x00))
				{
					//切换至NTC界面
					HMI.Page = Page_NTC;
					Display.Disp_Clr();
				}	
				//控件6弹起
				if((Temp_Array[2] == 0x06) && (Temp_Array[3] == 0x00))
				{
					//切换至蜂鸣器界面
					HMI.Page = Page_Buzzer;
					Display.Disp_Clr();
				}
			}
			
			//数码管页面信息
			if(Temp_Array[1] == 0x01)
			{
				//控件1弹起
				if((Temp_Array[2] == 0x01) && (Temp_Array[3] == 0x00))
				{
					//切换至主页面
					HMI.Page = Page_Main;				
					Display.Disp_Clr();
				}
			}
			
			//步进电机页面信息
			if(Temp_Array[1] == 0x02)
			{
				//控件11弹起
				if((Temp_Array[2] == 0x0B) && (Temp_Array[3] == 0x00))
				{
					//切换至主页面
					HMI.Page = Page_Main;
					Display.Disp_Clr();
					//关闭步进电机
					Unipolar_Step_Motor.Status = Stop_State;
					CLR_Motor_A;
					CLR_Motor_B;
					CLR_Motor_C;
					CLR_Motor_D;
					LED.LED_OFF(LED3);
					
					Unipolar_Step_Motor.Circle = 0;
				}
				
				//控件5弹起
				if((Temp_Array[2] == 0x05) && (Temp_Array[3] == 0x00))
				{
					HMI.Page_Step_Motor_KEY_Flag = TRUE;
					HAL_GPIO_EXTI_Callback(KEY1_Pin);
					HMI.Page_Step_Motor_KEY_Flag = FALSE;
				}
				
				//控件8弹起
				if((Temp_Array[2] == 0x08) && (Temp_Array[3] == 0x00))
				{
					HMI.Page_Step_Motor_KEY_Flag = TRUE;
					HAL_GPIO_EXTI_Callback(KEY2_Pin);
					HMI.Page_Step_Motor_KEY_Flag = FALSE;
				}
				
				//控件6弹起
				if((Temp_Array[2] == 0x06) && (Temp_Array[3] == 0x00))
				{
					HMI.Page_Step_Motor_KEY_Flag = TRUE;
					HAL_GPIO_EXTI_Callback(KEY3_Pin);
					HMI.Page_Step_Motor_KEY_Flag = FALSE;
				}
				
				//控件7弹起
				if((Temp_Array[2] == 0x07) && (Temp_Array[3] == 0x00))
				{
					HMI.Page_Step_Motor_KEY_Flag = TRUE;
					HAL_GPIO_EXTI_Callback(KEY4_Pin);
					HMI.Page_Step_Motor_KEY_Flag = FALSE;
				}				
			}
			//NTC页面信息
			if(Temp_Array[1] == Page_NTC)
			{
				if((Temp_Array[2] == 0x03) && (Temp_Array[3] == 0x00))
				{
					//切换至主页面
					HMI.Page = Page_Main;				
					Display.Disp_Clr();
				}
			}
			//蜂鸣器页面信息
			if(Temp_Array[1] == Page_Buzzer)
			{
				//控件2弹起
				if((Temp_Array[2] == 0x02) && (Temp_Array[3] == 0x00))
				{
					//Çл»ÖÁÖ÷Ò³Ãæ
					HMI.Page = Page_Main;
					Display.Disp_Clr();
				}
				//控件3弹起
				if((Temp_Array[2] == 0x03) && (Temp_Array[3] == 0x00))
				{
					HMI.Page_Buzzer_Flag = TRUE;
					HAL_GPIO_EXTI_Callback(KEY1_Pin);
					HMI.Page_Buzzer_Flag = FALSE;
				}
			}
		}
}

数码管计数代码:

/*
	* @name   Fun_Page_Display
	* @brief  数码管显示页面
	* @param  None
	* @retval None      
*/
static void Fun_Page_Display()
{

	
	static uint32_t Cnt = 0;
	uint32_t i = 0;
	uint8_t  Disp_Str[9] = {'n','6','.','v','a','l','=','0','\0'}; 
	uint8_t  Cnt_Arr[6]  = {0x00};
	
	Cnt_Arr[0] = Cnt%10;      
	Cnt_Arr[1] = Cnt/10%10;   
	Cnt_Arr[2] = Cnt/100%10;   
	Cnt_Arr[3] = Cnt/1000%10;  
	Cnt_Arr[4] = Cnt/10000%10; 
	Cnt_Arr[5] = Cnt/100000;   
	
	//数码管显示计数值
	Display.Disp_HEX(Disp_NUM_1,Cnt_Arr[0], Disp_DP_OFF); 
	Display.Disp_HEX(Disp_NUM_2,Cnt_Arr[1], Disp_DP_OFF); 
	Display.Disp_HEX(Disp_NUM_3,Cnt_Arr[2], Disp_DP_OFF); 
	Display.Disp_HEX(Disp_NUM_4,Cnt_Arr[3], Disp_DP_OFF); 
	Display.Disp_HEX(Disp_NUM_5,Cnt_Arr[4], Disp_DP_OFF); 
	Display.Disp_HEX(Disp_NUM_6,Cnt_Arr[5], Disp_DP_OFF);
	
	//数据传给HMI串口屏
	for(i=0;i<6;i++)
	{
		Disp_Str[1] = i + '1';
		Disp_Str[7] = Cnt_Arr[i] + '0';
		HMI.SendString(Disp_Str);	
	}
	
	//更新计数值
	if(++Cnt > 999999)
		Cnt = 0;
	
	//延时50ms
	HAL_Delay(50);
}

 !GUI界面下载后,硬件一定要改变为HMI串口屏与单片机通信

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西红柿鸡蛋超级美味

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值