单片机操作GSM模块问题,程序无法执行,这是为什么?

512826028   2015-1-23 16:56 楼主
单片机是 MSP430  
GSM模块是 SIM900A

回复评论 (9)

程序中 单片机单独发送  AT指令,可以得到OK答复,单片机点亮第一个LED灯。

单片机单独发送ATE0指令,也可以得到OK答复,单片机点亮另一个LED灯。

但是,如果让单片机按顺序,先发送AT指令,等到OK后,在发送ATE0指令,就不能继续运行了,第二个LED就一直都点不亮了。
朱志强
点赞  2015-1-23 16:59
  1. void SIM900(void)
  2. {

  3.     UART_Clear_BUFF();
  4.     UART_PutStr(0,"AT\r\n\r\n");
  5.     while(strstr((char const*)USART1BUFF,"OK")==NULL)
  6.     {
  7.         UART_Clear_BUFF();
  8.         led(2);
  9.         //注意:此处必须为\R\N\R\N!!!
  10.         UART_PutStr(0,"AT\r\n\r\n");
  11.     }
  12.     GPIO_OUT(P2,0Xf7);//点亮一个LED灯,代表握手成功   

  13.     UART_Clear_BUFF();
  14.     UART_PutStr(0,"ATE0\r\n\r\n");
  15.     while(strstr((char const*)USART1BUFF,"OK")==NULL)
  16.     {
  17.         UART_Clear_BUFF();
  18.         led(4);
  19.         //注意:此处必须为\R\N\R\N!!!
  20.         UART_PutStr(0,"ATE0\r\n\r\n");
  21.     }
  22.     GPIO_OUT(P2,0Xfe);//点亮一个LED灯,代表握手成功
  23. }


程序部分,应该没有问题,因为单独都可以握手成功。唯独就是这样,两个顺序放一块,就不能继续运行了。
朱志强
点赞  2015-1-23 17:04
是时候亮出你的代码了,show me the code
点赞  2015-1-23 17:05
一开始,在网上搜了好久,连第一个握手都很难完成。

网上有人说单片机是3.3V的,模块是3.5-5V的,串口的电平不兼容。我是直接用的TTL直连,中间也没有用232电平转换芯片。

当时从网上看到,有一种简易的电平转换,就是用一个三极管,自己也就动手做了一个,没有什么效果,还是不能握手成功。

后来,偶然一个想法,就是修改了一下程序,在后面多了一个“\r\n”,结果,程序就可以握手成功了。就是上面程序中看到的这个样子了。

然后,我就再添加第二条指令,但是,程序每次都只是执行完成第一个,到了第二条指令,就陷入死循环,那个LED就闪个没完。把两条指令反过来,还是只能执行第一条,到了第二条就卡住了。

只是百思不得其解,不知道问题究竟出在哪里了。
朱志强
点赞  2015-1-23 17:11
引用: sint27 发表于 2015-1-23 17:05
是时候亮出你的代码了,show me the code

还需要别的代码吗?我贴上

  1. /*******************************************************************************
  2. *描    述: 此文件包含操作GSM的所有函数
  3. *GSM 模块:SIM900A
  4. *控制芯片:MSP430F149
  5. *
  6. *******************************************************************************/
  7. #include "include.h"

  8. extern uchar USART1BUFF[];//重新声明一下其他函数中定义的USART1BUFF数组

  9. extern void UART_Clear_BUFF(void);
  10. //外部声明过的函数 0 UART1,1 UART2,str为字符串指针
  11. extern void UART_PutStr(uchar uartx, char *str);
  12. extern void UART_PutChar(uchar uartx, char ch);
  13. extern void DelayNms(unsigned char n);
  14. extern void DelayNs(unsigned char n);
  15. extern void led(int i);
  16. extern void GPIO_OUT(uchar px, uchar data8);
  17. extern void UART_Init(uchar uartx);

  18. char *ATE0="ATE0\r\n\r\n";//清除GSM模块回显


  19. /*******************************************************************************
  20. *SIM900初始化函数
  21. *
  22. *返回值:无
  23. *测试通过时间:2015年1月22日22:58:54
  24. *******************************************************************************/
  25. void SIM900(void)
  26. {

  27.     UART_Clear_BUFF();
  28.     UART_PutStr(0,"AT\r\n\r\n");
  29.     while(strstr((char const*)USART1BUFF,"OK")==NULL)
  30.     {
  31.         UART_Clear_BUFF();
  32.         led(2);
  33.         //注意:此处必须为\R\N\R\N!!!
  34.         UART_PutStr(0,"AT\r\n\r\n");
  35.     }
  36.     GPIO_OUT(P2,0Xf7);//点亮一个LED灯,代表握手成功   

  37.     UART_Clear_BUFF();
  38.     UART_PutStr(0,"ATE0\r\n\r\n");
  39.     while(strstr((char const*)USART1BUFF,"OK")==NULL)
  40.     {
  41.         UART_Clear_BUFF();
  42.         led(4);
  43.         //注意:此处必须为\R\N\R\N!!!
  44.         UART_PutStr(0,"ATE0\r\n\r\n");
  45.     }
  46.     GPIO_OUT(P2,0Xfe);//点亮一个LED灯,代表握手成功
  47. }

