STM32与陶晶驰串口屏交互

1、串口屏界面设计

1.新建工程

保存位置自定义,作为一个合格的嵌入式工程师要有路径下没有中文的情况并命名。

选择自己串口屏对应的芯片,一般屏幕背面会有,也可以查看资料。

选择显示方向,自行选择。按照自己的爱好

右边可对当前页面重命名。

再进行一些基础代码修改。一般情况下修改波特率与单片机串口一致即可。

Program.s

复制代码
//以下代码只在上电时运行一次,一般用于全局变量定义和上电初始化数据
int sys0=0,sys1=0,sys2=0    //全局变量定义目前仅支持4字节有符号整形(int),不支持其他类型的全局变量声明,如需使用字符串类型可以在页面中使用变量控件
bauds=115200    //配置波特率为115200
dim=100    //配置亮度100
bkcmd=0
printh 00 00 00 ff ff ff 88 ff ff ff//输出上电信息到串口
page 0   //上电刷新第0页

然后从工具箱添加组件

右下角可进行属性设置。

然后在按钮组件添加弹起事件,0 1 2 3类似,依次添加。

串口屏界面设计完毕,下载到串口屏。

接下来进行单片机程序编写,本实验使用串口1与串口屏通讯。

程序与串口驱动无异

tjc_usart_hmi.h

复制代码
#ifndef __TJCUSARTHMI_H_
#define __TJCUSARTHMI_H_

#include "stm32f10x.h" 

/**
	打印到屏幕串口
*/
void TJCPrintf (const char *str, ...);
void initRingBuff(void);
void writeRingBuff(uint8_t data);
void deleteRingBuff(uint16_t size);
uint16_t getRingBuffLenght(void);
uint8_t read1BFromRingBuff(uint16_t position);
void USART1_Init(uint32_t bound);
void USART1_printf(char* fmt,...); //串口1的专用printf函数

#define RINGBUFF_LEN	(500)     //定义最大接收字节数 500

#define usize getRingBuffLenght()
#define code_c() initRingBuff()
#define udelete(x) deleteRingBuff(x)
#define u(x) read1BFromRingBuff(x)


extern uint8_t RxBuff[1];

#endif

tjc_usart_hmi.c

复制代码
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "tjc_usart_hmi.h"
#include <stddef.h>
#include <stm32f10x_usart.h>

#define STR_LENGTH 100

typedef struct
{
    uint16_t Head;
    uint16_t Tail;
    uint16_t Lenght;
    uint8_t  Ring_data[RINGBUFF_LEN];
}RingBuff_t;

RingBuff_t ringBuff;	//创建一个ringBuff的缓冲区
uint8_t RxBuff[1];

void TJCPrintf (const char *str, ...){ 
	char buffer[STR_LENGTH+1];  // 数据长度
	u8 i = 0;	
	va_list arg_ptr;
	va_start(arg_ptr, str);  
	vsnprintf(buffer, STR_LENGTH+1, str, arg_ptr);
	va_end(arg_ptr);
	while ((i < STR_LENGTH) && (i < strlen(buffer)))
	{
        USART_SendData(USART1, (u8) buffer[i++]);
        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); 
	}
	USART_SendData(USART1,(uint8_t)0xff);		//这个函数改为你的单片机的串口发送单字节函数
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	
	USART_SendData(USART1,(uint8_t)0xff);		//这个函数改为你的单片机的串口发送单字节函数
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	
	USART_SendData(USART1,(uint8_t)0xff);		//这个函数改为你的单片机的串口发送单字节函数
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	

}








/********************************************************
函数名:  	USART1_IRQHandler
作者:
日期:    	2022.10.08
功能:    	串口接收中断,将接收到的数据写入环形缓冲区
输入参数:
返回值: 		void
修改记录:
**********************************************************/
void USART1_IRQHandler(void)
{
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
		RxBuff[0] = USART_ReceiveData(USART1);
		writeRingBuff(RxBuff[0]);
		
		
		
		
	}
}



