STM32F103学习笔记(5)—— 大彩屏使用——串口通信工程级应用

news/2025/2/1 4:55:21/

目录

 1. 大彩屏概览

 2. 大彩教程

3. 指令相关

4 . 指令设置

5. 屏幕仿真

6. 屏幕串口

7. 串口设置

8. 按键控制PWM大小

9. 全部代码


 1. 大彩屏概览

使用大彩屏的好处是,屏幕操作可以直接用屏幕内部指令,比如禁用按键、文本输出等功能,不需要通过下位机获取指令。

对外发送的就只有信号,如停止信号、启动信号等,我们只需要知道一个启动或停止信号就可以了,而不需要发送相应的禁用按键指令,这在迪文屏中是无法实现的

如图所示,大彩自家的组屏软件TFT,这里我目前只做了工程画面,没有做音频和视频

 2. 大彩教程

如图,可以直接百度大彩屏搜索大彩官网,去官网下载资料

3. 指令相关

组屏相关比较简单,看下入门手册自己试试就会了,这里不再多说。主要说一下我在使用过程中遇到的问题。

如下图所示,大彩自带指令系统,在按键触发时候会自动使用串口对外发送指令,因此几乎不需要自己制定对外指令。

点击按键,右侧的对内指令,如下图想要实现点击启动按钮后禁用除停止外其他按键。设置启动的对内指令即可。

波特率设置

最开始一直收不到指令,但是有中断,以为是屏幕坏了,发送的都是00 00 00,然后直接用USB转串口,就是下图这玩意儿

连上之后发现串口助手收到的也是00 00 00,突然想到波特率,因为记得在屏幕上面点了设置是115200,如下图

然后想到每次用屏幕仿真好像都是9600

所以直接把串口助手的波特率设置为9600,发现接收到真实数据。。。原来是波特率没设置好哈哈

实际上他的波特率设置在这里

或者直接点击左边的工程画面

就会出现下图所示,选择115200就可以了

 

4 . 指令设置

在上面步骤中得到如下界面,点击指令助手

比如使用禁用按键功能,选择如下禁使能控件,选择画面ID、控件ID指定当前想要禁用的按键,然后点击禁用控件即可生成相应指令,将该指令复制粘贴放到上图的按下指令当中。

按下指令可以设置多个,因此可以通过这个来禁用多个按键。

5. 屏幕仿真

如图,点击左上角的小三角开启仿真,模拟真实屏幕发送指令,如图是一个启动和停止的指令。

按下和弹起是两个指令,本次操作我只按下,因此只有按下指令,这个指令是对外发送的,也就是通过串口对外部主板发送的指令。

从图中可以看到只有三条指令,第一条是开始键按下的指令,第二条是停止键按下的指令,第三条是停止键弹起的指令。

因为设置了停止键的触发模式为瞬间,因此在按下的同一时间会自动弹起,而开始键设置的是开关,因此按下之后再次按下才会弹起。

6. 屏幕串口

如图,屏幕与主板之间只需要使用4根线,VCC5v,GND,Dout,Din。

VCC可以直接接入正点原子精英板5V输出口,但是使用电脑USB供电不足5V,因此要用上随主板附带的电源线,接上即可点亮屏幕。屏幕使用只需电源线连接就可以了吗,但是同行需要和主板共地,因此如果使用外接电源,需要把外接电源的地线和主板地线相连。

屏幕后的Dout对应主板RX口,Din对应主板TX口,屏幕和主板间的通信就是通过这个实现的,每次触发屏幕的对外指令就是通过这个发送,而屏幕也可以直接通过这个接收指令。大家可以试试主板接收到开启指令后发送禁用其他按键指令,看看屏幕的状态。

7. 串口设置

如上图所示,我使用了PB10和PB11也就是USART3作为屏幕和主板的通信通道

串口3的代码如下