主程序里面,没有什么东西,就是一个单独的SIM900程序。

  1. int main( void )
  2. {
  3.     // Stop watchdog timer to prevent time out reset
  4.     WDTCTL = WDTPW + WDTHOLD;
  5.   
  6.     uchar i;
  7.    
  8.     WDTCTL = WDTPW + WDTHOLD;           //关狗
  9.     /*------选择系统主时钟为8MHz-------*/
  10.     BCSCTL1 &= ~XT2OFF;                 //打开XT2高频晶体振荡器
  11.     do
  12.     {
  13.         IFG1 &= ~OFIFG;                 //清除晶振失败标志
  14.         for (i = 0xFF; i > 0; i--);     //等待8MHz晶体起振
  15.     }
  16.     while ((IFG1 & OFIFG));             //晶振失效标志仍然存在?
  17.     BCSCTL2 |= SELM_2 + SELS;           //MCLK和SMCLK选择高频晶振
  18.    
  19.    
  20.     //计数时钟选择SMLK=8MHz,1/8分频后为1MHz
  21.     TACTL |= TASSEL_2 + ID_3;
  22.   
  23.     GPIO_Init(P2,DIR_OUTPUT);  //设置P2为输出模式  
  24.    
  25.     UART_Init(0);
  26.    
  27.     //打开全局中断
  28.     _EINT();

  29.     //while(1);
  30.    
  31.     /******************************
  32.     此部分,已调试成功
  33.     2015年1月22日22:39:52
  34.     while(strstr((char const*)USART1BUFF,"OK")==NULL)
  35.     {
  36.         //uchar  ii;
  37.         UART_Clear_BUFF();
  38.         led(2);
  39.         UART_PutStr(0,"ATE0\r\n\r\n");
  40.         
  41.     }
  42.    
  43.    
  44.     ********************************/
  45.      SIM900();

  46.      while(1);
  47. }




朱志强
点赞  2015-1-23 17:14
很让人郁闷的一个问题啊。。。

如果第一次发送AT,第二次发送ATE0指令,程序可以执行完第一个(AT),到了第二个指令时,就卡住了。

如果第一次发送ATE0,第二次发送AT指令,程序也是可以执行完第一个(ATE0),卡在第二个指令上。

我看别人的程序,连续发送,中间就隔了个3秒而已,没有其他的操作了。我中间也加上延时,还是不管用。
朱志强
点赞  2015-1-23 17:30
我翻了一下AT指令,ATE0是表示取消回显吧,这样你就得不到OK了,你可以试下ATE0改成AT
点赞  2015-1-23 17:35
引用: sint27 发表于 2015-1-23 17:35
我翻了一下AT指令,ATE0是表示取消回显吧,这样你就得不到OK了,你可以试下ATE0改成AT


       ATE0 是取消回显,意思是什么都不要,只要显示0K。、

      例如: 原来指令是  AT
               串口得到的是 AT
                                     0K

               发送了指令  ATE0
               串口得到的  ATE0
                                  OK

               再发送指令  AT
     串口就直接得到     OK(第一次的回显 AT指令那一行不见了)。

朱志强
点赞  2015-1-23 17:47
大家有什么好的方法没有呀?
朱志强
点赞  2015-1-23 18:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复