糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > STM32与GSM800A调试记录

STM32与GSM800A调试记录

时间:2022-05-02 07:23:12

相关推荐

STM32与GSM800A调试记录

最近在做一个项目,调试单片机与GSM(我这里用的是GSM800A)通信时遇到问题。

实现功能:单片机控制GSM模块发送短信(很基础的功能)。用的的是AT指令,还有就是GSM模块启动工作流程。

当我们要开始动手干活时,首先要想着,整个流程时怎么样的?要用到那些知识?一步一步慢慢来,细心的来。就上边的功能来看。可能是这样一套流程:

(1)当我们选取了GSM模块之后,知道它与单片机之间是以串口的方式通信的,那么我们需要做好串口代码工作,并调试好,确保无误。

(2)详细阅读GSM模块的手册,知道它的一整套工作流程。假如我要发送短信:我就需要GSM模块初始化–>获取GSM模块初始化状态–>检测电话卡是否插入–>如果插入正常就进入发短信状态。

(3)细节实现:AT指令呐,用串口软件调试呐……

刚开始都是准备自己干的。结果部分来新人了,领导就安排GSM模块的调试部分给他做,然后新同事给我给了他封装好的代码,接口函数。我就拿过来测试,有问题。慢慢找。找着找着找到如下问题:

发送AT指令函数如下:

/** 函数名:GSMSendAtCmd* 描述 :发送AT指令* 输入 :-cmd被发送字符* 输入 :-size被发送数据长度* 输出 :无* 返回 :无*/void GSMSendText(unsigned char* cmd, u8 size){u8 i;for(i=size; i>0; i--){GSMSendChar(cmd[i]);}}

…………………………………………………………………………………………………………

/** 函数名:GSMInit* 描述 :GSM初始化* 输入 :无* 输出 :无* 返回 :发送短信状态*/u8 GSMInit(void){char * cmd = "AT\r\n";clean_rebuff();GSMSendAtCmd(cmd, sizeof(cmd));return GSM_GET_INIT_STATUS;}

…………………………………………………………………………………………………………

/** 函数名:GSMCheckCard* 描述 :GSM检查电话卡状态* 输入 :无* 输出 :无* 返回 :发送短信状态*/u8 GSMCheckCard(){char * cmd = "AT+CNUM\r\n";//同事写的//char cmd[] = "AT+CNUM\r\n"; //我修改的clean_rebuff();GSMSendAtCmd(cmd,sizeof(cmd));//发送电话卡检查命令 gsm.out_times = 0;//初始化超时次数return GSM_GET_CARD_STATUS;}

以上是两个函数,初始化GSM模块,要发送AT指令给GSM模块,也就是串口发送"AT\r\n"给GSM模块。

上边的函数存在的问题:

先看GSMSendAtCmd()这个函数。这样的实现,岂不是将cmd数组中的内容倒着发过去了么?

我修改成了以下的代码,刚开始学习C语言的时候,我就喜欢用for(i=0; i<size; i++)的方式去做延时,而不喜欢for(i=size; i>0; i–)这样的方式,但是用于简单的空跑,延时,是没有区别的,但是这里区别大了。发现问题,修改,心里嘿嘿。

/** 函数名:GSMSendAtCmd* 描述 :发送AT指令* 输入 :-cmd被发送字符* 输入 :-size被发送数据长度* 输出 :无* 返回 :无*/void GSMSendText(unsigned char* cmd, u8 size){u8 i;for(i=0; i<size; i++){GSMSendChar(cmd[i]);}}

可是还是有问题。继续查找。GSMInit()函数中,定义了指针变量,指向了需要发送给GSM模块的指令。刚开始没有发现什么毛病。char * cmd = “AT\r\n”; 与 GSMSendAtCmd(cmd, sizeof(cmd));

和GSMCheckCard()函数中char * cmd = “AT+CNUM\r\n”; 与 GSMSendAtCmd(cmd,sizeof(cmd));

注意:sizeof(cmd)一直为4哎,(在32位平台上,它是指针变量哎)。所以说:在GSMInit()中,发送了"AT\r\n"。但是没有发送‘\0’;而在GSMCheckCard()函数中,指令没有被正常发送,只发送了"AT+C"。我就把cmd定义成了数组,来解决这个问题。

………………………………………………………………………………………………………………

上边问题解决之后,下边又来问题了。程序没有安装理论上来。我就在中断中放了一个发送到屏幕的函数,显示一下,我可以看 。结果,越来越懵逼。什么问题呢?

串口接收数据不完整。很懵逼,因为我串口测试好的哎,回环测试都正常的。

之前老听别人讲,中断中不要放太多的东西,尽可能让中断简洁。放代码:

void USART3_IRQHandler(void){u8 res; if(USART_GetITStatus(GSM_USART, USART_IT_RXNE) != RESET) //接收到数据{res =USART_ReceiveData(GSM_USART); //读取接收到的数据if(gsm.recv_cnt < GSM_BUFF_SIZE)//防止缓冲区溢出{gsm.recv_buff[gsm.recv_cnt]=res;//记录接收到的值//array[gsm.recv_cnt] = res;gsm.recv_cnt++;//接收数据增加1 }SetTextInt32(0,8,gsm.recv_cnt,1,0);//因为我放的这个代码,导致数据接收不完整。这个代码实现由好多代码去实现的.实现过程如下://SetTextValue(0,9,array);//USART_ClearITPendingBit (GSM_USART, USART_IT_RXNE); //只有在多缓存通信中,才推荐清除。} }

………

//这个函数中实现过程太多了,发送指令太多,太耗时。原本6个字节的数据,在波特率115200的时候我只能收到//2个字节的数据,当波特率在9600的时候,就可以收到5个自己的数据了。当把SetTextInt32(0,8,gsm.recv_cnt,1,0);去掉的时候就会正常。void SetTextInt32(uint16 screen_id,uint16 control_id,uint32 value,uint8 sign,uint8 fill_zero){BEGIN_CMD();TX_8(0xB1);TX_8(0x07);TX_16(screen_id);TX_16(control_id);TX_8(sign?0X01:0X00);TX_8((fill_zero&0x0f)|0x80);TX_32(value);END_CMD();}

如果觉得《STM32与GSM800A调试记录》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。