打印

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

[复制链接]
8434|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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 | 只看该作者
int main( void )
{
    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;
  
    uchar i;
   
    WDTCTL = WDTPW + WDTHOLD;           //关狗
    /*------选择系统主时钟为8MHz-------*/
    BCSCTL1 &= ~XT2OFF;                 //打开XT2高频晶体振荡器
    do
    {
        IFG1 &= ~OFIFG;                 //清除晶振失败标志
        for (i = 0xFF; i > 0; i--);     //等待8MHz晶体起振
    }
    while ((IFG1 & OFIFG));             //晶振失效标志仍然存在?
    BCSCTL2 |= SELM_2 + SELS;           //MCLK和SMCLK选择高频晶振
   
   
    //计数时钟选择SMLK=8MHz,1/8分频后为1MHz
    TACTL |= TASSEL_2 + ID_3;
  
    GPIO_Init(P2,DIR_OUTPUT);  //设置P2为输出模式  
   
    UART_Init(0);
   
    //打开全局中断
    _EINT();


     SIM900();

     while(1);
}

使用特权

评论回复
5
512826028|  楼主 | 2015-1-23 17:40 | 只看该作者
/*******************************************************************************
*描    述: 此文件包含操作GSM的所有函数
*GSM 模块:SIM900A
*控制芯片:MSP430F149
*
*******************************************************************************/
#include "include.h"

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

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

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


/*******************************************************************************
*SIM900初始化函数
*
*返回值:无
*测试通过时间:2015年1月22日22:58:54
*******************************************************************************/
void SIM900(void)
{

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

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

使用特权

评论回复
6
512826028|  楼主 | 2015-1-23 18:12 | 只看该作者
大家给帮忙分析一下吧

使用特权

评论回复
7
512826028|  楼主 | 2015-1-23 18:58 | 只看该作者
。。。。。

使用特权

评论回复
8
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 赞一个!
9
dirtwillfly| | 2015-1-23 22:30 | 只看该作者
henryetchou 发表于 2015-1-23 22:13
俺認為您的問題不在硬件問題,而可能再UART1BUF裡的字串函數判斷,如果您想糾錯,
俺有一個有效直捷的方法 ...

好谦虚啊。
我觉得也是单片机和模块间的串口匹配问题。
具体能否确认是不是这个问题,还需要楼主进一步测试。

使用特权

评论回复
10
luhshuay| | 2015-1-24 10:26 | 只看该作者
用串口助手直接控制下模块看是否能行?为什么命令后要加两个回车符呢?一个回车的吧

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
512826028 + 3 一个还是不行,不知道是和原因。.
11
ocon| | 2015-1-24 14:26 | 只看该作者
GSM模块执行AT指令需要时间,不同的指令响应时间不同,大多数在300ms之内能返回结果。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
512826028 + 3 恩,谢谢。我一开的时间确实没注意。我现在.
12
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 谢谢 已更正。
13
pmp| | 2015-1-25 00:21 | 只看该作者
清楚中断了?

使用特权

评论回复
14
angerbird| | 2015-1-25 16:28 | 只看该作者
需要看下是否真的收到OK字符的吧。

使用特权

评论回复
15
512826028|  楼主 | 2015-1-25 20:05 | 只看该作者
henryetchou 发表于 2015-1-23 22:13
俺認為您的問題不在硬件問題,而可能再UART1BUF裡的字串函數判斷,如果您想糾錯,
俺有一個有效直捷的方法 ...

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

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

让我郁闷的是,偶尔忘了取下编程器,程序有时候也会运行,不过,概率很小。

使用特权

评论回复
16
512826028|  楼主 | 2015-1-25 20:10 | 只看该作者
luhshuay 发表于 2015-1-24 10:26
用串口助手直接控制下模块看是否能行?为什么命令后要加两个回车符呢?一个回车的吧 ...

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

现在程序勉强可以运行,有些地方,还是需要在调整。

使用特权

评论回复
17
512826028|  楼主 | 2015-1-25 20:12 | 只看该作者
guangbiao 发表于 2015-1-24 17:53
while(strstr((char const*)USART1BUFF,"OK")==NULL)
    {
        UART_Clear_BUFF();

这个地方是有些不妥。我已经把用于延时和显示的led程序放到了发送之后,这样就有足够的时间接受应答信号了。

使用特权

评论回复
18
512826028|  楼主 | 2015-1-25 20:18 | 只看该作者
谢谢各位的帮忙!!!

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

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

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


使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
dirtwillfly + 2 赞一个!感谢分享
19
512826028|  楼主 | 2015-1-25 20:25 | 只看该作者
现在程序时可以运行了,但是还是发布出去短信。问题我想应该出现在通信上。

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

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

333.jpg (30.73 KB )

串口接收的数据

串口接收的数据

使用特权

评论回复
20
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

粉丝