/********************************************************
函数名:  	initRingBuff
作者:
日期:    	2022.10.08
功能:    	初始化环形缓冲区
输入参数:
返回值: 		void
修改记录:
**********************************************************/
void initRingBuff(void)
{
  //初始化相关信息
  ringBuff.Head = 0;
  ringBuff.Tail = 0;
  ringBuff.Lenght = 0;
}



/********************************************************
函数名:  	writeRingBuff
作者:
日期:    	2022.10.08
功能:    	往环形缓冲区写入数据
输入参数:
返回值: 		void
修改记录:
**********************************************************/
void writeRingBuff(uint8_t data)
{
  if(ringBuff.Lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
  {
    return ;
  }
  ringBuff.Ring_data[ringBuff.Tail]=data;
  ringBuff.Tail = (ringBuff.Tail+1)%RINGBUFF_LEN;//防止越界非法访问
  ringBuff.Lenght++;

}




/********************************************************
函数名:  	deleteRingBuff
作者:
日期:    	2022.10.08
功能:    	删除串口缓冲区中相应长度的数据
输入参数:		要删除的长度
返回值: 		void
修改记录:
**********************************************************/
void deleteRingBuff(uint16_t size)
{
	if(size >= ringBuff.Lenght)
	{
	    initRingBuff();
	    return;
	}
	for(int i = 0; i < size; i++)
	{

		if(ringBuff.Lenght == 0)//判断非空
		{
		initRingBuff();
		return;
		}
		ringBuff.Head = (ringBuff.Head+1)%RINGBUFF_LEN;//防止越界非法访问
		ringBuff.Lenght--;

	}

}



/********************************************************
函数名:  	read1BFromRingBuff
作者:
日期:    	2022.10.08
功能:    	从串口缓冲区读取1字节数据
输入参数:		position:读取的位置
返回值: 		所在位置的数据(1字节)
修改记录:
**********************************************************/
uint8_t read1BFromRingBuff(uint16_t position)
{
	uint16_t realPosition = (ringBuff.Head + position) % RINGBUFF_LEN;

	return ringBuff.Ring_data[realPosition];
}




/********************************************************
函数名:  	getRingBuffLenght
作者:
日期:    	2022.10.08
功能:    	获取串口缓冲区的数据数量
输入参数:
返回值: 		串口缓冲区的数据数量
修改记录:
**********************************************************/
uint16_t getRingBuffLenght()
{
	return ringBuff.Lenght;
}


/********************************************************
函数名:  	isRingBuffOverflow
作者:
日期:    	2022.10.08
功能:    	判断环形缓冲区是否已满
输入参数:
返回值: 		1:环形缓冲区已满 , 2:环形缓冲区未满
修改记录:
**********************************************************/
uint8_t isRingBuffOverflow()
{
	return ringBuff.Lenght == RINGBUFF_LEN;
}



//初始化IO 串口1 
//bound:波特率
void USART1_Init(uint32_t bound){ 
	
	//串口1初始化并启动
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
	 //USART1_TX   PA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.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 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器 
	//USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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);//开启ENABLE/关闭DISABLE中断
	USART_Cmd(USART1, ENABLE);                    //使能串口 
}

main.c

复制代码
#include "stm32f10x.h"   
#include "tjc_usart_hmi.h"
#include "stm32f10x_rcc.h"

#define FRAMELENGTH 6

void NVIC_Configuration(void);
void RCC_Configuration(void);

int main(void)
{
	RCC_Configuration();
	NVIC_Configuration();
	USART1_Init(115200);	  	 //串口初始化为115200
	TJCPrintf("\x00");          //为确保串口HMI正常通信
	
	
	while(1)
	{
	
	//stm32f103的GND接串口屏或串口工具的GND,共地
	//stm32f103的TX1(PA9)接串口屏或串口工具的RX
	//stm32f103的RX1(PA10)接串口屏或串口工具的TX
	//stm32f103的5V接串口屏的5V,如果是串口工具,不用接5V也可以
		
	//串口数据格式:
	//串口数据帧长度:6字节
	//帧头      led编号  LED状态    帧尾
	//0x55      1字节    1字节     0xffffff
	//例子1:上位机代码  printh 55 01 00 ff ff ff  含义:1号led关闭
	//例子2:上位机代码  printh 55 04 01 ff ff ff  含义:4号led打开
	//例子3:上位机代码  printh 55 00 01 ff ff ff  含义:0号led打开
	//例子4:上位机代码  printh 55 04 00 ff ff ff  含义:4号led关闭
	  while(usize >= FRAMELENGTH)
	  {
		  //校验帧头帧尾是否匹配
		  if(u(0) != 0x55 || u(3) != 0xff || u(4) != 0xff || u(5) != 0xff)
		  {
			  //不匹配删除1字节
			  udelete(1);
		  }else
		  {
			  //匹配,跳出循环
			  break;
		  }

	  }

	  //进行解析
	  if(usize >= FRAMELENGTH && u(0) == 0x55 && u(3) == 0xff && u(4) == 0xff && u(5) == 0xff)
	  {
		  TJCPrintf("msg.txt=\"led %d is %s\"", u(1), u(2) ? "on" : "off");
		  udelete(FRAMELENGTH);
	  }		

		//delay_ms(1000);
		
		
	}
	
}


void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}


