最近要写个串口间通信的程序,要求PC端输入消息到串口1,然后stm32内部把该消息通过串口2转发出去,串口2得到消息返回,则通过串口1打印在PC端。实际上总体效果就是要是连接了设备的串口2具有串口1的功能,以便观察设备返回的信息以作后续的处理。
使用的芯片是stm32l151,采用中断接收方式,把串口2所收到的消息全部打印出来。
一开始直接参考原子的程序以接收回车键判断接收一次数据结束,实际上这样做的话会导致丢失大量信息,因为信息中可能还含有回车键。于是,便采用100ms连续接收的方式判断一次数据是否接收完成。如果两个数据之间的时间间隔超过100ms,则可以认为这两个数据不属于同一条消息了。这种机制的实现方法可以有很多,可以用定时器,也可以用简单的延时程序。在这里我用的是延时程序。
至于中断程序,因为采用的是100ms连续接收的方法,所以在中断处理中就可以简单很多了,不用判断是否收到了0x0a,0x0d之类的符号,只需要把数据寄存器里的内容保存起来就可以了。
因为串口2接的是设备,希望保存所以设备返回的信息,所以需要采用这种方法,而串口1的中断两种处理方法都可以(回车键和100ms延时)
串口2中断处理如下:
void USART2_IRQHandler(void)
{
char res;
if(__HAL_USART_GET_FLAG(&UartHandle2, USART_FLAG_RXNE) != RESET)//½ÓÊÕµ½Êý¾Ý
{
res =(uint16_t)(USART2->DR & (uint16_t)0x01FF);
if(USART2_RX_STA<800) //»¹¿ÉÒÔ½ÓÊÕÊý¾Ý
{
USART2_RX_BUF[USART2_RX_STA]=res; //¼Ç¼½ÓÊÕµ½µÄÖµ
USART2_RX_STA++;
}
}
}
下面是判断接收完成的程序
int USART2_Scan(void)
{
uint16_t ftemp=0,i;
ftemp = USART2_RX_STA;
if( ftemp != 0 )
{
HAL_Delay( 100 );
while ( ftemp != USART2_RX_STA )
{
ftemp = USART2_RX_STA;
HAL_Delay( 100 );
}
for ( i = 0; i <= ftemp+1; i++ )
{
RX2_Buff[i] = USART2_RX_BUF[i];
}
USART2_RX_STA = 0; /* ÖØÖÃÖ¸Õë */
return 1;
}
USART2_RX_STA=0;
return 0;
}
稍微解释一下上面的程序,
USART2_RX_STA是串口2接收缓存区的指针,在中断中该指针会随着接收消息而不断往后移
首先用一个临时指针指向它,然后用一个100ms的延时,如果还没接收完成的话
USART2_RX_STA会继续往后指,而ftemp还是原来的值,所以就可以通过判断延时后的两者是否还相等来判断是否接收完成了,如果100ms过了两个指针还相等,那么毫无疑问接收已经完成了。要再程序中调用串口2接收的内容,只需要判断这个函数的返回值即可。接收到的内容保存了在RX2_Buff数组里。
上一篇:stm32+neo6m GPS模块定位系统
下一篇:STM32开发 -- UART应用层通信协议分析
推荐阅读最新更新时间:2024-03-16 16:13