OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3496|回复: 10

浅析串口通信

[复制链接]

3

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
366
金钱
366
注册时间
2015-1-27
在线时间
43 小时
发表于 2016-3-18 22:12:37 | 显示全部楼层 |阅读模式
       就像很多论坛里面的并肩作战的同仁们说的那样,一直在论坛里潜水,从未有过贡献。自己也是在不断泡论坛的过程中,将自己对程序的理解上升到一定实践经验,对原子哥的赞美,咱也不想再说了,群里的坛友们已经能把我能想到的赞美的话全部来形容了原子哥,我这只有简单的两个字:谢谢。谢谢一直以来,原子哥在耐心的回复一些列问题,简单的,复杂的。读书育人,说的就是原子哥吧!       直接切入正题,前几天手头正好有个项目,是串口同喜的,加上简单的协议,开始也没有多想,原子哥的程序还是不错的,拿来直接用就行了啊!程序是最终跑起来了,但是发现整体联机的效果不尽如人意。最终调试下来发现,我一块MCU不断地在实时发数据,另外一块MCU需要不断地进入中断处理,所以实时性上收到一定的影响,再不断地询问老工程师的经验和在论坛里面的坛友,最终采用状态机加循环接收队列来完成,效果比之前好一些了!我想可能会有一些坛友会碰到类似的问题,我这算是抛砖引玉,也权当是为论坛做一些自己的绵薄之力,希望论坛越办越好,多出一些具有实战经验程序,早日超越PUDN。
void USART2_IRQHandler(void)   
{
          u8 res;
          static u8 n = 0;
          if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //½óêÕÖD¶Ï(½óêÕμ½μÄêy¾Y±ØDëêÇ0x0d 0x0a½áÎ2)
                {
                  res = USART_ReceiveData(USART2);
            //printf("%c",res);                       
                  switch(Recv_Status)
                        {
                          case RECV_START_HEAD1:
                                          if(res == 0xAA)
                                      Recv_Status =  RECV_START_HEAD2;                                                       
                                break;
                               
                                case RECV_START_HEAD2:
                                    if(res == 0x55)                                                       
                                      Recv_Status = RECV_ENQUEUE;
                                                  n = 0;
                                break;
                               
                                case RECV_REAR1:
                                         if(res == 0x0D)
                                                 Recv_Status = RECV_REAR2;
                                break;                       
                                case RECV_REAR2:
                                           if(res == 0x0A) // íêÕûμÄò»Ö¡êy¾YêÕíê
                                                {
                                                       
                                                        Recv_Status = RECV_START_HEAD1;
                                                        Write_Cnt++;
                                                        if(Write_Cnt>3)
                                                                Write_Cnt = 0;
                                                }                
                                break;
                                case RECV_ENQUEUE:
                RDS_BUF[Write_Cnt*8+n] = res;
                                        n = n+1;
                                        if(n == 8)
                                              {
                                                                        Recv_Status = RECV_REAR1;
                                                                  //printf("%x-%x-%x-%x-%x-%x-%x-%x\r\n",RDS_BUF[Write_Cnt*8+0],RDS_BUF[Write_Cnt*8+1],RDS_BUF[Write_Cnt*8+2],RDS_BUF[Write_Cnt*8+3],RDS_BUF[Write_Cnt*8+4],RDS_BUF[Write_Cnt*8+5],RDS_BUF[Write_Cnt*8+6],RDS_BUF[Write_Cnt*8+7]);
                                                                }
                                break;
                                default:
                                break;               
                        }
                }
}

//======================================================================================

//======== ===============================================================================================
void RDS_Process(void) //
{
        u8 RDS_TX_NEW_STATUS;
  RDS_TX_NEW_STATUS = (QND_READ(STATUS2) & 0x80);
        if(RDS_TX_STATUS != RDS_TX_NEW_STATUS) // ¿éòÔ·¢
        //if(read_cnt != Write_Cnt)
  {
                //printf("B");
                RDS_TX_STATUS = RDS_TX_NEW_STATUS;
                QND_RDSLoadData(&RDS_BUF[read_cnt*8],1);
                RDS_TX_TRIG();
                read_cnt+=1;
                read_cnt = read_cnt%4;
  }       
}

