> 技术文档 > STM32与陶晶驰串口屏交互_陶晶驰串口屏链接stm32

STM32与陶晶驰串口屏交互_陶晶驰串口屏链接stm32


1、串口屏界面设计

1.新建工程

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

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

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

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

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

 Program.s

//以下代码只在上电时运行一次,一般用于全局变量定义和上电初始化数据int sys0=0,sys1=0,sys2=0 //全局变量定义目前仅支持4字节有符号整形(int),不支持其他类型的全局变量声明,如需使用字符串类型可以在页面中使用变量控件bauds=115200 //配置波特率为115200dim=100 //配置亮度100bkcmd=0printh 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 #include #include #include #include \"tjc_usart_hmi.h\"#include #include #define STR_LENGTH 100typedef 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 = 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.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure); //USART1_RX PA.10GPIO_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 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3NVIC_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 6void NVIC_Configuration(void);void RCC_Configuration(void);int main(void){RCC_Configuration();NVIC_Configuration();USART1_Init(115200); //串口初始化为115200TJCPrintf(\"\\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);//使能PLLwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL输出稳定 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择SYSCLK时钟源为PLLwhile(RCC_GetSYSCLKSource() != 0x08); //等待PLL成为SYSCLK时钟源 } 

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