調試時,通過串口助手向GSM模塊發(fā)送相應的AT指令,就可以設置其工作模式。
比如“向指定的手機號碼發(fā)送英文短信”。
PS:功能有很多,本貼以發(fā)送英文短信為例。
與單片機結合的基本原理就是:把AT指令以字符串形式寫入程序,程序燒入單片機之后,調用串口中斷進行通信。依次向GSM模塊發(fā)送指令,GSM模塊接收指令成功則返回“ok”,失敗則返回“error”放在單片機的subf上,通過檢測subf上是否有“ok”來判斷GSM是否接收指令成功。每成功一次就發(fā)送下一條指令。以此實現(xiàn)設置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 //串口數(shù)據緩存長度
/*定義一些變量*/
unsigned long Time_Cont = 0; //定時器計數(shù)器
char phoneNumber[] = "15605156539";//替換成需要被撥打電話的號碼
char msg[] = "fire"; //短信內容
u8 point1;
u8 xdata Rec_Buf[Uart1_Buf_Max]; //串口數(shù)據緩存
u8 point1 = 0; //綬存指針
/*函數(shù)原型聲明*/
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);
/*************************************************************/
/*************************************************************/
/*********------------------子函數(shù)-------------------*********/
/*************************************************************/
/*************************************************************/
//MS延時函數(shù)(12M晶振下測試)
void delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
/****串口中斷觸發(fā)函數(shù)****/
void Uart_Init()
{
SCON = 0X50; //UART方式1;8位UART 0101 0000
REN = 1; //不允許串行口接收數(shù)據
PCON = 0x00; //SMOD=0;波特率9600不加倍
TMOD = 0x20; //T1計數(shù)器工作方式方式2自動重裝,0010 0000用于產生波特率
TH1 = 0xFD; //裝初值
TL1 = 0xFD;
TR1 = 1; //啟動定時器1
EA = 1; //打開全局中斷控制
ES = 1; //串行口中斷
}
/*****串口中斷服務函數(shù)******/
void RECEIVE_DATA(void) interrupt 4 using 1 //串口中斷服務函數(shù)
{
ES = 0;
if (RI)
{
RI = 0; //接收完數(shù)據,RI由硬件置1,需要用軟件使RI置0,等待下一次接收數(shù)據,所以清除RI位
Rec_Buf[point1] = SBUF; //出去接收到的數(shù)據
point1++; //在數(shù)組中依次存放數(shù)據
if(point1>=Uart1_Buf_Max) //接收的數(shù)據最大為100
{
point1 = 0;
}
}
ES = 1;
}
/*****單片機向GSM模塊發(fā)送串口數(shù)據******/
void SendData(unsigned char ch)
{
SBUF = ch; //寫數(shù)據到UART數(shù)據寄存器,SBUF把信息傳遞出去,完成后TI由硬件置1
while(TI == 0); //等待發(fā)送數(shù)據完成
TI = 0; //清除發(fā)送完成標志位
}
/*****發(fā)送字符串******/
void SendString(char *s)
{
while (*s) //檢測字符串結束標志
{
SendData(*s++); //發(fā)送當前字符
}
}
/*****串口命令識別函數(shù)******/
bit Hand(unsigned char *a) // 串口命令識別函數(shù)
{
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個字節(jié)大小的Rec_Buf全部置0 ,清空SBUF出去接收到的數(shù)據
point1 = 0;
}
/*****函數(shù)名:sendCommand*******/
/*****函數(shù)功能:*******/
/************/
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); //發(fā)送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;
}
/******--------------------------******/
/***發(fā)送號碼及短信內容,并判斷是否成功**/
/******--------------------------******/
void sendMessage(char *number,char *msg)
{
xdata char send_buf[20] = {0};//開辟1個20字節(jié)的空間
memset(send_buf, 0, 20); //清空 把send_buf初始化為20字節(jié)大小的內容全部是0的數(shù)組
strcpy(send_buf, "AT+CMGS=\"");
/*發(fā)送號碼并判斷是否發(fā)送成功*/
strcat(send_buf, number);//連接字符串
strcat(send_buf, "\"\r\n");
if (sendCommand(send_buf, ">", 3000, 10) == Success);//判斷手機號碼是否發(fā)送成功
else errorLog();
/*發(fā)送短信內容并判斷是否發(fā)送成功*/
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();
}
/*************************************************************/
/*************************************************************/
/*********------------------主函數(shù)-------------------*********/
/*************************************************************/
/*************************************************************/
void main()
{
Uart_Init();//調用串口中斷函數(shù)
/*******-----狀態(tài)檢測及設置-----********/
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卡狀態(tài)
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); //發(fā)送短信
while(1)
{
}
}
代碼下載:
自己寫的GSM.zip
(40.84 KB, 下載次數(shù): 68)
2021-5-14 23:15 上傳
點擊文件名下載附件
51單片機實現(xiàn)GSM發(fā)送短信的程序 下載積分: 黑幣 -5
|