#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define RxIn 90 //定义接收的数组长度为90
uchar code AT[]="AT"; //握手信号
uchar code ATE[]="ATE"; //关回显
uchar code AT_CNMI[]="AT+CNMI=2,1";//设置这组参数来了新信息直接显示到串口,不作存储
uchar code AT_CSCA[]="AT+CSCA=+8613010166500";//移动手机设置为"AT+CSCA=+8613800532500";设置短信服务中心号码,需要根据所在地区不同进行相应修改
uchar code AT_CMGF[]="AT+CMGF=1";//设置短信的格式为text格式
uchar code AT_CMGR[]="AT+CMGR=";//读取短信指令
uchar code AT_CMGS[]="AT+CMGS=";//发送短信指令
uchar code AT_CMGD[]="AT+CMGD=";//删除短信指令
uchar code successful[]="control successful!";//发送操作成功信息到目标号码
uchar code unsuccessful[]="control unsuccessful!"; //发送操作失败信息到目标号码
uchar AT_delete[12];
uchar AT_Read[12]; //用来存储发送读取短信指令
uchar AT_SendNumber[25]; //用来存储发送短信号码指令
uchar numberbuf[3]; //用来保存短信条数
uchar idata SystemBuf[RxIn]; //储存出口接收数据
uchar CommandBuf[6]; //用来储存指令
uchar idata state[9]; //用来存储IO口状态
uchar idata state1[9]; //用来存储IO口状态
uchar Rx=0;
uchar P2_state; // 用于记录P2口状态
bit check=0; //查询标志位
bit receiveready=0; //接收短信标志位
bit sendready=0; //发送短信准备标志位
bit send=0; //发送短信标志位
bit flag=0; //指令标志位
sbit start=P3^7;//启动GSM的启动线连IGT
sbit relay1=P2^4;//继电器1
sbit relay2=P2^5;//继电器2
sbit led1=P2^6; //指示灯1
sbit led2=P2^7; //指示灯2
void Delay_ms(uint i);
void Start_GSM(void);
void UART_init (void);
void sendchar(uchar ch);
void sendstring(uchar *p);
void GSM_INIT(void);
void receive_ready(void);
void message_read(void);
void read_message(void);
void sendmessage(void);
/*函数void Delay_ms(uint i);实现功能:进行毫秒延时*/
void Delay_ms(uint xms) //延时程序,xms是形式参数
{
uint i, j;
for(i=xms;i>0;i--) // i=xms,即延时xms, xms由实际参数传入一个值
for(j=115;j>0;j--); //此处分号不可少
}
/*函数void Start_GSM(void);实现功能:对TC35进行启动,开启TC35
功能详述:单片机上的start管脚是跟TC35的IGT管脚相连;需要启动TC35,必须在 15脚(/IGT)加时长至少为100ms的低电平信号,
且该信号下降沿时间小于1ms。启动后,15 脚的信号应保持高电平.
*/
void Start_GSM(void)
{
start=0;
Delay_ms(1000);
start=1;
Delay_ms(1000);
}
/*函数void UART_init;实现功能:对串口进行初始化*/
void UART_init (void)
{
TMOD=0x20; //选择定时器1
PCON=0x00; ///波特率不加倍
SCON=0x50; //串行工作方式1允许串行接收
TH1=0xFD; //实验板上晶振位11.0592MHZ,选择波特率为9600
TL1=0xFD; //在相应计数器上赋值
EA=1; //总中断开启
ES=1; //串行中断开启
TR1=1; //开启定时器1
}
/*函数void sendchar(uchar ch);实现功能:发送一字节数据*/
void sendchar(uchar ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}
/*函数void sendstring(uchar *p);实现功能:通过串口发送字符*/
void sendstring(uchar *p)
{
while(*p)
{
sendchar(*p);
p++;
}
sendchar(0x0D); //回车换行的ASCII码
sendchar(0x0A);
}
/*函数void receive(void) interrupt 4 using 1;实现功能:通过串口接收数据*/
void receive(void) interrupt 4 using 1
{
if(RI)
{
if(Rx<RxIn)
{
SystemBuf[Rx]=SBUF;
Rx++;
}
RI=0;
}
}
/*函数void GSM_INIT(void);实现功能:初始化TC35模块*/
void GSM_INIT(void)
{
LOOP:
Delay_ms(1000);
sendstring(AT); //发送握手信号
Delay_ms(1000);
sendstring(ATE); //发送关回显信号
Delay_ms(1000);
sendstring(AT_CNMI);//设置收到短消息提示
Delay_ms(1000);
sendstring(AT_CSCA);//设置短信中心号码
Delay_ms(1000);
for(Rx=0;Rx<RxIn;Rx++)
{
SystemBuf[Rx]=0x00;
}
Rx=0;
sendstring(AT_CMGF);//设置接收文本格式
Delay_ms(1000);
if((SystemBuf[2]=='O')&&(SystemBuf[3]=='K')) //判断是否模块初始化成功,成功的话模块会回复"OK"给单片机
{ //如果单片机没有收到OK,就继续发送初始化指令/
for(Rx=0;Rx<RxIn;Rx++)
{
SystemBuf[Rx]=0x00;
}
Rx=0;
}
else
{
for(Rx=0;Rx<RxIn;Rx++)
{
SystemBuf[Rx]=0x00;
}
Rx=0;
goto LOOP;
}
}
/*函数void receive_ready(void);实现功能:接收短信准备*/
void receive_ready(void)
{
uchar i;
if((SystemBuf[5]==0x54)&&SystemBuf[6]==0x49) //0x54表示T,0x49表示I,如果有新短信来,模块会通过串口向单片机发送字符串,
{ // 此函数的功能是判断是否有新短信来,如果来的话就置位准备接受位标志为1
receiveready=1; //如果不是新短信的指令,就舍弃,并将接收数组清零/
}
else
{
for(i=0;i<Rx;i++)
{
SystemBuf[i]=0x00;
}
Rx=0;
}
}
/*函数 void message_read(void);实现功能:判断短信,准备是否回复短信给目标号码*/
void message_read(void)
{
if((sendready==1)&&(SystemBuf[5]==0x47)&&(SystemBuf[6]==0x52))//0x47表示G,0x52表示R
send=1;
}
/*函数 void read_message(void);实现功能:发送读取短信指令*/
void read_message(void)
{
uchar i;
Delay_ms(1000);
for(i=0;i<3;i++)
{
numberbuf[i]=SystemBuf[14+i];//号码的起始位在第14位,先取3位,numberbuf[i]用来保存短信条数
}
for(i=0;i<8;i++)
{
AT_Read[i]=AT_CMGR[i];//读取第X条短消息
}
for(i=8;i<11;i++)
{
AT_Read[i]=numberbuf[i-8]; //将读取的短信送AT_Read
}
for(Rx=0;Rx<RxIn;Rx++)
{
SystemBuf[Rx]=0x00;
}
Rx=0;
sendstring(AT_Read); //发送AT+CMGR=?,?代表短信储存所在位置
}
/*
信息的格式:
+CMTI: "SM",3
+CMGR: "REC UNREAD","+8615853209853",,"10/04/24,14:53:49+32"
onall
OK
短信的内容是onall
这里面的每一个字符都包含在内的,包括逗号空格,还有回车
*/
/*函数 void readcommend(void);实现功能:读取短信内容,判断相应指令是否正确*/
void readcommend(void)
{
uchar i;
for(i=0;i<5;i++) //将短信内容中的指令部分截取出来放到
{ //CommandBuf数组中
CommandBuf[i]=SystemBuf[64+i];//短息的内容从64位开始截取
}
if((CommandBuf[0]=='o')&&(CommandBuf[1]=='p')&&(CommandBuf[2]=='e')&&(CommandBuf[3]=='n')) //判断指令是否为开继电器指令
{
switch(CommandBuf[4])
{
case 0x31: relay1=0;led1=0; //第4位为数字1的ASCII码时,继电器 1开启
break;
case 0x32: relay2=0;led2=0; //第4位为数字2的ASCII码时,继电器 2开启
break;
case 0x41: relay1=0;led1=0;relay2=0;led2=0; //大写字母"A"的ASCII码
break;
case 0x3f: //"?"的ASCII码,代表查询
P2_state=P2;
check=1; //置位查询标志位
break;
default:flag=1; //其他指令定义为错误操作
break; //置位错误操作位为1
}
}
else
{
if((CommandBuf[0]=='c')&&(CommandBuf[1]=='l')&&(CommandBuf[2]=='o')&&(CommandBuf[3]=='s')) //判断指令是否为关闭电器指令
{
switch(CommandBuf[4])
{
case 0x31: relay1=1;led1=1; //第4位为数字1的ASCII码时,关闭继电器1
break;
case 0x32: relay2=1;led2=1; //第4位为数字2的ASCII码时,关闭继电器2
break;
case 0x41:relay1=1;led1=1;relay2=1;led2=1; //大写字母"A"的ASCII码
break;
default:flag=1; //其他指令定义为错误操作
break; //置位错误操作位为1
}
}
else {flag=1;} //如果发送的指令既不是open也不是shut就定义为错误操作
}
}
/*函数 void readstate;实现功能:将P2口的状态转化为数组*/
void readstate(void)
{
uint bitcnt,i,j;
for(bitcnt=0,i=0;bitcnt<8,i<8;bitcnt++,i++)
{
if((P2_state<<bitcnt)&0x80){state1[i]=0x31;}
else state1[i]=0x30;
}
for(j=7,i=0;j>=0,i<8;j--,i++)
{
state[j]=state1[i];
}
}
/*函数 void delete_message;实现功能:删除读短信指令*/
void delete_message(void)
{
uchar i;
Delay_ms(1000);
Delay_ms(1000);
Delay_ms(5000);
for(i=0;i