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();
}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值