void RCC_Configuration(void){ //RCC时钟的设置  
	ErrorStatus HSEStartUpStatus;   
	RCC_DeInit();              /* RCC system reset(for debug purpose) RCC寄存器恢复初始化值*/   
	RCC_HSEConfig(RCC_HSE_ON); /* Enable HSE 使能外部高速晶振*/   
	HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* Wait till HSE is ready 等待外部高速晶振使能完成*/   
	if(HSEStartUpStatus == SUCCESS){   
		/*设置PLL时钟源及倍频系数*/   
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //RCC_PLLMul_x(枚举2~16)是倍频值。当HSE=8MHZ,RCC_PLLMul_9时PLLCLK=72MHZ   
		/*设置AHB时钟(HCLK)*/   
		RCC_HCLKConfig(RCC_SYSCLK_Div1); //RCC_SYSCLK_Div1------AHB时钟 = 系统时钟(SYSCLK) = 72MHZ(外部晶振8HMZ)   
		/*注意此处的设置,如果使用SYSTICK做延时程序,此时SYSTICK(Cortex System timer)=HCLK/8=9MHZ*/   
		RCC_PCLK1Config(RCC_HCLK_Div2); //设置低速AHB时钟(PCLK1),RCC_HCLK_Div2------APB1时钟 = HCLK/2 = 36MHZ(外部晶振8HMZ)   
		RCC_PCLK2Config(RCC_HCLK_Div1); //设置高速AHB时钟(PCLK2),RCC_HCLK_Div1------APB2时钟 = HCLK = 72MHZ(外部晶振8HMZ)   
		/*注:AHB主要负责外部存储器时钟。APB2负责AD,I/O,高级TIM,串口1。APB1负责DA,USB,SPI,I2C,CAN,串口2,3,4,5,普通TIM */  
		FLASH_SetLatency(FLASH_Latency_2); //设置FLASH存储器延时时钟周期数   
		/*FLASH时序延迟几个周期,等待总线同步操作。   
		推荐按照单片机系统运行频率:
		0---24MHz时,取Latency_0;   
		24---48MHz时,取Latency_1;   
		48~72MHz时,取Latency_2*/   
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //选择FLASH预取指缓存的模式,预取指缓存使能   
		RCC_PLLCmd(ENABLE);	//使能PLL
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL输出稳定   
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择SYSCLK时钟源为PLL
		while(RCC_GetSYSCLKSource() != 0x08); //等待PLL成为SYSCLK时钟源   
	}  

代码很好理解,查看注释可知,可根据自己情况添加控制外设以及显示温湿度等函数

相关推荐
无垠的广袤4 小时前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟6 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞6 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲6 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up7 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技16 小时前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
单片机日志17 小时前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣18 小时前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法
小曹要微笑1 天前
STM32F7 时钟树简讲(快速入门)
c语言·stm32·单片机·嵌入式硬件·算法
XINVRY-FPGA1 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga