USART空闲中断发送一帧完整的数据包(适合新手学习)

USART发送一帧完整的数据包

项目描述:

用一块STM32F103C8T6核心板(作为发送板)ADC采集来自手柄的电压信号,然后将数据发送给另一块STM32F103C8T6核心板(作为接收板)。最终,接收板在上位机(电脑)上打印出发送板采集到的电压信号。

硬件:

两块STM32F103C8T6核心
上位机(电脑)
摇杆(工具人,提供个电压信号)

发送板程序

int main()
{
	u16 valuex=0;
	u16 valuey=0;
	u8 a[4];
	float volx,voly;
	int i;
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	USART1_Init(9600);
	ADCx_Init();
	while(1)
	{
		valuex=Get_ADC_Value(ADC_Channel_1,10);
		valuey=Get_ADC_Value(ADC_Channel_2,10);
		a[0]=valuex;
		a[1]=valuex>>8;
		a[2]=valuey;
		a[3]=valuey>>8;
		for(i=0;i<4;i++)
		{
			USART_SendData(USART1,a[i]);
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
		}
			delay_ms(500);
	}
}

由于USART_SendData函数只能发送8位,所以说我们的两个u16的数据需要各自发送第八位和高八位数据,总共四个数据。如果是四个数据,一个一个的发,就会很慢,而且也无法判断这四个数据的先后顺序,导致接收板根本无法使用。
所以要发送一帧数据。发送一帧数据的有点就是很快,因为连续发四个数据只产生一次中断,四个数据之后才需要delay。而如果一个数据一个数据的发,要产生4次中断,要有4个delay,在对收发数据的速度有要求的场景下必须这样发送一整帧数据。发送一帧数据的方法有很多,现在介绍的是用空闲中断法,比较适合新手入门使用。

容易忽略的点:
for(i=0;i<4;i++)
		{
			USART_SendData(USART1,a[i]);
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
		}

这里的while不可省,这句是等待上一次发送完成再发送下一个数据。如果没有这句,就无法达到每次发四个数据,发完四个数据再delay一下的效果了。

while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);

接收版程序

接收板的程序主要就是配置空闲中断,以及将数据printf出来。

u8 a[4]={0,0,0,0};
int j=0;
u16 temp,valuex,valuey;
float x,y;
void USART1_IRQHandler(void)  
{
	u8 clear=clear;
	USART_ClearFlag(USART1,USART_FLAG_TC);
		if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
		{
		a[j++]=USART1->DR;	
		}
	else if (USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=RESET)
	{
		clear=USART1->SR;
		clear=USART1->DR;
		valuex=a[0]+a[1]*256;
		x=(float)valuex*(3.3/4096);
		valuey=a[2]+a[3]*256;
		y=(float)valuey*(3.3/4096);
		printf("volx: %.2f\r\n",x);
		printf("voly: %.2f\r\n",y);
		j=0;
	}
}
接收中断:
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
		{
		a[j++]=USART1->DR;	
		}

这里a[j++]=USART1->DR; 就是把接收数据寄存器中的数据存进数组里,在这个过程结束的同时USART_IT_RXNE标志位也会reset(应该是硬件自动reset的),等待下一个数据发来。
a[j++]=USART1->DR;和a[j++]=USART_ReceiveData函数几乎是一样的,因为USART_ReceiveData函数里边主要就是“a[j++]=USART1->DR;”这一句。

空闲中断:
else if (USART_GetFlagStatus(USART1,USART_FLAG_IDLE)!=RESET)
	{
		clear=USART1->SR;
		clear=USART1->DR;
		valuex=a[0]+a[1]*256;
		x=(float)valuex*(3.3/4096);
		valuey=a[2]+a[3]*256;
		y=(float)valuey*(3.3/4096);
		printf("volx: %.2f\r\n",x);
		printf("voly: %.2f\r\n",y);
		j=0;
	}
}

