前言

我们先来看下串口屏,下图:

STM32串口触摸屏物联网 stm32串口屏方案_单片机

STM32串口触摸屏物联网 stm32串口屏方案_串口_02

 可以看到串口屏接线只需四根,就可以实现对屏幕的控制。我在某宝购买的型号HF043串口屏,价格80多,我加了demo板,其实只需要买屏和线就够了,一定要有USB转TTL模块哦。我的屏幕是4.3寸(不带触摸功能),欧克克,让我们开始吧。

 一、软件设置串口屏

一般商家会自带软件,可以对串口屏进行设置,比如添加图片、动画,或者按键、文字、进度条、指针等。

STM32串口触摸屏物联网 stm32串口屏方案_STM32串口触摸屏物联网_03

软件的使用也很简单,新建一个页面Page0,添加一些自己想要的按键文案,如图(自己随意):

STM32串口触摸屏物联网 stm32串口屏方案_arm_04

上图中可以看到,屏幕上一些简单设置,可在右侧编辑具体颜色、文字等,左边可以添加图片,添加好后,先下载再设置动画。

中间的命令行及串口可以对屏幕进行测试,我们也可以把这些命令用单片机串口输出,直接控制串口屏,就像stm32和esp8266用AT指令互动一样。

我是先把屏幕动画,图案设置好,再利用单片机输出命令控制它。

我们先来看下效果:


串口屏stm32互动


二、代码设置

先来看main.c,关键地方我写了注释,大家也可以尝试换其他命令尝试下。

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "key.h"
#include "led.h"

typedef  unsigned long	 uint32; 

	//连线RX连接PA10,TX连接PA9				
extern unsigned char val[];
int main(void)
{	
		vu8 key1=0;

	unsigned char i,k;
	unsigned char ret;
	char buf[128];
	unsigned char key=0xff;
	unsigned char data_h,data_l;
	unsigned short data;
	SystemInit();//初始化RCC 设置系统主频为72MHZ
	delay_init();	     //延时初始化
	uart_init(115200);	 //串口初始化为115200
	SPI_Flash_Init(); 
	delay_ms(500);
	SPI_Flash_Read(&data_h,0,1);  
	SPI_Flash_Read(&data_l,1,1);  
	data=data_h*256+data_l;	
	KEY_Init();
	LED_Init();

    while(1)
  {			
    delay_ms(500); 

		key1=KEY_Scan(0);
		if(key1){
	switch(key1){
	case WKUP_PRES:	//控制蜂鸣器
				UartSend("JUMP(1);\r\n");//翻页
		    CheckBusy();
	    	delay_ms(100);
					break; 
		case  KEY1_PRES:
    UartSend("SET_BTN(3,1);SET_POINT(2,90);SET_PROG(1,50);\r\n");//控制按键、指针、进度条
		CheckBusy();
		LED1=!LED1;
		delay_ms(10); 
		break;
		case  KEY0_PRES:
    UartSend("SET_BTN(3,0);SET_POINT(2,150);SET_PROG(1,100);\r\n");
		CheckBusy();
		LED0=!LED0;
		delay_ms(100);
		break;
	
		
	}
		}
	}
}

串口使用到了stm32f103的串口1,库文件如下:usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" 


extern u8 USART_RX_BUF[64];     //接收缓冲,最大63个字节.末字节为换行符 
extern u8 USART_RX_STA;         //接收状态标记	

void uart_init(u32 bound);
void UartSend(char * databuf) ;
void CheckBusy(void)  ;
#endif

 这个是usart.c,大家把它们添加到模板里。

#include "sys.h"
#include "usart.h"
#include "delay.h"

typedef  unsigned long	 uint32; 



//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

/*使用microLib的方法*/
 /* 
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t) ch);

	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}	
   
    return ch;
}
int GetKey (void)  { 

    while (!(USART1->SR & USART_FLAG_RXNE));

    return ((int)(USART1->DR & 0x1FF));
}
*/
int UartGet (void)  { 

    while (!(USART1->SR & USART_FLAG_RXNE));

    return ((int)(USART1->DR & 0x1FF));
} 

