OpenEdv-开源电子网

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

串口数据接收问题

[复制链接]

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2011-4-28
在线时间
0 小时
发表于 2011-5-13 16:34:30 | 显示全部楼层 |阅读模式
我现在有这样一串数据:$GPGGA,065805.00,3957.1842,N,11615.9249,E,1,04,2.20,00085,M,-006,M,,*43   要同时判断接收到这$GPGGA这六个字符之后,才决定是否接收后面的数据,怎么弄,给个建议,谢谢!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-5-13 16:55:19 | 显示全部楼层
接收一个字符检测一下。就可以了。连续收到$GPGGA就继续,否则放弃。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2011-4-28
在线时间
0 小时
 楼主| 发表于 2011-5-13 17:17:02 | 显示全部楼层
我现在能接收一个字符,但是想接收五个之后再做判断,就不行,算法还没整对。
回复 支持 反对

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2011-4-28
在线时间
0 小时
 楼主| 发表于 2011-5-19 11:29:49 | 显示全部楼层
回复【3楼】hrj寒江蓑笠:
-------------------------------
问题解决:在接收中断里面自己写算法。
void USART1_IRQHandler(void)
{
u8 res;     
if(USART1->SR&(1<<5))//接收到数据
{  
res=USART1->DR; 
if((USART_RX_STA&0x80)==0)//接收未完成
  {

 if(res=='$')
 {  
   RX_num=0;
   USART_RX_BUF[RX_num++]=res;
 }
     else
{
    if(RX_num)
    {
 USART_RX_BUF[RX_num++]=res;
 if(RX_num==6)
  {
    if((USART_RX_BUF[1]=='G')&&(USART_RX_BUF[2]=='P')&&(USART_RX_BUF[3]=='G')&&(USART_RX_BUF[4]=='G')&&(USART_RX_BUF[5]=='A'))
     USART_RX_STA&=0x40;
 else
 USART_RX_STA=0;  //接收数据错误,重新开始接收
  }

}
    if(RX_num>63) {RX_num=0; USART_RX_STA|=0x80;} //接收完成了 
}
 }   
         
}    
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-5-19 11:43:36 | 显示全部楼层
恭喜
回复 支持 反对

使用道具 举报

98

主题

408

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2010-12-14
在线时间
0 小时
发表于 2011-5-19 11:53:58 | 显示全部楼层
回复【4楼】hrj寒江蓑笠:
回复【3楼】hrj寒江蓑笠:
-------------------------------
问题解决:在接收中断里面自己写算法。
void USART1_IRQHandler(void)
{
u8 res;     
if(USART1->SR&(1<<5))//接收到数据
{  
res=USART1->DR; 
if((USART_RX_STA&0x80)==0)//接收未完成
  {
 if(res=='$')
 {  
   RX_num=0;
   USART_RX_BUF[RX_num++]=res;
 }
     else
{
    if(RX_num)
    {
 USART_RX_BUF[RX_num++]=res;
 if(RX_num==6)
  {
    if((USART_RX_BUF[1]=='G')&&(USART_RX_BUF[2]=='P')&&(USART_RX_BUF[3]=='G')&
......
-------------------------------
测试一下引用回复
希望openedv能给大家提供一个友好的技术交流平台!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2011-5-22
在线时间
0 小时
发表于 2011-5-22 00:24:18 | 显示全部楼层
正点原子的串口程序太恶心了,非要换行回车发送才能接收。我改了一下,在主循环处理串口接收,用定时器判断超时.
void UART1_SendByte(u8 dat)

    USART1->DR = (u8) dat;       
    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
}
void UART1_SendStr(char *str)

    while (1) 
    { 
        if (*str == '\0') 
        { 
            break; // 遇到结束符,退出 
        }
        UART1_SendByte(*str++); 
    }
}
void UART1SendBytes(u8 *buffer, u16 size)

    while(size--) { 
        USART1->DR =*buffer++; 
        while ((USART1->SR&0X40)==0); 
    }
}
void USART1_IRQHandler(void)
{      
    if(USART1->SR&(1<<5))//接收到数据 
    { 
        if(iCom1RecvCount==0) UART1_Rx_Flag =1; 
        cCom1RecvBuf[iCom1RecvCount] = USART1->DR;     
        iCom1RecvCount++; 
        iCom1RecvCount  %= MAX_UART_RECV_BUFF;           
    }    

void roSerialProtocol(char *pStrcmd, unsigned short iRecvcnt)

    if(iRecvcnt > 255)  { 
    sprintf(strp, "%s", pStrcmd); 
    UART1_SendStr(strp); 
    } 
    else{ 
        if( !strcmp( pStrcmd, "$scan" ) || !strcmp( pStrcmd, "$scan\r\n" ) ) { 
            sprintf(strp,"scan mod\r\n"); 
            UART1_SendStr(strp); 
       }
       else if( !strcmp( pStrcmd, "$ver" ) || !strcmp( pStrcmd, "$ver\r\n" ) ) { 
           UART1_SendStr((char *)cVersion);
       }
       else if( !strcmp( pStrcmd, "$bye" ) || !strcmp( pStrcmd, "$bye\r\n" ) ) { 
        UART1_SendStr("bye\r\n");
       } 
    }
}  
void roSerial1(void)
{
if(bCom1RecvOver) {
delay_ms(20);
  if(iCom1RecvCount > 0) {
  cCom1RecvBuf[iCom1RecvCount] = 0;
  ProSerialProtocol((char *)cCom1RecvBuf, iCom1RecvCount);
  bCom1RecvOver = 0;
  iCom1RecvCount = 0;
  }
}
}
void TIM3_IRQHandler(void)

            
if(TIM3->SR&0X0001){//溢出中断
tcount++;
if(tcount>=50) {
tcount = 0;
SYS_LED=!SYS_LED;
}
if(UART1_Rx_Flag){
UART1_COUNT++;
if(UART1_COUNT>=2) {
bCom1RecvOver = 1;
UART1_Rx_Flag = 0;
UART1_COUNT = 0;
}
}                    
}    
TIM3->SR&=~(1<<0);//清除中断标志位      
}
void SYS_Init(void)
{
Stm32_Clock_Init(9);  //系统时钟设置
delay_init(72);       //延时初始化 
uart_init(72,57600);   //串口初始化为57600
LED_Init();      //初始化与LED连接的硬件接口 
SYS_LED = 1; 
tcount = 0;
iCom1RecvCount = 0;
bCom1RecvOver = 0;
UART1_Rx_Flag = 0;
UART1_COUNT = 0;
//Timerx_Init(5000,7199); //10Khz的计数频率,计数到5000为500ms  
Timerx_Init(100,7199); //10Khz的计数频率,计数到100为10ms 
// SYS_LED = 0; 

}
int main(void)
{  
SYS_Init();
UARTSendDebugInfo();
while(1)
{
ProSerial1();

}  
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-5-22 01:17:09 | 显示全部楼层
回复【7楼】jimwin:
-----------------------------------------------------------------------
呵呵,你的方法不错.
不过我的方法也谈不上恶心吧?
有的时候用回车键表示结束,是一个不错的方法.
你用过finsh/shell/usmart么?用过你就知道回车键的作用了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

90

帖子

0

精华

初级会员

Rank: 2

积分
146
金钱
146
注册时间
2012-7-27
在线时间
1 小时
发表于 2012-8-28 14:52:14 | 显示全部楼层
各有个的好处,又多了就知道了
回复 支持 反对

使用道具 举报

13

主题

91

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
235
金钱
235
注册时间
2012-11-17
在线时间
18 小时
发表于 2013-2-2 18:06:10 | 显示全部楼层

是我错了,是我自己的问题……

回复 支持 反对

使用道具 举报

头像被屏蔽

2

主题

164

帖子

1

精华

禁止访问

积分
1316
金钱
1316
注册时间
2012-5-13
在线时间
127 小时
发表于 2013-2-3 10:07:16 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-22 06:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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