用clear去先后读取SR(状态寄存器),DR(数据寄存器)这一步的作用是重置空闲中断的标志位。然后下面是,我们直接在这个空闲中断中进行了数据的处理,发送。
定义clear变量的时候,使用了clear=claer的作用是,防止编译时出warning,提示我们clear变量没有使用。

数据处理:

高八位乘256+第八位就可以复原数据。
*3.3/4096是因为我收集到的电压的范围是0~3.3V,这是处理ADC采集到的数据。

容易出错的地方:

不要忘记使能空闲中断!!!要在初始化函数中加上这一句

USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); 

另外注意:不要在中断函数的其它位置处理数据,因为处理数据需要时间,可能处理数据的过程中就会丢掉正在发来的下一个数据,导致整个接收过程都出问题。可以自己再写一个数据处理和发送的函数,或者就在空闲中断里处理,发送数据,因为我们主函数delay了10ms,时间足够。

工程文件压缩包已上传,可免费下载!

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: F407的USART空闲中断是指当USART接收缓冲区中无数据时,即数据传输完成时触发的中断。在使用空闲中断前,需要先初始化USART,并使能空闲中断。初始化USART可以参考以下代码: ``` USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStruct); ``` 使能空闲中断的方法如下: ``` USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); ``` 在中断服务函数中,可以通过以下方式判断是否触发了空闲中断: ``` if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) { // 空闲中断处理代码 USART_ReceiveData(USART1); // 读取USART数据寄存器以清除中断标志 } ``` 需要注意的是,中断服务函数需要在启用全局中断之后才能正常工作,可以使用以下函数开启全局中断: ``` __enable_irq(); ``` ### 回答2: F407是一款STM32系列的微控制器,其中具有USART通信接口。USART(通用同步/异步收发传输器)是一种串行通信协议,允许微控制器与外部设备进行高效的数据传输。 F407 usart空闲中断是指当USART接口传输数据完成后,当数据线上出现空闲状态时触发的中断空闲状态是指数据线上连续一段时间内没有任何数据传输。在此时,微控制器可以利用空闲中断来及时响应数据的接收,并进行后续的处理。 F407的USART空闲中断可以通过编程的方式来实现,并且需要进行以下几个步骤: 1. 配置USART接口的工作模式和波特率,使其能够与外部设备相适应。 2. 开启USART接收中断空闲中断。 3. 在中断服务函数中,判断是否触发了空闲中断。可以通过读取USART的状态寄存器来判断是否接收到了数据,并检查空闲标志位是否被置位。 4. 如果触发了空闲中断,则可以读取USART接收寄存器中的数据,并进行后续的处理,例如解析数据、执行相应的操作等。 5. 最后,清除空闲标志位,并重新使能接收中断。 通过使用F407的USART空闲中断,我们可以实现高效的数据接收和处理,提高系统的响应速度和性能。同时,由于中断的方式,可以减少对处理器的占用,在处理大量数据时尤为重要。 ### 回答3: F407 usart空闲中断是指在F407系列单片机USART通信接口中,当接收到数据并且一段时间内没有继续接收到新的数据时触发的中断。 在USART通信中,当数据传输完毕后会触发空闲中断空闲中断是指接收器接收端口完成了所有接收操作并且停止接收数据。正常情况下,在接收到每个字节的数据时,都会触发接收中断,即使多个字节的数据被连续接收也是如此。但是,在接收完最后一个字节之后,如果一段时间内没有接收到新的数据,就会触发空闲中断空闲中断可以用来判断数据的接收是否完成。在空闲中断中,我们可以进行相应的处理操作,例如读取接收缓冲区中的数据并进行处理,或者设置标志位表示数据接收完成等。 要使用F407 usart空闲中断,首先需要初始化USART通信接口,并使能空闲中断。在接收到数据时,会自动触发中断并跳转到相应的中断服务函数中进行处理。 总之,F407 usart空闲中断是一种在USART通信接口中利用空闲状态来触发的中断机制,用于判断数据接收是否完成,并进行相应的处理操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值