这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 求教 串口抓取字符串中特定字符遇到的问题

共2条 1/1 1 跳转至

求教 串口抓取字符串中特定字符遇到的问题

院士
2006-09-17 18:14:16     打赏
求教 串口抓取字符串中特定字符遇到的问题



关键词: 求教     串口     抓取     字符串     特定     字符     遇到     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问  小弟是个菜鸟,编写了一个抓取串口中特定字符的程序,但总是不能成功,望
各位大侠谁知道原因,敬请指点,谢谢!



/* 此程序为若接收字符串中有ok字符则发送stn[]数组中的内容,现在出现的问题是不能发送,经检查觉得有可能是串口中断程序有误。因为若直接将data_receive[rv_num]分别赋值0x4f 0x4b(字符ok的ascii码值),如程序中所示,则往串口输入任意两个字符,数组stn[]能从串口发送。但再三检查也
未发现问题出在哪里。另外,在串口中断里if((data_receive[rv_num]==0x4b)&&(flag_o)) 与 while(flag_o)两个程序段,我觉得意思是一样的,但实际运行时while程序段是不行的,我也不大明白 */


#include <reg51.h>

#define uchar unsigned char
#define uint unsigned int

uchar  idata data_receive[];
uchar  idata str[];
uchar  idata stn[]="at+csca=+8613800100500\r" ;
uchar rv_num=0;
bit flag_s=0;     //发送程序标志位
bit flag_o=0;     //接收到字母o标志位


void UART_Init(void);       //串口初始化
void UART_ISR(void);        //串口中断程序
void WriteGsm(uchar *str ); //发送字符串程序


void main(void)
{
  UART_Init();
  
  EA=1;
  while(1)
{ if(flag_s)
  {
   WriteGsm(stn);
   flag_s=0;
  }
}
}


void UART_Init(void)
{
SCON=0x50;     //串行口工作在方式1,并允许接收
TMOD=0x20;     // T1工作在方式2
TH1=0xe8;      // 1200波特率
TL1=0xe8;
TR1=1;
ES=1;         // 允许串口中断

}

void WriteGsm(uchar *str)
{ uchar i=0;
while(str[i]!=0x0d)  //当发送到有回车字符时停止发送
{
  SBUF=str[i];
  while(TI==0);
  TI=0;
  i++;
}

}


void UART_ISR(void)  interrupt 4  using 1
{
  uchar  d;

  
  if(!RI)
   return;
   RI=0;
  d=SBUF;
  data_receive[rv_num]=d;
//data_receive[rv_num]=0x4f;
  if((data_receive[rv_num]==0x4f)&&(!flag_o))  //当接收到字符o      并 且flag_o为0时
     {
      flag_o=1;
      goto next;                              //跳转到next
     }

//data_receive[rv_num]=0x4b;
  if((data_receive[rv_num]==0x4b)&&(flag_o))   //当接收到字符k,并且flag_o为1时
         flag_s=1;
       
         flag_o=0;
           
/*  while(flag_o)
    {
      
      if(data_receive[rv_num]==0x4b)   
         flag_s=1;
     
         flag_o=0;
           
    }
    */     



  next:  rv_num++;

}     
     1: 你这是AT命令有时你发送一条AT指令,回来的未必就是OK 2: 试试看void UART_ISR(void)  interrupt 4  using 1
{
  static uchar last_uchar=0;
  uchar  d;  
  if(RI)
  {   
    RI=0;
    d=SBUF;        
    if((last_uchar=='o')&&(d=='k'))
    {
         flag_s=1;
    }
    last_uchar = d;
  }
} 3: 回复 非常感谢二位大侠的帮助,目前我用到的at指令只有几个,都是能返回ok的。其次zgl7903大侠给的程序我会再调试看看。我比较不明白的就是我编的程序采用设标志位的方法,为何行不通,错在那里?因为我以后的程序都想采用这种方法来判断发给单片机的字符串中是否有我设定的字符。
再一次感谢 艾森豪威尔与zgl7903二位大侠的帮助 4: WriteGsm(uchar *str) 有错void WriteGsm(uchar *str)
{ //uchar i=0;
while(*str!=0x0d)//str[i]!=0x0d)  //当发送到有回车字符时停止发送
{
  SBUF=*str;SBUF=str[i];
  while(TI==0);
  TI=0;
  ++str;i++;
}

}

