STM32串口接收不定长数据

STM32串口接收不定长数据

1.配置串口

void USART1_Config(void)
{
	//初始化使用的端口 A9->TX   A10->Rx
	//初始化GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART1_InitStructure;	
	//使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置波特率等
	USART1_InitStructure.USART_BaudRate = 115200;
	USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//None
	USART1_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//
	USART1_InitStructure.USART_Parity = USART_Parity_No;//No
	USART1_InitStructure.USART_StopBits = USART_StopBits_1;//1
	USART1_InitStructure.USART_WordLength = USART_WordLength_8b;//8b
	//配置
	USART_Init(USART1,&USART1_InitStructure);
//	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	//使能
	USART_Cmd(USART1,ENABLE);
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
}

2.配置串口中断

void NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//配置串口中断	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
	//DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
}

3.配置串口中断响应函数

/************定义联合体的意义是接收字节数>1的数,如浮点数**************/
/***********对于一帧多个字节数据可以直接使用数组来接受就OK了,不需要用联合体****/
union DataType{
	unsigned char s[4];
	unsigned int data;
}RxDataType;//共用内存地址思想,详见C语言

void USART1_IRQHandler(void)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_0 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_0)));
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//是否接受到一个字节
	{
		RxDataType.s[RxCounter++] = USART1->DR;
	}
	if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//是否接受到一帧
	{
		USART1->SR;
		USART1->DR;						
		RxCounter=0;
	}
}

代码解释如上注释

以下为测试使用代码

串口发送代码

	GPIO_WriteBit(GPIOB,GPIO_Pin_0 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_0)));//LED闪烁辅助观察
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//是否接受到一个字节
	{
		RxDataType.s[RxCounter++] = USART1->DR;
	}
	if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//是否接受到一帧
	{
		USART1->SR;
		USART1->DR;//这两句是清除状态位的,必须加上。如果提示未使用,定义一个uint8_t变量存储返回值即可						
		RxCounter=0;//一帧数据存储完毕,清零

STM32串口发送代码:

/***************这里我是定义外部中断使能发送的,可以直接发这段代码放在主函数while循环中也可以***/

void EXTI1_IRQHandler(void)
{
	GPIO_WriteBit(GPIOB,GPIO_Pin_1 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_1)));
	USART_SendData(USART1,0xAA);
	delay_ms(1);
	USART_SendData(USART1,RxDataType.s[0]);
	delay_ms(1);
	USART_SendData(USART1,RxDataType.s[1]);
	delay_ms(1);
	USART_SendData(USART1,RxDataType.s[2]);
	delay_ms(1);
	USART_SendData(USART1,RxDataType.s[3]);
	delay_ms(1);
	USART_SendData(USART1,0xFF);
	delay_ms(1);
	for(c = 0;c < 4;++c)
	{
		RxDataType.s[c] = 0;
	}
	EXTI_ClearITPendingBit(EXTI_Line1);
}

演示效果:
默认情况下,STM32发送给电脑的数据应该是0,对应的16进制应该是

AA 00 00 00 00 FF

初始状态发送0
当电脑发送11给STM32之后,STM32接收到数据并回传给电脑:

之所以接收到AA 11 00 00 00 FF后,数据变为了AA 00 00 00 00 FF,是因为我这边设置了发送一次之后即将所有位设置为0,代码见“发送代码”	
for(c = 0;c < 4;++c)
{
	RxDataType.s[c] = 0;
}


当电脑发送22 22给STM32之后,STM32接收到数据并回传给电脑:


当电脑发送88 88 88 88给STM32之后,STM32接收到数据并回传给电脑

其他

**在上位机和下位机之间发送和接收float、double类型的数据使用联合体即可**
  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值