extern u8 rx_flag_finished;
extern u8 RX_BUF[];
extern u8 rx_count;
extern u8 ok;
void CheckBusy(void)  
{
	while(1)
	{
   if(ok==0x0f)
		 break;
	}		
	
	ok=0;
}


    void get_var(unsigned char *val)
		{	 
			for(;;)
			{ 
				if((RX_BUF[0]=='V')&&(RX_BUF[1]=='A')&&(RX_BUF[2]=='R'))
				{
					RX_BUF[0]=0;
					RX_BUF[1]=0;
					RX_BUF[2]=0;
					val[0]=RX_BUF[3];
					val[1]=RX_BUF[4];
					val[2]=RX_BUF[5];
					val[3]=RX_BUF[6];
					rx_flag_finished=0;	
					rx_count=0;
					break;				
				}	
			}

		}

		
char rch[5][3];     //xxx:xxx,xxx,xxx,xxx
u8 i=0;	
u8 p=0;//
u8 cmd=0;		//==1
u8 cmdok=0;	//==1 
u8 ok=0x00;
void getch(u8 c)
{	
	 if (c=='{')
	{	i=0;
		cmd=1;
		p=0;
	}
	else if(c=='}')
	{	cmd=0;
		cmdok=1;
	}
	else if((c==':')||(c==','))
	{
			p++;
			i=0;
	}		
	else if (cmd==1)
	{	
		if (i<3) rch[p][i]=c;
		i++;
	}
	else	if(c=='O')
	{
		ok=(ok&0x00)|(0x01);
	}		
	else if(c=='K')
	{
		ok=(ok&0x0d)|(0x02);
	}	
  else if(c=='\r')
	{
		ok=(ok&0x0b)|(0x04);
	}
  else if(c=='\n')
	{
	 ok=(ok&0x07)|(0x08);
	}
	
}
unsigned char val[4];
unsigned char GetValue(void)  
{	
	unsigned char m,n;
	while(1)
	{			
		if(cmdok==1)
		{			
			if ((rch[0][0]=='V')&&(rch[0][1]=='A')&&(rch[0][2]=='R'))
			{	
				/*第一个字节*/
				if ((rch[1][2]>=0x30) && (rch[1][2]<=0x39))//100以上的数  
				{		
					val[0]=(rch[1][0]-0x30)*100+(rch[1][1]-0x30)*10+(rch[1][2]-0x30);
					
				}
				else if((rch[1][1]>=0x30) && (rch[1][1]<=0x39)) //10以上的数
				{
					val[0]=(rch[1][0]-0x30)*10+(rch[1][1]-0x30);
				}		
				else if((rch[1][0]>=0x30) && (rch[1][0]<=0x39))
				{
					val[0]=(rch[1][0]-0x30);						
				}
				/*第二个字节*/
					if ((rch[2][2]>=0x30) && (rch[2][2]<=0x39))//100以上的数
				{		
					val[1]=(rch[2][0]-0x30)*100+(rch[2][1]-0x30)*10+(rch[2][2]-0x30);				
				}
				else if((rch[2][1]>=0x30) && (rch[2][1]<=0x39)) //10以上的数
				{
					val[1]=(rch[2][0]-0x30)*10+(rch[2][1]-0x30);
				}		
				else if((rch[2][0]>=0x30) && (rch[2][0]<=0x39))
				{
					val[1]=(rch[2][0]-0x30);						
				}
				
			/*第三个字节*/
					if ((rch[3][2]>=0x30) && (rch[3][2]<=0x39))//100以上的数
				{		
					val[2]=(rch[3][0]-0x30)*100+(rch[3][1]-0x30)*10+(rch[3][2]-0x30);
					
				}
			
				else if((rch[3][1]>=0x30) && (rch[3][1]<=0x39)) //10以上的数
				{
					val[2]=(rch[3][0]-0x30)*10+(rch[3][1]-0x30);
				}		
				else if((rch[3][0]>=0x30) && (rch[3][0]<=0x39))
				{
					val[2]=(rch[3][0]-0x30);						
				}
				/*第四个字节*/
					if ((rch[4][2]>=0x30) && (rch[4][2]<=0x39))//100以上的数
				{		
					val[3]=(rch[4][0]-0x30)*100+(rch[4][1]-0x30)*10+(rch[4][2]-0x30);
					
				}
			
				else if((rch[4][1]>=0x30) && (rch[4][1]<=0x39)) //10以上的数
				{
					val[3]=(rch[4][0]-0x30)*10+(rch[4][1]-0x30);
				}		
				else if((rch[4][0]>=0x30) && (rch[4][0]<=0x39))
				{
					val[3]=(rch[4][0]-0x30);						
				}		
				
			for(n=0;n<5;n++)
					for(m=0;m<3;m++)
				rch[n][m]=0;
				 cmdok=0;
					break;
				
				
		}
			//	cmdok=0;
			
		
		
	}	
		
}
}