5: 回复 dwq175大侠指出的问题,我觉得可能没错。因为如果在串口中断中对data_receive[rv_num]赋初值'ok'后,可以正常输出字符串。
感谢dwq175大侠的热心帮助。 6: 用字符串搜索函数就可以了   #include    <string.h>

   char *pFind;
   pFind = strstr(Buffer,"OK");
   if(pFind != NULL)
   {
      // 找到OK
   } 7: re:while(str[i]!=0x0d)  //当发送到有回车字符时停止发送

使用at命令时,回车是作为字符串的结束标志的,它仍然需要发送到gsm模块中,而你的程序没有把这个回车字符发出去,当然得不到正确响应,也就得不到ok字符,于是发送程序也就得不到执行了。

8: 回复  昨天又在实验板上跑了一下,用zgl7903大侠的串口中断程序后,程序正常输出,但我编得串口中断程序却找不出错误,谁能发现问题请指点一下,谢谢!
另外汽车电子大侠说的用字符串搜索函数的回复,我基础可能有些差没有看懂,请问这能在单片机里实现吗?可否详细解释一下。
原野之狼大侠的提示很重要,我没有说清楚,现在我只是先用单片机实验板与计算机串口通讯,用串口调试助手察看是否正确输出字符串,等没有问题了,再
和短信模块通讯。不过这确实是一个错误,我会在以后的程序中将此改正。在此
感谢原野之狼大侠的热心帮助。 9: 不客气所谓字符串搜索函数 是编译器带的库函数
你查看安装文件夹能找到它的定义。 10: 回复 小弟使用的是keil c 编译软件,原野之狼大侠说的“在安装文件夹能找到它的定义”,我找了一下没有找到,可否再详细说一下,谢谢!还有编译器自带的库函数存在哪里,是在math.h里吗? 如果我调用的话是不是很占资源
11: 哈,用PC调试GSM/GPRS/CDMA模块时,串口通好用    串口通V3.22,超强功能...

   
    最新功能1: 接收区能混合显示ASCII和中文,ASCII和16进制,
    最新功能2: 能自定义设置5个换行符,显示纯16进制显示时能自动换行
    最新功能3: 发送前可选择自动换行或清空接收区...增加接收时间
    最新功能4: 可自定义300条常用的数据或命令,可自动轮巡发送或手动按次序发送选中的数据

    自动保存的路径可选,自动保存文件的大小可选。方便很多调试场合,更好地对事后的数据进行分析......
    自动保存最后配置,即打开软件时自动加载上次配置,方便...
    自动清空长度可选...
    此外,还可选择TB8作为多机通讯位...   
         
      
    特别功能: 发送/接收显示数据支持 16进制、10进制和ASCII码的混合输入,方便更多场合调试
    两个频率和占空比可调的低频简易矩形波发生器

     发送数据举例:
     例1: \x01\x23 \x90 \180\238 \xf0 1234567890 \n\r \xaa abcd可输出中文\r\n
     例2: AT+CIPSTART="TCP","168.168.168.168","1688" \r\n
     例3: AT+CIPSEND=1024\r\n
           输入发送命令和长度后,可直接输入10进制、16进制、ASCII和中文,到预定长度时自动发送...

     自发自收测试:115200波特率,无校验,每隔100ms发送第一次开机默认发送区的数据(546字节)。测试过程中,界面操作反应正常,接收显示与发送基本同步,一直测试到发送约200KB(接收区不清空),发送字节数与接收字节数相同。
12: re:math.h是数学函数头文件。
楼上某人说的查找函数是属于字符串函数,在标准c里有详细的介绍的,你可以看c语言的教材。
我不是很清楚keil里有没有这个函数,我在使用iccAVR时有这个函数,所以才这样说的。
keil应该也包含的,应该是在library之下,你可以以str作为关键字搜索一下你的电脑。
我水平很菜的,刚出道,不对之处请指教,大家互相学习。 13: 回复多谢二位的回答,我再找找看。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]