单片机控制GSM收发短信
2010.9.2
准备工作:1.单片机(AT89C52,lcd1602)
2.GSM模块(TC35)
3.sim卡
4.串口线,电源线(其中串口线需准备一根交叉串口线,即接口两端的收发线倒接)
GSM调试:
GSM采用AT指令进行控制。短信的发送是先将信息数据发送至短信中心,再由短信中心发送给目标对象。GSM调试是将GSM模块与PC机相连,测试GSM是否正常工作以及熟悉AT指令控制GSM收发短信的操作流程。
1. 连接
首先通过串口线(串口线为直连线还是交叉线查看GSM说明)将GSM与电脑连接,GSM模块默认的通信波特率为9600bps。打开串口调试工具,调整波特率与GSM对应,输入AT,若返回OK说明连接正常,若无返回值或者返回wrong说明连接不正确,或者GSM未准备好,可稍等片刻或者重启GSM,再次尝试。
2. 初始化
连接正常以后,可以对GSM进行收发短信的初始化。GSM成功接受初始化指令后都会返回OK。初始化的AT指令为:
AT\r //测试GSM是否正常连接
//重复发送直到返回OK
ATE0\r //关闭回显,便于后续操作
//返回OK表示设置成功
AT+CSCA=”+8613800250500”\r
//设置所在地短信中心的号码
//返回OK表示设置成功
AT+CNMI=2,1,0,0,1\r
//设置收信息模式为的收
//到的信息时向上位机发送
//收到信息指令同时信息存
//入sim卡,返回OK表示
//设置成功
AT+CMGF=1/r //设置发信息为txet格式
//返回OK表示设置成功
3. 发短息测试
在初始化完成以后就可以进行短信的收发了。发送短息的流程如下:
AT+CMGS=”+86138XXXXXXXX”\r
//设置收信方号码,设置成功
//返回”>”表示输入短信内容
XXXXX //输入信息内容,由于为txet //格式输入内容不为中文
Ctrl+z //发送命令,十六进制代码为//0x1a,返回OK表示发送成
//发送信息返回的OK延迟有
//2s左右,程序应给足够延迟
//以便正确判断是否接收成
//功
4. 收短信测试
GSM在收到短信以后会返回:“+CMTI: "SM",1”表示信息存储在sim卡1的位置。发送信息到GSM模块,收到信息后GSM会返回“+CMTI: "SM",X”此时只要读取sim卡中相应位置X中的信息即可。读取的信息内容如下:“+CMGR: "REC UNREAD","+8613508485560",,"01/07/16,15:37:28+32",once more”。信息构成为,未读标记,发送人号码,发送时间,发送内容。下面是具体的AT指令:
+CMTI: "SM",X //表示收到信息,
//信息内容存入
//sim卡中地址X
//储存元
AT+CMGR=X\r //读取X地址的单元
//的内容
+CMGR:"REC NREAD","+8613508485560",,"01/0
7/16,15:37:28+32",once more //读取sim信息
AT+CMGD=X\r //删除该信息
单片机程序的编写:
根据PC控制单片机的流程命令,设计单片机的程序。
1. 程序功能简介
首先进行各器件的初始化,LCD显示“connecting”,初始化成功以后显示欢迎界面“welcom to use!”
此时按下发信息键,将显示“write the phone number:”,从4*4矩阵键盘输入收件人号码,按确认键,此时显示“write the message:”,从矩阵键盘输入信息内容,再次按下确认件显示“sending”
表示信息正在发送,发送完毕显示“the message has been sended”,延迟5秒回到欢迎界面。
进入欢迎界面后,收到信息后,会显示“there is a newmessage”,按下读信息键,会读出信息内容,再次按下该键将删除该信息并返回欢迎界面。
2. 程序流程图
3. 程序的实现
#include
#include
sbit k1=P3^2;
sbit k2=P3^3;
sbit rs=P2^0;
sbit rw=P2^1;
sbit ep=P2^2;
unsigned int cou_lcd=0;
unsigned int cou_rec=0;
unsigned int cou_send=0;
unsigned int cou_temp=0;
unsigned char date_rec[30];
unsigned char num_send[40];
unsigned char code connect[]="connecting...";
unsigned char code sending[]="sending...";
unsigned char code sended[]="the message has been sended.";
unsigned char code welcom[]="welcom to use\!";
unsigned char code new_message[]="there is a new message...";
unsigned char code phone_number[]="write the phone number:";
unsigned char code message[]="write the message:";
unsigned char code wrong[]="wrong!";
unsigned char code num[]="0123456789abcdefghijklimnopqrstuvwxyz ";
unsigned char code GSM_AT[]="AT\r";
unsigned char code GSM_ATE[]="ATE0\r";
unsigned char code GSM_CSCA[]="AT+CSCA=\"+8613800250500\"\r";
unsigned char code GSM_CNMI[]="AT+CNMI=2,1,0,0,1\r";
unsigned char code GSM_CMGF[]="AT+CMGF=1\r";
unsigned char code GSM_CMGR[]="AT+CMGR=1\r";
unsigned char code GSM_CMGD[]="AT+CMGD=1\r";
unsigned char code GSM_CMGS1[]="AT+CMGS=\"+86";
unsigned char code GSM_CMGS2[]="\"\r";
unsigned char code GSM_START=0x1a;
void delay(unsigned int n)
{
unsigned int m;
while(n--)
{
for(m=0;m<115;m++);
}
}
/***************************************************************************************************
Lcd显示部分
***************************************************************************************************/
bit lcd_bz() //Test Busy:if lcd is busy,return 0,else return 1
{
bit result;
rs=0;
rw=1;
ep=1;
_nop_();_nop_();_nop_();
result=(bit)(P0&0x80);
_nop_();_nop_();_nop_();
ep=0;
_nop_();_nop_();_nop_();
return result;
}
void lcd_wcmd(unsigned char cmd) //write commands to Lcd
{
while(lcd_bz());
rs=0;
rw=0;
ep=0;
_nop_();_nop_();_nop_();
P0=cmd;
_nop_();_nop_();_nop_();
ep=1;
_nop_();_nop_();_nop_();
ep=0;
}
void lcd_wdat(unsigned char dat) //write date to Lcd for displaying
{
while(lcd_bz());
rs=1;
rw=0;
ep=0;
P0=dat;
delay(80);
_nop_();_nop_();_nop_();
ep=1;
_nop_();_nop_();_nop_();
ep=0;
}
void lcd_init() //Lcd initialization
{
lcd_wcmd(0x01);
delay(1);
lcd_wcmd(0x05);
delay(1);
lcd_wcmd(0x38);
delay(1);
lcd_wcmd(0x0f);
delay(1);
lcd_wcmd(0x06);
delay(1);
}
void lcd_display(unsigned char *temp,unsigned int n) //display date
{
unsigned int m=0;
while(n--)
{
if(m<=15)
{
lcd_wcmd(0x00+0x80+m);
}
if(m>=16&&m<=31)
{
lcd_wcmd(0x40+0x70+m);
}
if(m>=32&&m<=47)
{
lcd_wcmd(0x00+0x70+m);
}
if(m>=48&&m<=63)
{
lcd_wcmd(0x40+0x60+m);
}
if(m>=64)
{
lcd_wcmd(0x01);
m=0;
}
lcd_wdat(*temp);
temp++;
m++;
}
}
/***************************************************************************************************
串口部分***************************************************************************************************/
void uart_init() //Uart initialization
{
SCON=0x50;
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
ES=1;
TR1=1;
EA=1;
}
void receive_uart() interrupt 4 //receive date from uart
{
while(RI==1)
{
RI=0;
if(cou_rec==30)
cou_rec=0;
date_rec[cou_rec]=SBUF;
cou_rec++;
}
}
void send_uart(unsigned char temp) //send date from uart
{
SBUF=temp;
while(!TI);
TI=0;
}
bit check_ok()
{
bit k=0;
while(cou_rec--)
{
if(date_rec[cou_rec]=='K'&&date_rec[cou_rec-1]=='O')
{
k=1;
date_rec[cou_rec]=0;
date_rec[cou_rec-1]=0;
break;
}
}
if(!cou_rec)
{
k=0;
}
return k;
}
void send_gsm(unsigned char *temp,unsigned int m,unsigned int n,bit che)
{
unsigned int k;
unsigned char *p;
while(n--)
{
cou_rec=0;
k=m;
p=temp;
while(k--)
{
send_uart(*p);
p++;
}
delay(500);
if(che)
{
if(check_ok())
{
break;
}
}
if(!n&&che)
{
lcd_wcmd(0x01);
delay(10);
lcd_display(wrong,6);
while(1);
}
}
}
/***************************************************************************************************
GSM初始化
***************************************************************************************************/
void gsm_init()
{
send_gsm(GSM_AT,3,10,1);
send_gsm(GSM_ATE,5,10,1);
send_gsm(GSM_CSCA,25,10,1);
send_gsm(GSM_CNMI,18,10,1);
send_gsm(GSM_CMGF,10,10,1);
}
/***************************************************************************************************
读信息
***************************************************************************************************/
void read_message()
{
unsigned int n=0;
unsigned int temp;
send_gsm(GSM_CMGR,10,1,0);
delay(1000);
temp=cou_rec;
while(date_rec[temp-8]!=0x0a&&date_rec[temp-9]!=0x0d)
{
temp--;
n++;
}
n--;
lcd_wcmd(0x01);
lcd_display(&date_rec[cou_rec-8-n],n);
while(k1);
while(!k1)
{
delay(20);
while(!k1)
{
send_gsm(GSM_CMGD,10,10,1);
}
}
}
/***************************************************************************************************
键盘扫描
***************************************************************************************************/
unsigned char keyscan()
{
unsigned char cord_h,cord_l;
P1=0x0f;
cord_h=P1&0x0f;
if(cord_h!=0x0f)
{
delay(9);
if((P1&0x0f)!=0x0f)
{
cord_h=P1&0x0f;
P1=cord_h|0xf0;
cord_l=P1&0xf0;
return(cord_h+cord_l);
}
}
return(0xff);
}
void change(unsigned char m,unsigned char n)
{
if(cou_tempn)
{
cou_temp=m;
}
if(cou_lcd<=15)
{
lcd_wcmd(0x00+0x80+cou_lcd);
}
if(cou_lcd>=16&&cou_lcd<=31)
{
lcd_wcmd(0x40+0x70+cou_lcd);
}
if(cou_lcd>=32&&cou_lcd<=47)
{
lcd_wcmd(0x00+0x70+cou_lcd);
}
if(cou_lcd>=48&&cou_lcd<=63)
{
lcd_wcmd(0x40+0x60+cou_lcd);
}
if(cou_lcd>=64)
{
lcd_wcmd(0x01);
cou_lcd=0;
}
lcd_wdat(num[cou_temp]);
num_send[cou_send]=num[cou_temp];
cou_temp++;
}
void keyboard()
{
unsigned char key;
key=keyscan();
switch(key)
{
case 0x7e:
{
change(0,3);
break;
}
case 0x7d:
{
change(3,6);
break;
}
case 0x7b:
{
change(6,10);
break;
}
case 0x77:
{
change(10,12);
break;
}
case 0xbe:
{
change(12,14);
break;
}
case 0xbd:
{
change(14,16);
break;
}
case 0xbb:
{
change(16,18);
break;
}
case 0xb7:
{
change(18,20);
break;
}
case 0xde:
{
change(20,22);
break;
}
case 0xdd:
{
change(22,24);
break;
}
case 0xdb:
{
change(24,26);
break;
}
case 0xd7:
{
change(26,28);
break;
}
case 0xee:
{
change(28,30);
break;
}
case 0xed:
{
change(30,32);
break;
}
case 0xeb:
{
change(32,34);
break;
}
case 0xe7:
{
change(34,37);
break;
}
}
}
/***************************************************************************************************
发信息
***************************************************************************************************/
void send_message()
{
unsigned int temp;
bit flag=0;
lcd_wcmd(0x01);
lcd_display(phone_number,23);
while(k1);
while(1)
{
if(!flag)
{
lcd_wcmd(0x01);
flag=1;
}
keyboard();
if(!k1)
{
delay(20);
if(!k1)
{
cou_send++;
cou_lcd++;
while(!k1);
}
}
if(!k2)
{
delay(20);
if(!k2)
break;
}
}
temp=cou_send;
cou_lcd=0;
lcd_wcmd(0x01);
lcd_display(message,18);
while(k1);
while(1)
{
if(flag)
{
lcd_wcmd(0x01);
flag=0;
}
keyboard();
if(!k1)
{
delay(20);
if(!k1)
{
cou_send++;
cou_lcd++;
while(!k1);
}
}
if(!k2)
{
delay(20);
if(k2)
{
lcd_display(sending,10);
break;
}
}
}
send_gsm(GSM_CMGS1,12,1,0);
send_gsm(&num_send[1],temp-1,1,0);
send_gsm(GSM_CMGS2,2,1,0);
delay(500);
send_gsm(&num_send[temp+1],cou_send-temp-1,1,0);
send_gsm(&GSM_START,1,1,0);
lcd_display(sended,28);
delay(5000);
cou_lcd=0;
cou_rec=0;
cou_send=0;
cou_temp=0;
}
/***************************************************************************************************
main
***************************************************************************************************/
void main()
{
bit flag=0;
uart_init();
lcd_init();
lcd_display(connect,13);
gsm_init();
while(1)
{
if(!flag)
{
flag=1;
cou_rec=0;
lcd_wcmd(0x01);
lcd_display(welcom,14);
}
while(cou_rec)
{
flag=0;
cou_rec=0;
lcd_wcmd(0x01);
lcd_display(new_message,25);
while(k1);
while(!k1)
{
delay(20);
while(!k1)
{
read_message();
}
}
cou_rec=0;
}
while(!k1)
{
delay(20);
while(!k1)
{
flag=0;
send_message();
}
}
}
}
单片机控制GSM:
在完成了GSM测试,单片机程序的编写后,将单片机与GSM相连,上电即可完成单片机控制GSM收发短信。
_1345240660.vsd
开始
串口初始化
Lcd初始化
判断是否收到信息
判断是否
按下发信息键
GSM初始化
是
提示收到信息
输入收件人号码
输入信息内容
等待完成发送信息
信息发送完毕
否
是
显示信息内容
删除信息
否