unsigned char GetKey(unsigned char *rval)  
{	
	unsigned char m,n;
	while(1)
	{			
		if(cmdok==1)
		{			
			if ((rch[0][0]=='U')&&(rch[0][1]=='P'))
			{		
				*rval=1;
						cmdok=0;
				for(n=0;n<5;n++)
					for(m=0;m<3;m++)
				rch[n][m]=0;
	
					break;	
				
			}
			else if ((rch[0][0]=='D')&&(rch[0][1]=='N'))
			{
						*rval=0;
				   cmdok=0;
				for(n=0;n<5;n++)
					for(m=0;m<3;m++)
				rch[n][m]=0;
					break;	
			}

		
		}
		
	}	
		
}






void UartSend(char * databuf) 
{ 
	u8 i=0;
	while (1)
	{ 
		if ((*databuf)!=0)//直到数据都发送完成 
	{ 
		USART_SendData(USART1, *databuf); //发送一个字节数据
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}; //
		databuf++;//i++;
	}
	else return;
	}
}


u8 USART_RX_BUF[64];     //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0;       //接收状态标记

#ifdef AUTO_TEST
	#define AUTO_NEXT
#else
	#define MANUA_NEXT
#endif


#define AUTO_NEXT	    //自动
//#define MANUA_NEXT	  //手动

#define KEY_UP    GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)//定义“下一步”按键
#define KEY_DOWM  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1)//定义上一步”按键
#define KEY_Stop  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)//定义"暂停"
  


void uart_init(u32 bound){
    //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);
	
	
	
	     //_KEY_STEP   PC0  UP
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);
	
		     //_KEY_STEP   PC1  DOWN
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);
	
		     //_KEY_Stop   PC2  暂停
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	     //_LED   PD2
		GPIO_SetBits(GPIOD,GPIO_Pin_2);	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;	   //
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD, &GPIO_InitStructure); //	
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	
     //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

   //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//

	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
  
   //USART 初始化设置
   
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);
   

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
   
    USART_Cmd(USART1, ENABLE);                    //使能串口 

}

//extern void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);
extern void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite);





u8 RX_BUF[4];
u8 rx_flag_finished=0;
u8 rx_count=0;
void USART1_IRQHandler(void)                	//??1??????
{
	u8 Res=1;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //????(?????????0x0d 0x0a??)
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//????????
		getch(Res);

  }
}

 完整工程

qq-hh-My_Project_stm32/stm32串口屏 at master · qq-hh/qq-hh-My_Project_stm32 (github.com)

STM32串口触摸屏物联网 stm32串口屏方案_串口_05

https://github.com/qq-hh/qq-hh-My_Project_stm32/tree/master/stm32%E4%B8%B2%E5%8F%A3%E5%B1%8F