STM32多字节发送与接收(附淘晶驰串口屏教程)

由于本人做题目时发现正点原子的串口发送教程是单字节,也在网上找了许多案例,但都不是很满意,这里借鉴了一下B站江科大UP主的代码,结合自己的需求,改了一下,大家可以参考一下,讲的很好,话不多说,直接上代码,希望帮助更多小伙伴。同时哪里不对的地方望大神多多指教。

usart.c

头文件自己添加

#if 1
#pragma import(__use_no_semihosting)



uint8_t Serial_TxPacket[4];				//FF 01 02 03 04 FE
uint8_t Serial_RxPacket[4];   
uint8_t Serial_RxFlag;



//标准库需要的支持函数
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));
}
*/

//#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA = 0;     //接收状态标记
char rxarray[4];
uint8_t rxlength=0;

//字符串发送函数
void HMISends(char *buf1)		  
{
	u8 i=0;
	while(1)
	{
		if(buf1[i] != 0)
	 	{
			USART_SendData(USART1,buf1[i]);  //发送一个字节
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束
		 	i++;
		}
		else
		{
			return ;
		}
	}
}

//字节发送函数
void HMISendb(u8 k)		         
{		 
	u8 i;
	 for(i=0; i<3; i++)
	 {
			if(k != 0)
			{
				USART_SendData(USART1,k);  //发送一个字节
				while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束
			}
			else
			{
				return ;
			}
	 } 
} 





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, ENABLE); //使能USART1,GPIOA时钟

    //USART1_TX   GPIOA.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);//初始化GPIOA.9

    //USART1_RX   GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10

    //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;//串口波特率
    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); //初始化串口1
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
    USART_Cmd(USART1, ENABLE);                    //使能串口1

}
void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}
void Serial_SendPacket(void)   //发送字头
{
	Serial_SendByte(0xFF);
	Serial_SendArray(Serial_TxPacket, 4);
	Serial_SendByte(0xFE);
}

uint8_t Serial_GetRxFlag(void)   //读取状态位
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}
char tjcstr[100];
void USART1_IRQHandler(void)
{
	int a=9;
	static uint8_t RxState = 0;
	static uint8_t pRxPacket = 0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		uint8_t RxData = USART_ReceiveData(USART1);
//		printf ("%d",RxData);
		if (RxState == 0)
		{
			if (RxData == 0xFF)
			{
				RxState = 1;
				pRxPacket = 0;
			}
		}
		else if (RxState == 1)
		{
			Serial_RxPacket[pRxPacket] = RxData;
			pRxPacket ++;
			if (pRxPacket >= 4)
			{
				RxState = 2;
			}
		}
		else if (RxState == 2)
		{
			if (RxData == 0xFE)
			{
				RxState = 0;
				Serial_RxFlag = 1;
			}
		}
		
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

usart.h

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

#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			1		//使能(1)/禁止(0)串口1接收

extern u8  USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA;         		//接收状态标记
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
extern char rxarray[4];
extern uint8_t rxlength;


extern uint8_t Serial_TxPacket[];
extern uint8_t Serial_RxPacket[];
void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);
void Serial_Printf(char *format, ...);

void Serial_SendPacket(void);
uint8_t Serial_GetRxFlag(void);

#endif

大家需要注意的是发送数据格式,当然包头包尾自己可以改下哈。

格式:FF 12 45 67 89 FE

我们发送的数据都被数组接收了,那怎样打印出来尼,看大招。

while(1)
{

  if (Serial_GetRxFlag() == 1)
      {
	     for(i=0;i<4;i++)
			 {
			   printf ("%x", Serial_RxPacket[i]);
		      }
			
	  }
}

方法2

if(rxlength == 4)
		{
			//int rxint = (rxarray[0] << 24) | (rxarray[1] << 16) | (rxarray[2] << 8) | (rxarray[3]);
			//printf("get %c,%c,%c,%c",rxarray[0],rxarray[1],rxarray[2],rxarray[3]);
		
			union tmpa2i
			{
			char tmpa[4];
			int tmpi;				
			}
			tmpa2i1;

			tmpa2i1.tmpa[0] = rxarray[0];
			tmpa2i1.tmpa[1] = rxarray[1];
			tmpa2i1.tmpa[2] = rxarray[2];
			tmpa2i1.tmpa[3] = rxarray[3];
			int rxint = tmpa2i1.tmpi;
			printf("\x01\xff\xff\xffpage2.n7.val=%d\xff\xff\xff",rxint);
			rxlength = 0;
		}

他们的原理都差不多,都是数组接收,打印的方式不一样罢了,方法2是串口屏给单片机发送数据时写的,大家如果使用的是串口屏的话推荐看方法2。

如果还是看不懂,建议大家看看江科大的视频。

需要源代码的伙伴评论区聊吧。

淘晶驰串口屏是一种用于STM32应用的显示屏,它有多个系列和尺寸可供选择。其中包括T1系列、K0系列、X2系列、X3系列和X5系列。每个系列都有不同的功能选型和特性。 T1系列串口屏的尺寸包括1.8寸、2.4寸、2.8寸和3.5寸。K0系列串口屏即将停产,尺寸包括2.4寸、2.8寸、3.5寸、4.3寸、5.0寸和7.0寸。X2系列串口屏的尺寸为4.3寸和7.0寸。X3系列串口屏的尺寸为4.3寸、5.0寸和7.0寸。X5系列串口屏的尺寸包括4.0寸、4.3寸、5.0寸、7.0寸、8.0寸和10.1寸。 不同系列的串口屏具有不同的功能选项。例如,X5系列具有控件图层保持、页面加载特效、滑动翻页、控件加载特效、控件移动、控件触摸拖动、控件半透明、PNG透明图片、PNG图片抗锯齿、百变指针、指针抗锯齿等功能。而X3系列、X2系列、K0系列和T1系列也有各自的功能选项。 在使用淘晶驰串口屏时,需要在初始化后添加相应的代码。例如,可以添加USART1_IRQHandler函数来处理串口中断,以及使能IDLE中断和启用DMA接收函数来接收数据。 总之,淘晶驰串口屏是一种适用于STM32应用的显示屏,具有多个系列和尺寸可供选择,并且具有不同的功能选项和特性。 #### 引用[.reference_title] - *1* [淘晶驰串口屏产品简单介绍](https://blog.csdn.net/Tjc1688com/article/details/124789963)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [stm32+cubemx+淘晶驰串口屏+收发通信并应用](https://blog.csdn.net/lili66666aini/article/details/119190942)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值