单片机是 MSP430
GSM模块是 SIM900A
程序中 单片机单独发送 AT指令,可以得到OK答复,单片机点亮第一个LED灯。
单片机单独发送ATE0指令,也可以得到OK答复,单片机点亮另一个LED灯。
但是,如果让单片机按顺序,先发送AT指令,等到OK后,在发送ATE0指令,就不能继续运行了,第二个LED就一直都点不亮了。
是时候亮出你的代码了,show me the code
一开始,在网上搜了好久,连第一个握手都很难完成。
网上有人说单片机是3.3V的,模块是3.5-5V的,串口的电平不兼容。我是直接用的TTL直连,中间也没有用232电平转换芯片。
当时从网上看到,有一种简易的电平转换,就是用一个三极管,自己也就动手做了一个,没有什么效果,还是不能握手成功。
后来,偶然一个想法,就是修改了一下程序,在后面多了一个“\r\n”,结果,程序就可以握手成功了。就是上面程序中看到的这个样子了。
然后,我就再添加第二条指令,但是,程序每次都只是执行完成第一个,到了第二条指令,就陷入死循环,那个LED就闪个没完。把两条指令反过来,还是只能执行第一条,到了第二条就卡住了。
只是百思不得其解,不知道问题究竟出在哪里了。
还需要别的代码吗?我贴上
- /*******************************************************************************
- *描 述: 此文件包含操作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灯,代表握手成功
- }
主程序里面,没有什么东西,就是一个单独的SIM900程序。
- 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();
- //while(1);
-
- /******************************
- 此部分,已调试成功
- 2015年1月22日22:39:52
- while(strstr((char const*)USART1BUFF,"OK")==NULL)
- {
- //uchar ii;
- UART_Clear_BUFF();
- led(2);
- UART_PutStr(0,"ATE0\r\n\r\n");
-
- }
-
-
- ********************************/
- SIM900();
- while(1);
- }
很让人郁闷的一个问题啊。。。
如果第一次发送AT,第二次发送ATE0指令,程序可以执行完第一个(AT),到了第二个指令时,就卡住了。
如果第一次发送ATE0,第二次发送AT指令,程序也是可以执行完第一个(ATE0),卡在第二个指令上。
我看别人的程序,连续发送,中间就隔了个3秒而已,没有其他的操作了。我中间也加上延时,还是不管用。
我翻了一下AT指令,ATE0是表示取消回显吧,这样你就得不到OK了,你可以试下ATE0改成AT
ATE0 是取消回显,意思是什么都不要,只要显示0K。、
例如: 原来指令是 AT
串口得到的是 AT
0K
发送了指令 ATE0
串口得到的 ATE0
OK
再发送指令 AT
串口就直接得到 OK(第一次的回显 AT指令那一行不见了)。