A40 - 基于51单片机的GSM模块优化设计

任务

  1. 基于STC89C52系列51单片机(内存有限)
  2. 使用GSM模块(SIM800,GA6等,目前支持移动卡,部分地区关闭了2G网络则无法使用)
  3. 采用LCD1602显示相关信息,如Phone number,message等。

实物

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

资料内容

在这里插入图片描述
在这里插入图片描述

源代码

主函数

/*******************************************************************************

* 文件名称:基于STM32的智能生态鱼缸

* 实验目的:1.

* 2.

* 程序说明:完整程序Q:2772272579;@: [email protected]

* 日期版本:本项目分享关键细节,熟悉使用单片机的可做参考代码。完整讲解+源代码工程可联系获取,可定制。

*******************************************************************************/
#include "config.h"
#include "lcd1602.h"
#include "UART.H"  
#include "gsmA6.h"
#include "Timer0.h"

sbit k1=P2^0;
void Key_Touch(void)
{
    
    
	if(k1==0){
    
    
		Delay_ms(20);
		if(k1==0)
		{
    
    
			write_string(1,0,"Send:13956413848");
			write_string(2,0," Sending    SMS ");
			if(GSMA6_text_message("13956413848","SMS System ,Made By Zhang Hu") == 1)
			{
    
    
				write_string(1,0,"Send:13956413848");
				write_string(2,0," successfully!  ");
			}
			else
			{
    
    
				write_string(1,0,"Send:13956413848");
				write_string(2,0," fail  in send! ");
			}
			Delay_ms(3000);
			write_string(1,0,"GSM Init Success");
			write_string(2,0,"Waiting      SMS");
		}
		while(k1==0);
	}
}

void main()
{
    
    
	Init_1602();
	UART_Init();
	Timer0Init();
	Delay_ms(5000);
	if(GSMA6_Init() == 1) //初始化成功
	{
    
    
		write_string(1,0,"GSM Init Success");
		write_string(2,0,"Waiting      SMS");
	}
	else
	{
    
    
		write_string(1,0,"  Sorry ,GSMA6  ");
		write_string(2,0,"SysTemInit Error");
	}
	while(1)
	{
    
    
		GSMA6_ReadMessageTest();
		Key_Touch();
	}
}

优化的GA6驱动

由于51单片机内存不足,无法使用大内存数组存放串口获取到的GSM反馈信息,故而需要极为慎重的分配内存资源,防止出现内存溢出。需要合理分配单片机内存的使用,尽量减少变量。

#include "gsmA6.h"
#include <stdio.h>
#include <string.h>
#include "delay.h"
#include "lcd1602.h"

bit is_getGsmData=0;

char xdata GSMA6_RECEICV_BUFFER[GSMA6_USART_REC_LEN];
u8 GSMA6_point = 0;
void GSMA6_Receive_Byte(char res)
{
    
    
	/*发现个很严重的问题,这模块回馈信息不知道怎么回事有0x00,就算我清空用的是255,数组接收中依然有0x00,而这个又代表字符串结束符,导致strstr直接使用时strlen判定字符串长度变成了0*/
	if(res != 0x00)
	{
    
    
		GSMA6_RECEICV_BUFFER[GSMA6_point++] = res;
		if(GSMA6_point>6)
		{
    
    
			is_getGsmData = 1; 
		}
		if(GSMA6_point>=GSMA6_USART_REC_LEN)
		{
    
    
			GSMA6_point=0;
		}
	}
}
void GSMA6_ClearDate(void)
{
    
    
	u8 k=0;
	for(k=0;k<GSMA6_USART_REC_LEN;k++)      //将缓存内容清零
	{
    
    
		GSMA6_RECEICV_BUFFER[k] = 0;
	}

	GSMA6_point=0;	
	is_getGsmData=0;
}

char GSMA6_Find(char *a)
{
    
     
	if(strstr(GSMA6_RECEICV_BUFFER,a)!=NULL) 
	{
    
    
		return 1;
	}	
	else
	{
    
    
		return 0;
	}	
}