#include "sys.h"
#include "usart.h"
#include "led.h"#if 1 //如果使能了接收  
//串口1中断服务程序
u8  USART_RX_BUF[30]; //接收缓冲
u8 USART_RX_STA=0;
u8 Lock4UsartRX=0;
u8 Tag;void uart_init(u32 bound)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;/* Configure the NVIC Preemption Priority Bits */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE  );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = bound;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(USART3, &USART_InitStructure);USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);USART_Cmd(USART3, ENABLE);
}void USART3_IRQHandler(void)                	//串口1中断服务程序
{u8 Res;
//	if(Lock4UsartRX==0if(1){if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){USART_ClearITPendingBit(USART3,USART_IT_RXNE);  /* 清中断标志 */Res = USART_ReceiveData(USART3);	//读取接收到的数据if(USART_RX_STA!=4)//下位机发送结束,开始接收数据{USART_RX_BUF[Tag]=Res ;Tag++;if(Res==0xFF&&USART_RX_STA==0){USART_RX_STA=1;}else if(Res==0xFC&&USART_RX_STA==1){USART_RX_STA=2;}else if(Res==0xFF&&USART_RX_STA==2){USART_RX_STA=3;}else if(Res==0xFF&&USART_RX_STA==3){USART_RX_STA=4;Tag=0;Lock4UsartRX=1;}else{USART_RX_STA=0;}if(Tag>30)Tag=0;//接收数据错误,重新开始接收...}}}}#endif

因为屏幕对外发送的指令都是以FF FC FF FF结尾,因此只要判断最后收到的4个字节是不是这四个字,是的话就关闭接收,然后主函数里面处理这个指令,处理完之后就重新打开接收。(其实如果直接在接收完成后把缓冲区内容直接放到另一个数组里面应该会更好点,这样就可以边接收边处理上一帧的指令,这里我是担心如果在处理的时候缓冲区内容被改变,因此使用上锁来关闭接收中断)

所谓的上锁,如下图所示,给一个标志位,接收完成置4,处理完成再置零。

如下图的接收完成也是有操作的,把判断都放在前面,如果前面的都成立就会跳过else,如果有一个不成立,则都会把USART_RX_STA置零。 

8. 按键控制PWM大小

如下图,点上升和下降的发送的指令中,1-9是14位指令,而11到99是15位指令,100是16位指令。

这里我设置的最大是100,因此无需考虑100以上的情况。

先判断是否已经接收完成,如果接收完成则开始处理缓冲区内容。

如果符合以下条件则计算出传过来的数据大小,注意大彩的屏幕发送的数字指令是以3x开头的,如9则是0x39,要去掉3则0x39-16*3即可。如果是0x39 0x39这样的数,则(0x39-16*3)*10+0x39-16*3就可以得到结果99

   if(Lock4UsartRX==1)  //设置PWM{if(USART_RX_BUF[15]!=0x00&&USART_RX_BUF[4]==0x01&&USART_RX_BUF[6]==0x04){pwmNum=100;}else if(USART_RX_BUF[14]!=0x00&&USART_RX_BUF[4]==0x01&&USART_RX_BUF[6]==0x04){pwmNum=(USART_RX_BUF[8]-16*3)*10+(USART_RX_BUF[9]-16*3);}else if(USART_RX_BUF[13]!=0x00&&USART_RX_BUF[4]==0x01&&USART_RX_BUF[6]==0x04){pwmNum=USART_RX_BUF[8]-16*3;}TIM_SetCompare2(TIM3,pwmNum*3);  //设置红蓝光PWMUSART_RX_BUF[15]=USART_RX_BUF[14]=USART_RX_BUF[13]=0;Lock4UsartRX=0;USART_RX_STA=0;}

 CSDN不能传视屏,我就直接整了个仿真结果给大家伙儿瞅瞅

按理说缓冲区数据8 9应该是本次发送的数据,不知道为什么在处理完之后就直接给置0置1了,后面有时间再看看吧(▼ヘ▼#)....

然后用这个值设置PWM就不用说了吧,不明白的同学可以看看我前面的PWM相关文章。

9. 全部代码

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"	
#include "sys.h" void uart_init(u32 bound);
#endif

usart.c

#include "sys.h"
#include "usart.h"
#include "led.h"#if 1 //如果使能了接收  
//串口1中断服务程序
u8  USART_RX_BUF[30]; //接收缓冲
u8 USART_RX_STA=0;
u8 Lock4UsartRX=0;
u8 Tag;void uart_init(u32 bound)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;/* Configure the NVIC Preemption Priority Bits */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE  );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = bound;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(USART3, &USART_InitStructure);USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);USART_Cmd(USART3, ENABLE);
}void USART3_IRQHandler(void)                	//串口1中断服务程序
{u8 Res;
//	if(Lock4UsartRX==0if(1){if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){USART_ClearITPendingBit(USART3,USART_IT_RXNE);  /* 清中断标志 */Res = USART_ReceiveData(USART3);	//读取接收到的数据if(USART_RX_STA!=4)//下位机发送结束,开始接收数据{USART_RX_BUF[Tag]=Res ;Tag++;if(Res==0xFF&&USART_RX_STA==0){USART_RX_STA=1;}else if(Res==0xFC&&USART_RX_STA==1){USART_RX_STA=2;}else if(Res==0xFF&&USART_RX_STA==2){USART_RX_STA=3;}else if(Res==0xFF&&USART_RX_STA==3){USART_RX_STA=4;Tag=0;Lock4UsartRX=1;}else{USART_RX_STA=0;}if(Tag>30)Tag=0;//接收数据错误,重新开始接收...}}}}#endif

mian.c

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "pwm.h"
#include "usart.h"
#include "timer.h"
#include "disPlay.h"int main(void)
{delay_init();ledInit();uart_init(115200);TIM2_Int_Init(7999,8999);TIM3_CH2_PWM_Init(899,0);while(1){disPlayCommand();}
}

时间原因,多余的代码没有删掉,请同志们自己删一下。


http://www.ppmy.cn/news/393957.html

相关文章

嵌入式调试神器——MicroLab​

关注、星标公众号,直达精彩内容 来源:网络素材 最近发现了一个调试神器-MicroLab,MicroLab是一款怎样的神器? 历时十五个月,有效代码量七万九千余行,蓝色星球上最好用的嵌入式开发调试神软——MicroLab Ve…

”WinForm上位机+OV7670摄像头+STM32+蓝牙“图像采集系统(一)STM32驱动CMOS摄像头OV7670

初衷;将摄像头放在防盗门猫眼位置,访客到来时,给访客拍个照,然后传到房主端显示。 现在只完成了蓝牙传输,和WinForm窗体显示,后面时间来得及的话会陆续完成WiFi传输,和手机端APK显示。 常规思路…

micropython 通过spi驱动LCD显示屏

我呢一直对电路设计和程序设计有非常大的爱好,不好说有多精通,纯属个人弄着玩的,所以后面有时间可以和大家一起来交流一下,另外最近也接触了一些PCB,所以一些开发板之类的都自己设计制作了。 今天讲的是通过micropytho…

Redis-原生命令

string 单值 set key value get key 对象 set user:1 value Mset user:1:name zhangsan user:1:sex man Mget user:1:name user:1:sex 分布式锁 setnx product:1001 true 计数器/全局序列号维护 incr article:readcount:{文章id} get article:readcount:{文章id} 哈希hash…

嵌入式调试神软——MicroLab​~

MicroLab是风媒电子的号主赵工的杰作。上周杨工与果果小师弟也分享了相关的文章,看起来很酷,但一直没有时间玩,这里先Mark一下,下一篇文章我们也玩来一下。MicroLab是一款怎样的神器?下面看看赵工文章的介绍&#xff1…

龙邱特别款英飞凌miniwiggler拆机鉴赏

龙邱特别款英飞凌miniwiggler拆机鉴赏 今年暑假准备参加智能车大赛,做基础四轮组。据学长说龙邱的库用了更多的硬件外设资源,我就在全实验室用逐飞套的情况下转投龙邱了。。。 今天核心板仿真器一堆外设到货(龙邱总是比逐飞慢个一个星期&…

STM32CubeMX(11) ——JY901陀螺仪数据的读取与简单数据处理

JY901陀螺仪数据的读取与简单数据处理 文章目录 JY901陀螺仪数据的读取与简单数据处理前言JY901简单介绍 一、上位机调试二、Cubemax配置三、代码包含官方JY901.h文件创建接收结构体和定义一些参数接收处理函数编写和结构体初始化函数一些细节的修改 实验结果总结 前言 JY901是…

使用STM32的硬件SPI及软件模拟SPI的方式驱动MAX7219点阵

使用STM32的硬件SPI及软件模拟SPI的方式驱动MAX7219点阵 一、max7219.c。二、max7219.h。三、main.c 开发板使用STM32F103ZET6主控,可使用其自带的硬件SPI或者使用软件模拟SPI的方式驱动MAX7219点阵,显示其他字符可在code_disp1中修改字节定义。 一、ma…