stm32串口通信,收发字符串,并对其进行解析

串口以字符串接收和发送

将传输的数据转化为整数(正负)

stm32发送端

	motor_position = Read_Encoder_Angle(Encoder);
  	sensor_position = Get_Adc_Average_Angle(Adc);
    motor_velocity = Read_Encoder_Speed(Encoder);
	sensor_velocity = Get_Adc_Average_Speed(); 
	sprintf(data_str, "%-8.4f, %-8.4f, %-8.4f, %-8.4f\n", motor_position , sensor_position , motor_velocity , sensor_velocity );
	Usart_SendString(USART1, data_str);

stm32接收端

接收数据格式为:\t16900\r\n,其中第一位“\t”为帧头,第二位数据1为奇偶校验位,最后两位数据"\r\n"为帧尾,中间数据为实际传输数据,即“6900”。

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res = USART_ReceiveData(USART1);	//读取接收到的数据 0x2D,0x31,0x30,0x30,0x30,0x0D,0x0A

				if((USART_RX_STA&0x8000)==0)//接收未完成
					{
					if(USART_RX_STA&0x4000)//接收到了0x0D
						{
							if(Res!=0x0A){
								USART_RX_STA=0;//接收错误,重新开始
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA|=0x8000;	//接收完成了
								
								check_flag = count_odd_numbers(2);
								USART_RX_BUF[1] = USART_RX_BUF[1] - '0';
								if(USART_RX_BUF[0] == '\t'&& USART_RX_BUF[1] == check_flag ) // 判断帧头是否正确、判断奇偶校验位是否正确 || USART_RX_BUF[1] == check_flag
								{
									float value = 0;
									int16_t sign = 1;
										int a = 2;
											for (int i = a; i < (USART_RX_STA&0X3FFF); i++) {
												 value = value * 10 + USART_RX_BUF[i] - '0';		
											}
											action = sign * value;
											USART_RX_STA = 0;	
											memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA = 0;	
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
						}								
						}
					else //还没收到0X0D
						{	
							if(Res==0x0D)
								USART_RX_STA|=0x4000;
							else
								{					
										USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
										USART_RX_STA++;
										if(USART_RX_STA>(USART_REC_LEN-1))
										{
											USART_RX_STA=0;//接收数据错误,重新开始接收
											memset(USART_RX_BUF,0,USART_REC_LEN);
										}					
								}		 
						}
					}

				 } 
}

将传输的数据转化为浮点数(正负)

stm32发送端

	motor_position = Read_Encoder_Angle(Encoder);
  	sensor_position = Get_Adc_Average_Angle(Adc);
    motor_velocity = Read_Encoder_Speed(Encoder);
	sensor_velocity = Get_Adc_Average_Speed(); 
	sprintf(data_str, "%-8.4f, %-8.4f, %-8.4f, %-8.4f\n", motor_position , sensor_position , motor_velocity , sensor_velocity );
	Usart_SendString(USART1, data_str);

stm32接收端

接收数据格式为:\t11.0246\r\n,其中第一位“\t”为帧头,第二位数据1为奇偶校验位,最后两位数据"\r\n"为帧尾,中间数据为实际传输数据,即“1.0246”。

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	

	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res = USART_ReceiveData(USART1);	//读取接收到的数据 0x2D,0x31,0x30,0x30,0x30,0x0D,0x0A

				if((USART_RX_STA&0x8000)==0)//接收未完成
					{
					if(USART_RX_STA&0x4000)//接收到了0x0D
						{
							if(Res!=0x0A){
								USART_RX_STA=0;//接收错误,重新开始
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA|=0x8000;	//接收完成了
								
								check_flag = count_odd_numbers(2);
								USART_RX_BUF[1] = USART_RX_BUF[1] - '0'; // 串口接收的是ASCII码,将其与'0'作差,则获得相应的整数。
								if(USART_RX_BUF[0] == '\t'&& USART_RX_BUF[1] == check_flag ) // 判断帧头是否正确、判断奇偶校验位是否正确 || USART_RX_BUF[1] == check_flag
								{
									float value = 0;
									int16_t sign = 1;
										int a = 2;
										if(USART_RX_BUF[2] == '-')
										{
											sign = -1;
											a = 3;
										}
											for (int i = a; i < (USART_RX_STA&0X3FFF); i++) {
												if(USART_RX_BUF[i] != '.')
											{
												 value = value * 10 + USART_RX_BUF[i] - '0';	
												 value +=  (USART_RX_BUF[i] - '0') * pow(10, -(i - a));
											}
												else
												{
													a = a+ 1;
												}
												
											}
											action = sign * value;
											USART_RX_STA = 0;	
											memset(USART_RX_BUF,0,USART_REC_LEN);
							}
							else{
								USART_RX_STA = 0;	
								memset(USART_RX_BUF,0,USART_REC_LEN);
							}
						}								
						}
					else //还没收到0X0D
						{	
							if(Res==0x0D)
								USART_RX_STA|=0x4000;
							else
								{					
										USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
										USART_RX_STA++;
										if(USART_RX_STA>(USART_REC_LEN-1))
										{
											USART_RX_STA=0;//接收数据错误,重新开始接收
											memset(USART_RX_BUF,0,USART_REC_LEN);
										}					
								}		 
						}
					}

				 } 
}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,用于在STM32收发字符串: ```c #include "stm32f10x.h" #include <stdio.h> #include <string.h> // 定义串口接口 #define USARTx USART1 #define USARTx_CLK RCC_APB2Periph_USART1 #define USARTx_GPIO_CLK RCC_APB2Periph_GPIOA #define USARTx_RxPin GPIO_Pin_10 #define USARTx_TxPin GPIO_Pin_9 #define USARTx_GPIO GPIOA // 定义波特率 #define USARTx_BAUDRATE 115200 // 声明函数 void USART_Config(void); void USART_SendString(char* str); void USART_SendChar(char c); char USART_ReceiveChar(void); void delay_ms(uint32_t n); int main(void) { USART_Config(); char buffer[100]; while (1) { // 发送字符串 USART_SendString("Enter a string:\r\n"); // 接收字符串 int index = 0; while (1) { char c = USART_ReceiveChar(); if (c == '\r' || c == '\n') { buffer[index] = '\0'; break; } else { buffer[index++] = c; USART_SendChar(c); } } // 输出接收到的字符串 USART_SendString("\r\nYou entered: "); USART_SendString(buffer); USART_SendString("\r\n"); // 延时 delay_ms(1000); } } void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 使能GPIO和串口时钟 RCC_APB2PeriphClockCmd(USARTx_GPIO_CLK | USARTx_CLK, ENABLE); // 配置串口引脚 GPIO_InitStructure.GPIO_Pin = USARTx_TxPin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(USARTx_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USARTx_RxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USARTx_GPIO, &GPIO_InitStructure); // 配置USART USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE; 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(USARTx, &USART_InitStructure); // 使能USART USART_Cmd(USARTx, ENABLE); } void USART_SendString(char* str) { while (*str) USART_SendChar(*str++); } void USART_SendChar(char c) { while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); USART_SendData(USARTx, c); } char USART_ReceiveChar(void) { while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET); return USART_ReceiveData(USARTx); } void delay_ms(uint32_t n) { uint32_t i; for (i = 0; i < n * 8000; i++); } ``` 在这个示例代码中,我们使用了USART1作为串口接口,并定义了发送和接收字符串的函数。主函数中,我们循环接收字符串并输出收到的字符串。为了防止串口输出过快,我们在每次输出之后延时1秒。在编写代码时,请注意修改GPIO引脚和波特率等参数,以适配您的硬件配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值