//======================================================================================
程序比较简单,但是理念我觉得很不错,串口处理函数将协议解析,串口接收全部涵盖在里面,所以个人认为有一定的实战意义,献丑了


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-3-18
在线时间
6 小时
发表于 2016-3-18 22:47:01 | 显示全部楼层
恩,自己经常用循环缓冲区的方案。状态机也是一个不错的选择。
回复 支持 1 反对 0

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-3-19 02:16:55 | 显示全部楼层
不错的想法!值得参考
回复 支持 反对

使用道具 举报

15

主题

317

帖子

0

精华

高级会员

Rank: 4

积分
863
金钱
863
注册时间
2015-2-12
在线时间
354 小时
发表于 2016-3-19 08:26:25 | 显示全部楼层
没有很详细看,感觉这程序有不足之处:当消息体为变长推送时,接收处理是否有点麻烦?
回复 支持 反对

使用道具 举报

3

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
366
金钱
366
注册时间
2015-1-27
在线时间
43 小时
 楼主| 发表于 2016-3-19 09:13:10 | 显示全部楼层
csmjmcc 发表于 2016-3-19 08:26
没有很详细看,感觉这程序有不足之处:当消息体为变长推送时,接收处理是否有点麻烦?

个人认为串口通信本身就不适合发长消息,程序确实有不完善之处,我循环发送的只有12个字节,所以暂时不存在写指针写了一圈又超过了读指针的情况。这种情况其实也应该在应用层处理的。感谢指点
回复 支持 反对

使用道具 举报

15

主题

317

帖子

0

精华

高级会员

Rank: 4

积分
863
金钱
863
注册时间
2015-2-12
在线时间
354 小时
发表于 2016-3-19 09:33:17 | 显示全部楼层
淋哥儿 发表于 2016-3-19 09:13
个人认为串口通信本身就不适合发长消息,程序确实有不完善之处,我循环发送的只有12个字节,所以暂时不存 ...

我说的“变长”是指:消息体非定长(固定字节)的。另外,还得考虑消息突然中止推送之情形,即超时处理。
个人看法,实属探讨。请指正!
回复 支持 反对

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1837
金钱
1837
注册时间
2014-6-27
在线时间
981 小时
发表于 2016-3-19 11:17:24 | 显示全部楼层
淋哥儿 发表于 2016-3-19 09:13
个人认为串口通信本身就不适合发长消息,程序确实有不完善之处,我循环发送的只有12个字节,所以暂时不存 ...

接收数据数量不固定是常有的情况,要么你在数据格式协议就考虑到了,或者从串口接收来考虑,无妨方式如何,能正确接收变长数据就行了。FIFO,只要总体你读的速度比写的速度快,一般它是写不满的,FIFO深度设置稍微深一点也能满足了。
回复 支持 反对

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11554
金钱
11554
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-3-19 11:40:14 | 显示全部楼层

改天发个变长度的方案。


回复 支持 反对

使用道具 举报

3

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
366
金钱
366
注册时间
2015-1-27
在线时间
43 小时
 楼主| 发表于 2016-3-19 12:59:21 | 显示全部楼层
TinyBoy 发表于 2016-3-19 11:17
接收数据数量不固定是常有的情况,要么你在数据格式协议就考虑到了,或者从串口接收来考虑,无妨方式如何 ...

多谢指点!
回复 支持 反对

使用道具 举报

3

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-1-26
在线时间
11 小时
发表于 2016-3-19 13:27:07 | 显示全部楼层
DDDDDDD
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-3-19 13:50:48 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 04:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表