前言
我们先来看下串口屏,下图:
可以看到串口屏接线只需四根,就可以实现对屏幕的控制。我在某宝购买的型号HF043串口屏,价格80多,我加了demo板,其实只需要买屏和线就够了,一定要有USB转TTL模块哦。我的屏幕是4.3寸(不带触摸功能),欧克克,让我们开始吧。
一、软件设置串口屏
一般商家会自带软件,可以对串口屏进行设置,比如添加图片、动画,或者按键、文字、进度条、指针等。
软件的使用也很简单,新建一个页面Page0,添加一些自己想要的按键文案,如图(自己随意):
上图中可以看到,屏幕上一些简单设置,可在右侧编辑具体颜色、文字等,左边可以添加图片,添加好后,先下载再设置动画。
中间的命令行及串口可以对屏幕进行测试,我们也可以把这些命令用单片机串口输出,直接控制串口屏,就像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);
}
}
完整工程