单片机驱动GSM模块,遇到了个很棘手的问题!【已解决】

[复制链接]
8884|31
 楼主| 512826028 发表于 2015-1-23 17:37 | 显示全部楼层 |阅读模式
本帖最后由 512826028 于 2015-1-25 23:06 编辑

单片机是 MSP430F149  
GSM模块是 SIM900A

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

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

但是,如果让单片机按顺序,先发送AT指令,等到OK后,在发送ATE0指令,就不能继续运行了,第二个LED就一直都点不亮了。
 楼主| 512826028 发表于 2015-1-23 17:38 | 显示全部楼层
一开始,在网上搜了好久,连第一个握手都很难完成。

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

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

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

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

只是百思不得其解,不知道问题究竟出在哪里了。
 楼主| 512826028 发表于 2015-1-23 17:39 | 显示全部楼层
很让人郁闷的一个问题啊。。。求大家帮帮,看看有没有遇到过这种情况的呐。

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

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

我看别人的程序,连续发送,中间就隔了个3秒而已,没有其他的操作了。我中间也加上延时,还是不管用。
 楼主| 512826028 发表于 2015-1-23 17:39 | 显示全部楼层
  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.      SIM900();

  30.      while(1);
  31. }
 楼主| 512826028 发表于 2015-1-23 17:40 | 显示全部楼层
  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. }
 楼主| 512826028 发表于 2015-1-23 18:12 | 显示全部楼层
大家给帮忙分析一下吧
 楼主| 512826028 发表于 2015-1-23 18:58 | 显示全部楼层
。。。。。
henryetchou 发表于 2015-1-23 22:13 | 显示全部楼层
俺認為您的問題不在硬件問題,而可能再UART1BUF裡的字串函數判斷,如果您想糾錯,
俺有一個有效直捷的方法來兩分....
您把GSM TX串口接上回電腦的RS-232 RX,包率設置正確,用終端機或是串口助手監看,
肯定第二個指令是否有ACK回覆??回覆得是否真是OK??
假如有回覆,那就是strstr()程序判斷不嚴謹.如果沒回覆那麼就可以判定是發送指令的問題.
此時再把單片機串口TX接回電腦RX確認一下串口打印字串是否是對的??
另~GSM模塊除了包率設置外,有時會有校驗碼(Parity)停止字節(Stop bit)的設置差異,
確認單片機的UART串口這些設置都是謀合的....
P.S.俺是台灣來的,如有用語差異鬧笑話,請多海涵。

评分

参与人数 2威望 +5 收起 理由
512826028 + 3 谢谢了,大陆人都上书法课的,繁体字无压力.
ocon + 2 赞一个!

查看全部评分

dirtwillfly 发表于 2015-1-23 22:30 | 显示全部楼层
henryetchou 发表于 2015-1-23 22:13
俺認為您的問題不在硬件問題,而可能再UART1BUF裡的字串函數判斷,如果您想糾錯,
俺有一個有效直捷的方法 ...

好谦虚啊。
我觉得也是单片机和模块间的串口匹配问题。
具体能否确认是不是这个问题,还需要楼主进一步测试。
luhshuay 发表于 2015-1-24 10:26 | 显示全部楼层
用串口助手直接控制下模块看是否能行?为什么命令后要加两个回车符呢?一个回车的吧

评分

参与人数 1威望 +3 收起 理由
512826028 + 3 一个还是不行,不知道是和原因。.

查看全部评分

ocon 发表于 2015-1-24 14:26 | 显示全部楼层
GSM模块执行AT指令需要时间,不同的指令响应时间不同,大多数在300ms之内能返回结果。

评分

参与人数 1威望 +3 收起 理由
512826028 + 3 恩,谢谢。我一开的时间确实没注意。我现在.

查看全部评分

guangbiao 发表于 2015-1-24 17:53 | 显示全部楼层
while(strstr((char const*)USART1BUFF,"OK")==NULL)
    {
        UART_Clear_BUFF();
        led(2);
        //注意:此处必须为\R\N\R\N!!!
        UART_PutStr(0,"AT\r\n\r\n");
    }
这两个类似的循环会出大问题的:
1.只要判断没有“OK”就清接收缓存,如果我刚收到一个'O',后面的字节还没有收到时,缓存就被冲刷了。
2.只要判断没有“OK”,就一直重发相应AT命令。你这是在测试GSM模块的串口接收缓冲区有多大吧!!!!!!

评分

参与人数 2威望 +4 收起 理由
wyscjm + 1 很给力!
512826028 + 3 谢谢 已更正。

查看全部评分

pmp 发表于 2015-1-25 00:21 | 显示全部楼层
清楚中断了?
angerbird 发表于 2015-1-25 16:28 | 显示全部楼层
需要看下是否真的收到OK字符的吧。
 楼主| 512826028 发表于 2015-1-25 20:05 | 显示全部楼层
henryetchou 发表于 2015-1-23 22:13
俺認為您的問題不在硬件問題,而可能再UART1BUF裡的字串函數判斷,如果您想糾錯,
俺有一個有效直捷的方法 ...

谢谢了。 这个strstr()函数是系统库函数,用于在字符串中查找什么含有指定的字符串(即“OK”)。

这个问题现在算是差不多解决了,跟BSL编程器有关,我把编程器从开发板上取下,程序就可以运行了。

让我郁闷的是,偶尔忘了取下编程器,程序有时候也会运行,不过,概率很小。
 楼主| 512826028 发表于 2015-1-25 20:10 | 显示全部楼层
luhshuay 发表于 2015-1-24 10:26
用串口助手直接控制下模块看是否能行?为什么命令后要加两个回车符呢?一个回车的吧 ...

我不知道具体原因是什么,用串口调试助手调试,是一个回车的。
可是,当是用单片机发送时,一个就不起作用。而两个就可以起通过。

现在程序勉强可以运行,有些地方,还是需要在调整。
 楼主| 512826028 发表于 2015-1-25 20:12 | 显示全部楼层
guangbiao 发表于 2015-1-24 17:53
while(strstr((char const*)USART1BUFF,"OK")==NULL)
    {
        UART_Clear_BUFF();

这个地方是有些不妥。我已经把用于延时和显示的led程序放到了发送之后,这样就有足够的时间接受应答信号了。
 楼主| 512826028 发表于 2015-1-25 20:18 | 显示全部楼层
谢谢各位的帮忙!!!

问题出在BSL编程器上,我的BSL编程器,是我自己用CH340的USB串口改造的。把编程器从开发板上拆掉,程序就可以运行了。

对于上面各位说道的延时问题,我的程序中延时放置的确实不妥,我已将发送语句,移动到了用于延时的led()函数后面了。

唯独让人郁闷的是,有时来回改写程序,有可能会忘记拆掉编程序,程序有的时候,竟然也能运行。不过是小概率事件。


评分

参与人数 1威望 +2 收起 理由
dirtwillfly + 2 赞一个!感谢分享

查看全部评分

 楼主| 512826028 发表于 2015-1-25 20:25 | 显示全部楼层
现在程序时可以运行了,但是还是发布出去短信。问题我想应该出现在通信上。

单片机发送,GSM发送的数据同时发给单片机和串口调试助手,是这个样子。

GSM发回的数据里面有乱码。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 512826028 发表于 2015-1-25 22:44 | 显示全部楼层
本帖最后由 512826028 于 2015-2-21 00:04 编辑

额 现在这个乱码的原因找到了。

原来是我一开始都是使用ATE0这个关闭回显当做是握手信号了,后来我为了方便调试,就暂时把回显功能给注释了。

直到我连上串口,才发现GSM模块自己在疯狂的发送数据,就是这个数据,导致了串口调试助手接收不正常,也影响了串口中断正常接收GSM反馈的OK信号。


后期修改:2015年2月21日00:00:59
这个原因现在才搞明白,原来是GSM模块工作不稳定导致的。我买的这个模块对电源的要求有些苛刻。试过5v 0.7A的电源和5V  2A的电源,都不能稳定工作,电脑USB供电也是一会好一会差。后来用的5V 1A的手机充电器才保证了最起码的稳定工作。

因为这个东西的不稳定,调试程序时走了好多的弯路。希望大家也要注意,不要在硬件上犯低级的错误。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

本版积分规则

1

主题

45

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部