/**********************************
发送命令
**********************************/
void GSMA6_Send_Command(char *s)
{
    
    
	GSMA6_ClearDate(); 
	while(*s != '\0')//检测字符串结束符
	{
    
    
		GSMA6_USART_SendData(*s++);//发送当前字符
	}
	GSMA6_UART_SendLR();
//	GSMA6_ClearDate();		 
}
void GSMA6_Send_Command_END(char *s)
{
    
    
	GSMA6_ClearDate(); 
	while(*s != '\0')//检测字符串结束符
	{
    
    
		GSMA6_USART_SendData(*s++);//发送当前字符
	}
}
char GSMA6_Send_AT_Command(char *b,char *a,char wait_time,u16 charerval_time)         
{
    
    
	char i;

	GSMA6_ClearDate(); // 清除缓存数据
	i = 0;
	while(i < wait_time)                    
	{
    
    
		GSMA6_Send_Command(b);
		Delay_ms(charerval_time);
		if(GSMA6_Find(a))            //查找需要应答的字符
		{
    
    
			return 1;
		}
		i++;
	}	
	return 0;
}
char GSMA6_Send_AT_Command_END(char *b,char *a,char wait_time,u16 charerval_time)         
{
    
    
	char i;

	GSMA6_ClearDate(); 
	i = 0;
	while(i < wait_time)                    
	{
    
    
		GSMA6_Send_Command_END(b);
		Delay_ms(charerval_time);
		if(GSMA6_Find(a))            //查找需要应答的字符
		{
    
    
			return 1;
		}
		i++;
	}	
	return 0;
}
/***************************************************************
查询状态。
****************************************************************/
char GSMA6_Check_Status(void)
{
    
    
	char ret;
	
	ret = GSMA6_Send_AT_Command((char *)"AT",(char *)"OK",3,1000);//测试通信是否成功
	if(ret == 0)
	{
    
    
		return COMMUNITE_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CPIN?",(char *)"READY",3,1000);//查询卡是否插上
	if(ret == 0)
	{
    
    
		return NO_SIM_CARD_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CREG?",(char *)"+CREG: 1,1",5,2000);//查询卡是否注册到网络
	if(ret == 0)
	{
    
    
		return SIM_CARD_NO_REG_ERROR;
	}
	ret = GSMA6_Send_AT_Command((char *)"AT+CMGD=1,4",(char *)"OK",3,3000);//删除所有短信   新增
	if(ret == 0)
	{
    
    
		return AT_DELET_SMS_ERROR;
	}
	return 1;
}

char GSMA6_Config_Format(void)
{
    
    
	char ret;
	
	//设置存储位置
	ret = GSMA6_Send_AT_Command((char *)"AT+CPMS=\"SM\",\"ME\",\"SM\"",(char *)"OK",3,1000);
	if(ret == 0)
	{
    
    
		return AT_CPMS_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CMGF=1",(char *)"OK",3,1000);//配置为TEXT模式
	if(ret == 0)
	{
    
    
		return AT_CMGF_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CSCS=\"GSM\"",(char *)"OK",3,1000);//设置字符格式
	if(ret == 0)
	{
    
    
		return AT_CSCS_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CNMI=2,1",(char *)"OK",3,1000);//设置收到短信提示
	if(ret == 0)
	{
    
    
		return AT_CNMI_ERROR;
	}
	return 1;
}
/***************************************************************
发送短信给对应手机号
****************************************************************/
char xdata AT_Cmd_GMGS[25];
char GSMA6_text_message(char *phoneNum,char *content)
{
    
    
	char ret;
	char end_char[2];  	//信息结束字符串
	end_char[0] = 0x1A;//结束字符
	end_char[1] = '\0';	

	memset(AT_Cmd_GMGS,'\0',25);			 //先清空,再 对AT_CMGR 赋值   
	strcpy((char *)AT_Cmd_GMGS,"AT+CMGS=\"");  // strcpy从目标地址0 开始拷贝
	strcat((char *)AT_Cmd_GMGS,(char *)phoneNum);	   //strcat从目标地址字符串后开始连接
	strcat((char *)AT_Cmd_GMGS,"\"\r");
	
	//设置存储位置
	ret = GSMA6_Config_Format();
	if(ret != 1)
	{
    
    
		return ret;
	}
	ret = GSMA6_Send_AT_Command(AT_Cmd_GMGS,(char *)">",3,1000);//输入收信人的电话号码	  set_phone_num
	if(ret == 0)
	{
    
    
    return AT_CMGS_ERROR;
	}	
	GSMA6_USART_SendStr(content); //此函数发送短信内容 不加回车换行
	ret = GSMA6_Send_AT_Command_END(end_char,(char *)"OK",1,4000);//发送结束符,等待返回ok,等待5S发一次,因为短信成功发送的状态时间比较长
	if(ret == 0)
	{
    
    
		return END_char_ERROR;
	}	
	return 1;
}
char xdata PhoneNumber[GSMA6_REC_PHONENUMLEN];
char xdata LCD_ShowMessage[17];
char GSMA6_ReadMessageTest(void)
{
    
    
	char *subString;
	char *subStringNext;
	char AT_CMGR[15];
	char AT_SMSNum[3];
	if(is_getGsmData)
	{
    
    
		Delay_ms(1000);
		is_getGsmData = 0;
		
		if(GSMA6_Find("+CMTI"))
		{
    
    											
			if((subString = strstr(GSMA6_RECEICV_BUFFER, "SM\",")) != NULL)
			{
    
    
				subString+=4;
				if ((subStringNext = strstr(subString, "\r")) != NULL)
				{
    
    
					memset(AT_SMSNum, 0, 3);
					memcpy(AT_SMSNum, subString, subStringNext - subString);
					
					memset(AT_CMGR,'\0',15);
					strcpy(AT_CMGR,"AT+CMGR=");
					strcat(AT_CMGR,AT_SMSNum);
					
					if(GSMA6_Send_AT_Command((char *)AT_CMGR,(char *)"OK",3,1000))
					{
    
    
						Delay_ms(100);
					
						if((subString = strstr(GSMA6_RECEICV_BUFFER, "+86")) != NULL)
						{
    
    
							subString+=3;
							if((subStringNext = strstr(subString, "\"")) != NULL)
							{
    
    
								memset(PhoneNumber, 0, GSMA6_REC_PHONENUMLEN);
								memcpy(PhoneNumber, subString, subStringNext - subString); //获取手机号
								memset(LCD_ShowMessage, 0, 17);
								sprintf(LCD_ShowMessage,"M:%s,%s ",AT_SMSNum,PhoneNumber);
								write_string(1,0,LCD_ShowMessage);
								subString = subStringNext+5;
								if((subStringNext = strstr(subString, "\n")) != NULL)// 短信前\r\n  短信后\r\n
								{
    
    
									subString = subStringNext+1;
									if((subStringNext = strstr(subString, "\r")) != NULL)
									{
    
    
										memset(LCD_ShowMessage, 0, 17);
										if(subStringNext - subString>16)
										{
    
    
											memcpy(LCD_ShowMessage, subString,16);
										}
										else{
    
    
											memcpy(LCD_ShowMessage, subString,subStringNext - subString);
										}									
//										sprintf(LCD_ShowMessage,"R:%s",LCD_ShowMessage);
										write_string(2,0,"                ");
										write_string(2,0,LCD_ShowMessage);
										GSMA6_text_message(PhoneNumber,LCD_ShowMessage);
									}									
								}								
							}
						}
						else if((subString = strstr(GSMA6_RECEICV_BUFFER, "READ")) != NULL)
						{
    
    
							subString+=7;
							if((subStringNext = strstr(subString, "\"")) != NULL)
							{
    
    
								memset(PhoneNumber, 0, GSMA6_REC_PHONENUMLEN);
								memcpy(PhoneNumber, subString, subStringNext - subString); //获取手机号
								memset(LCD_ShowMessage, 0, 17);
								sprintf(LCD_ShowMessage,"M:%s,%s ",AT_SMSNum,PhoneNumber);
								write_string(1,0,LCD_ShowMessage);
								subString = subStringNext+5;
								if((subStringNext = strstr(subString, "\n")) != NULL)// 短信前\r\n  短信后\r\n
								{
    
    
									subString = subStringNext+1;
									if((subStringNext = strstr(subString, "\r")) != NULL)
									{
    
    
										memset(LCD_ShowMessage, 0, 17);
										if(subStringNext - subString>16)
										{
    
    
											memcpy(LCD_ShowMessage, subString,16);
										}
										else{
    
    
											memcpy(LCD_ShowMessage, subString,subStringNext - subString);
										}									
//										sprintf(LCD_ShowMessage,"R:%s",LCD_ShowMessage);
										write_string(2,0,"                ");
										write_string(2,0,LCD_ShowMessage);
										GSMA6_text_message(PhoneNumber,LCD_ShowMessage);
									}									
								}								
							}
						}
						else{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_SMCHECKError;
						}
//						if(GSMA6_Find("check"))  //指令
//						{
    
    
//							GSMA6_ClearDate();
//							return TEXT_CMD_CHECK;
//						}
						
					}
					else
					{
    
    
						GSMA6_ClearDate();
						return TEXT_CMD_SMCHECKError;
					}
				}
			}
			GSMA6_ClearDate();
			return TEXT_CMD_READ_NOSM;
		}
		else  //必须要有
		{
    
    
			GSMA6_ClearDate();
		}
	}
	Delay_ms(100);
	return TEXT_CMD_READ_ERROR;
}
char GSMA6_Init(void)
{
    
    
	char ret = 0;
	
	GSMA6_ClearDate();
	
	ret = GSMA6_Check_Status();
	if(ret != 1)
	{
    
    
		return ret;
	}
	ret = GSMA6_Config_Format();
	if(ret != 1)
	{
    
    
		return ret;
	}
	GSMA6_ClearDate();
	
	return 1;
}



















猜你喜欢

转载自blog.csdn.net/qq_20467929/article/details/126107667