调试时,通过串口助手向GSM模块发送相应的AT指令,就可以设置其工作模式。
比如“向指定的手机号码发送英文短信”。
PS:功能有很多,本贴以发送英文短信为例。
与单片机结合的基本原理就是:把AT指令以字符串形式写入程序,程序烧入单片机之后,调用串口中断进行通信。依次向GSM模块发送指令,GSM模块接收指令成功则返回“ok”,失败则返回“error”放在单片机的subf上,通过检测subf上是否有“ok”来判断GSM是否接收指令成功。每成功一次就发送下一条指令。以此实现设置GSM的工作模式。
代码如下:
/*头文件*/
#include <REG52.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
/*宏定义*/
#define Success 1U
#define Failure 0U
#define Uart1_Buf_Max 100 //串口数据缓存长度
/*定义一些变量*/
unsigned long Time_Cont = 0; //定时器计数器
char phoneNumber[] = "15605156539";//替换成需要被拨打电话的号码
char msg[] = "fire"; //短信内容
u8 point1;
u8 xdata Rec_Buf[Uart1_Buf_Max]; //串口数据缓存
u8 point1 = 0; //绶存指针
/*函数原型声明*/
void Uart_Init();
void SendData(unsigned char ch);
void SendString(char *s);
bit Hand(unsigned char *a);
void CLR_Buf(void);
void delay_ms(unsigned int n);
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry);
void errorLog();
void soft_reset(void);
void phone(char *number);
void sendMessage(char *number,char *msg);
/*************************************************************/
/*************************************************************/
/*********------------------子函数-------------------*********/
/*************************************************************/
/*************************************************************/
//MS延时函数(12M晶振下测试)
void delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
/****串口中断触发函数****/
void Uart_Init()
{
SCON = 0X50; //UART方式1;8位UART 0101 0000
REN = 1; //不允许串行口接收数据
PCON = 0x00; //SMOD=0;波特率9600不加倍
TMOD = 0x20; //T1计数器工作方式方式2自动重装,0010 0000用于产生波特率
TH1 = 0xFD; //装初值
TL1 = 0xFD;
TR1 = 1; //启动定时器1
EA = 1; //打开全局中断控制
ES = 1; //串行口中断
}
/*****串口中断服务函数******/
void RECEIVE_DATA(void) interrupt 4 using 1 //串口中断服务函数
{
ES = 0;
if (RI)
{
RI = 0; //接收完数据,RI由硬件置1,需要用软件使RI置0,等待下一次接收数据,所以清除RI位
Rec_Buf[point1] = SBUF; //出去接收到的数据
point1++; //在数组中依次存放数据
if(point1>=Uart1_Buf_Max) //接收的数据最大为100
{
point1 = 0;
}
}
ES = 1;
}
/*****单片机向GSM模块发送串口数据******/
void SendData(unsigned char ch)
{
SBUF = ch; //写数据到UART数据寄存器,SBUF把信息传递出去,完成后TI由硬件置1
while(TI == 0); //等待发送数据完成
TI = 0; //清除发送完成标志位
}
/*****发送字符串******/
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
}
}
/*****串口命令识别函数******/
bit Hand(unsigned char *a) // 串口命令识别函数
{
if(strstr(Rec_Buf,a)!=NULL)//strstr判断字符串a是否为字符串Rec_Buf的字串,如果是,则返回1
return 1;
else
return 0;
}
//制造重启命令
void soft_reset(void)
{
((void (code *) (void)) 0x0000) ();
}
void errorLog()
{
while (1)
{
if (sendCommand("AT\r\n", "OK\r\n", 100, 10) == Success)
{
soft_reset();
}
delay_ms(200);
}
}
/*****串口缓存清理******/
void CLR_Buf(void) // 串口缓存清理
{
memset(Rec_Buf, 0, Uart1_Buf_Max); //清空 100个字节大小的Rec_Buf全部置0 ,清空SBUF出去接收到的数据
point1 = 0;
}
/*****函数名:sendCommand*******/
/*****函数功能:*******/
/************/
unsigned int sendCommand(char *Command, char *Response, unsigned long Timeout, unsigned char Retry)
{
unsigned char n;
CLR_Buf();//串口缓存清理
for (n = 0; n < Retry; n++)
{
SendString(Command); //发送GPRS指令
Time_Cont = 0;
while (Time_Cont < Timeout)
{
delay_ms(100);
Time_Cont += 100;
if (strstr(Rec_Buf, Response) != NULL)
{
CLR_Buf();
return Success;
}
}
Time_Cont = 0;
}
CLR_Buf();
return Failure;
}
/******--------------------------******/
/***发送号码及短信内容,并判断是否成功**/
/******--------------------------******/
void sendMessage(char *number,char *msg)
{
xdata char send_buf[20] = {0};//开辟1个20字节的空间
memset(send_buf, 0, 20); //清空 把send_buf初始化为20字节大小的内容全部是0的数组
strcpy(send_buf, "AT+CMGS=\"");
/*发送号码并判断是否发送成功*/
strcat(send_buf, number);//连接字符串
strcat(send_buf, "\"\r\n");
if (sendCommand(send_buf, ">", 3000, 10) == Success);//判断手机号码是否发送成功
else errorLog();
/*发送短信内容并判断是否发送成功*/
if (sendCommand(msg, msg, 3000, 10) == Success);
else errorLog();
memset(send_buf, 0, 40); //清空
send_buf[0] = 0x1a;
send_buf[1] = '\0';
if (sendCommand(send_buf, "OK\r\n", 10000, 5) == Success);
else errorLog();
}
/*************************************************************/
/*************************************************************/
/*********------------------主函数-------------------*********/
/*************************************************************/
/*************************************************************/
void main()
{
Uart_Init();//调用串口中断函数
/*******-----状态检测及设置-----********/
if (sendCommand("AT\r\n", "OK\r\n", 3000, 10) == Success);
else errorLog();
delay_ms(100);
if (sendCommand("AT+CSQ\r\n", "OK\r\n", 3000, 10) == Success);//信号质量
else errorLog();
delay_ms(100);
if (sendCommand("AT+CPIN?\r\n", "READY", 3000, 10) == Success);//SIM卡状态
else errorLog();
delay_ms(100);
if (sendCommand("AT+COPS?\r\n", "OK\r\n", 3000, 10) == Success);//运营商
else errorLog();
delay_ms(100);
if (sendCommand("AT+CREG?\r\n", ",1", 3000, 10) == Success); //本地SIM卡
else if(sendCommand("AT+CREG?\r\n", ",5", 3000, 10) == Success );//漫游SIM卡
else errorLog();
delay_ms(100);
if (sendCommand("AT+CMGF=1\r\n", "OK\r\n", 1000, 10) == Success);//短消息为文本模式
else errorLog();
delay_ms(10);
if (sendCommand("AT+CSMP=17,167,0,8\r\n", "OK\r\n", 3000, 10) == Success);
else errorLog();
delay_ms(10);
if (sendCommand("AT+CSCS=\"GSM\"\r\n", "OK\r\n", 1000, 10) == Success);
else errorLog();
delay_ms(10);
sendMessage(phoneNumber,msg); //发送短信
while(1)
{
}
}
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|
|