打印
[应用相关]

stm32串口间通信(转载)

[复制链接]
679|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
guanjiaer|  楼主 | 2019-7-5 08:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近要写个串口间通信的程序,要求PC端输入消息到串口1,然后stm32内部把该消息通过串口2转发出去,串口2得到消息返回,则通过串口1打印在PC端。实际上总体效果就是要是连接了设备的串口2具有串口1的功能,以便观察设备返回的信息以作后续的处理。

使用的芯片是stm32l151,采用中断接收方式,把串口2所收到的消息全部打印出来。

一开始直接参考原子的程序以接收回车键判断接收一次数据结束,实际上这样做的话会导致丢失大量信息,因为信息中可能还含有回车键。于是,便采用100ms连续接收的方式判断一次数据是否接收完成。如果两个数据之间的时间间隔超过100ms,则可以认为这两个数据不属于同一条消息了。这种机制的实现方法可以有很多,可以用定时器,也可以用简单的延时程序。在这里我用的是延时程序。

至于中断程序,因为采用的是100ms连续接收的方法,所以在中断处理中就可以简单很多了,不用判断是否收到了0x0a,0x0d之类的符号,只需要把数据寄存器里的内容保存起来就可以了。

因为串口2接的是设备,希望保存所以设备返回的信息,所以需要采用这种方法,而串口1的中断两种处理方法都可以(回车键和100ms延时)


使用特权

评论回复
沙发
guanjiaer|  楼主 | 2019-7-5 08:55 | 只看该作者
串口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++;
                }
        }                               
}

使用特权

评论回复
板凳
guanjiaer|  楼主 | 2019-7-5 08:55 | 只看该作者
下面是判断接收完成的程序
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;
}

使用特权

评论回复
地板
guanjiaer|  楼主 | 2019-7-5 08:55 | 只看该作者
稍微解释一下上面的程序,

USART2_RX_STA是串口2接收缓存区的指针,在中断中该指针会随着接收消息而不断往后移
首先用一个临时指针指向它,然后用一个100ms的延时,如果还没接收完成的话<pre name="code" class="cpp">USART2_RX_STA会继续往后指,而ftemp还是原来的值,所以就可以通过判断延时后的两者是否还相等来判断是否接收完成了,如果100ms过了两个指针还相等,那么毫无疑问接收已经完成了。
要再程序中调用串口2接收的内容,只需要判断这个函数的返回值即可。接收到的内容保存了在RX2_Buff数组里。

使用特权

评论回复
5
爰有树檀| | 2019-10-16 22:28 | 只看该作者
可以避免0x0d,0x0a结束一次接收导致的数据丢失,但这种方法只适用于接收数据有明显时间间隔的情况,不适用于RX端收到数据频繁且随机的情况。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

4116

帖子

2

粉丝