前一篇文章《时钟及温度的显示》中所介绍的作品,是作为一个单片机新手在暑假学了一个月的单片机之后,做的第一个综合性作品,涵盖了二极管、蜂鸣器、数码管、液晶屏、按键、时钟芯片、温度传感器的控制操作。做完这个之后,也没碰过单片机了。在大三开始的时候,由于和同学参加了一个由有方公司提供GPRS芯片的比赛,便开始重拾单片机,完成了下面这个作品,还获奖了。
基于有方GPRS的智能电梯控制系统,名字感觉很高端,其实就是噱头。其功能描述如下(直接复制当初演示用的PPT):
构思背景
目前的很多企业都在很高的楼层办公,每天上下班高峰期,电梯门口总是会排上很长的队,为了让电梯用最快的速度将所有的员工送到指定楼层,需要给出一些改进;下班的时候,由于楼层很高,员工往往需要花费一些时间等待电梯到达自己的楼层,利用一些改进可以让员工掌握电梯状态,从而节省一些等电梯的时间。
功能特色
功能一:我们对电梯作出这样的改进:在上班高峰时段,电梯只能向上运行时开门搭载上朝楼上去的人员,即电梯只会响应朝上行的按键,在向下运行的过程中,不会响应任何按钮。在下班时间段,也可以做相应修改。从而节省大多数人的时间,将人快速送达指定地点。
功能二: 平时,由于工作人员多工作于很高的楼层,而此时的电梯可能处于一楼,所以可以先向控制中心发送一条短信来获取电梯的实际位置,如果电梯此时距离自己所在的楼层还有一段距离,就可以提前向控制中心发送一条请求短信,这时控制中心会向电梯应用端发送请求信号,命令电梯开往指定的楼层,从而减少等待的时间。
具体操作
只需要编辑短信XY#到指定的电话号码就可以远程控制电梯的运行。其中X代表发信人所在楼层,Y代表发信人将要到达的楼层。电梯也会对发信人的要求进行应答,告诉电梯当前的运行情况,好让发信人掌握好乘坐电梯的时间。
GPRS的使用
我们主要用到了有方GPRS模块的短信收发功能。主要用于在上下班高峰时帮助员工获得电梯状态信息、向电梯发送停靠指令。命令电梯开往指定的楼层,从而减少等待的时间。电梯应用端使用有方GPRSM660+模块来接收来自控制中心的信号并发送短信作为应答,从而实现用户与电梯的交互通信。
硬件电路图
作品展示
原文:http://blog.csdn.net/tengweitw/article/details/45896479
作者:nineheadedbird
软件实现
#include<REG52.h>
#include<STRING.h>
#define uint unsigned int
#define uchar unsigned char
#define FLOOR 10
int Con_Floor = 1;//当前的楼层号
int com_dat = 0 ;
int flag2 = 0 ;
int low = 1 ;
int high = 9 ;
int sign_flag = 0 ;
void delayms(uint xms); //延时函数(毫秒级)
uint test(uchar * floor); //测试在几楼
uint checkinfo();
uchar ReceiveData(uchar* ,uchar*);
void writefloor(int);
void writestate(int);
void up_down_logic(); //电梯的运行逻辑
void com_init(void); //串口初始化
void send_uart(uchar ch); //向串口发送单个字符
void send_AT_IPR(void); //设置模块的波特率为9600bps
void send_AT_CMGF(void); //设置发短信为文本模式
void send_AT_CSCS(void); //发送TE的字符集为GSM
void send_AT_CNMI(void); //设置短信的提示信息
void send_AT_CMGR(); //发送读取命令
void send_AT_CMGS(uchar *phone_num); //选择发送目的手机号
void send_text(uchar *text); //发送短信文本
void init_GPRS(void); //初始化GPRS模块
sbit dula=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P2^0;
sbit s2=P2^1;
sbit s3=P2^2;
sbit s4=P2^3;
sbit rd=P3^7;
sbit dscs=P1^4;
sbit dsas=P1^5;
sbit dsrw=P1^6;
sbit dsds=P1^7;
sbit dsirq=P3^3;
uchar count,s1num,flag,flag1;
uchar miao,shi,fen;
uchar code table[]=" 2012-10-15 MON";
uchar code table1[]=" 00:00:00";
uchar code floor[]="FLOOR: 1";
uchar code state[]="STATE: IDLE";
uchar code welcome[]="WELCOME TO USE!";
uchar code up[]="UP ";
uchar code down[]="DOWN";
uchar code idle[]="IDLE";
void write_date(uchar);
void write_ds(uchar,uchar);
uchar read_ds(uchar); //从ds187读取时间
void init();
void keyscan();
void write_sfm(uchar add,uchar date);
uchar code *AT_CMGF = "AT+CMGF=1"; //发送AT+CMGF=1,设置文本模式
uchar code *AT_CSCS = "AT+CSCS="; //选择TE的字符集(默认是GSM),M580返回数据时缓冲数组是OK
uchar code *AT_IPR = "AT+IPR=9600"; //设置波特率为9600bps
uchar code *AT_CNMI ="AT+CNMI=2,1,0,0,0" ; //设置收到新短信存于SIM卡中并发CMTI通知
uchar code *AT_CMGR="AT+CMGR="; //发送读取短信的命令
uchar code *AT_CMGS="AT+CMGS=";
uchar xdata buffer[100]={0}; //单片机用于接收短信的缓冲
uchar code tab[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//流水灯的状态
uchar code message0[] = "Sorry ,it is busy now ";
uchar code message1[] = "Sorry , we can only reach to ";//指明可以到达的终点
uchar code message2[] = "and now we are moving to ";//指明将要到达的楼层
uchar code message3[] = "Ok , we have accepted your request !";//接受请求后发送的消息
/**************************************************************\
*名称:test(char* )
*功能:判断电梯的此刻状态
\**************************************************************/
uint test(uchar * floor)
{
uint i;
for (i = 1 ; i < FLOOR ; i++)//从一楼开始判断
{
if(floor[i])
{
if(i < Con_Floor)
return 1;//表示电梯正在下降
else
return 0;//表示电梯正在上升
}
}
return 2;//表示此时电梯为空
}
/**************************************************************\
*名称:up_down_logic()
*功能:电梯的升降逻辑
\**************************************************************/
void up_down_logic()
{
uchar floor_data [FLOOR]={0};//判断执行方向
uchar buf[FLOOR]={0};
uchar tel[13] ;
uchar temp;
uint i=0;
uchar temp1 ;
while(1)
{
miao=read_ds(0); //没有响应时,时间可以正确的运行,但是一旦有请求,时间便会出现跳跃情况
fen=read_ds(2);
shi=read_ds(4);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
delayms(100);
while(checkinfo())
{
/* i = 0;
while(tel[i])
{
tel[i] = 0 ;
i++;
}*/
temp=ReceiveData(&temp1,tel);//temp 表示起点,temp1表示终点
EA=0;//关中断
//以下是将缓冲区清空
i=0;
while(buffer[i])
{
buffer[i]=0;
i++;
}
com_dat=0;
if (test(floor_data)==1&&temp-'0'>=1&&Con_Floor>=1)//在下降
{
if(temp -'0' < Con_Floor&&!floor_data[temp-'0'])//8点之前为上楼的高峰,所以下楼的请求(在7点半以前)不予响应,电梯直接到达一楼
{
if(temp1-'0' < temp - '0' && temp1 - '0' >= low&&(read_ds(4)>8))//希望到楼下去,即temp1 < temp的且此时电梯所能到的最低点比temp1还小
{
floor_data[temp-'0']=1;
buf[temp-'0'] = temp1-'0';
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (temp1 - '0' < temp - '0' && temp1 - '0' < low &&(read_ds(4)>8))//希望到楼下去,即temp1 < temp的且此时电梯所能到的最低点比temp1大
{
if (buf[low] < low)//如果在电梯所能到的最低点处就没有请求了或有向下的请求
{
floor_data[temp-'0']=1;
buf[temp-'0'] = temp1-'0';
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(low+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
}
else if(temp1 - '0' < temp - '0' && temp1 - '0' < low &&(read_ds(4)<8))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(low+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (temp1 - '0' > temp - '0'&& temp - '0' < low)//如果希望到楼上去,则仅当到最低点处没有请求或请求到达的地方小于temp后才可以
{
if ((buf[low] == 0||(buf[low] > temp - '0' && buf[low] < low))&&(read_ds(4)<5))//确保电梯到low层后无请求或有向下的但大于temp的请求
{
floor_data[temp - '0'] = 1 ;
buf[temp - '0'] = temp1 - '0' ;
high = temp1 - '0' ;//在电梯向上运行时所能到达的最高点
low = temp - '0' ;
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if(buf[low] > low &&(read_ds(4)<5))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(low+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if(buf[low] < temp - '0' &&(read_ds(4)<5))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(buf[low]+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else//不响应会执行下面的语句
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(buf[low]+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
}
}
}
else if (!test(floor_data)&&temp-'0'>=1&&Con_Floor>=1)//在上升
{
if(temp-'0' > Con_Floor&&!floor_data[temp-'0'])
{
if(temp1-'0' > temp - '0' && temp1 - '0' <= high &&(read_ds(4)<5))//请求者希望到楼上去,且此时电梯所能到达的最高点比请求temp1还大
{
floor_data[temp-'0']=1;
buf[temp-'0'] = temp1-'0';
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (temp1 - '0' > temp - '0' && temp1 - '0' > high &&(read_ds(4)<5))//请求者希望到楼上去,且此时请求的目的地已经超过了电梯所能到达的最高点
{
if (buf[high] > high || buf[high] == 0)//如果电梯到了最高点处还有向上的请求或者到了最高点处就没有请求了
{
floor_data[temp-'0']=1;
buf[temp-'0'] = temp1-'0';
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (buf[high] < high)
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(high+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
}
else if(temp1 - '0' > temp - '0' && temp1 - '0' > high &&(read_ds(4)>5))//不响应时执行
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(buf[low]+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (temp1 - '0' < temp - '0' && temp - '0' > high )//请求者希望到楼下去
{
if ((buf[high] == 0||(buf[high] < temp - '0'&&buf[high] > high))&&(read_ds(4)>8))//要确保电梯到达high层后没有请求或有向上的小于temp的请求
{
floor_data[temp - '0'] = 1 ;
buf[temp-'0'] = temp1 - '0';
low = temp1 - '0';
high = temp - '0';
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (buf[high] < high &&(read_ds(4)>8))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(high+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if (buf[high] > temp - '0'&&(read_ds(4)>8))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message1);
send_uart(buf[high]+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(low+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
}
}
}
else if (test(floor_data)==2&&temp-'0'!=Con_Floor&&temp-'0'>=1&&Con_Floor>=1)//电梯未被请求,则响应,但是请求的楼层数就是本层楼则不予响应
{
if (temp - '0' > temp1 - '0'&&(read_ds(4)>8))
{
low = temp1 - '0';
buf[temp - '0'] = temp1 - '0';
floor_data[temp-'0']=1;
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message3);
send_text(message2);
if(temp-'0'>Con_Floor)
send_uart(Con_Floor+1+'0');
else
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if(temp - '0' > temp1 - '0'&&(read_ds(4)<8))
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(low+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if(temp - '0' < temp1 - '0'&&(read_ds(4)<5))
{
high = temp1 - '0';
buf[temp - '0'] = temp1 - '0' ;
send_AT_CMGS(tel);//先发号码
floor_data[temp-'0']=1;
delayms(500);
send_text(message3);
send_text(message2);
if(temp-'0' > Con_Floor)
send_uart(Con_Floor+1+'0');
else
send_uart(Con_Floor-1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
else if(temp - '0' < temp1 - '0'&&(read_ds(4)>5))//不响应时执行
{
send_AT_CMGS(tel);//先发号码
delayms(500);
send_text(message0);
send_uart(buf[low]+'0');
delayms(10);
send_text(message2);
send_uart(Con_Floor+1+'0');
delayms(10);
send_uart(0x1a);
delayms(10);
}
}
}
if(test(floor_data)==1)//下降
{
writefloor(Con_Floor);
writestate(1);
delayms(3000);
Con_Floor--;
}
else if(!test(floor_data))//上升
{
writefloor(Con_Floor);
writestate(0);
delayms(3000);
Con_Floor++;
}
else if (test(floor_data) == 2)//处于空闲状态
{
writefloor(Con_Floor);
writestate(2);
high = 9;
low = 1 ;
}
if(floor_data[Con_Floor])//如果之前被请求过,则响应
{
P1=tab[Con_Floor];
delayms(3000);
if (buf[Con_Floor]!=0)
{
floor_data[buf[Con_Floor]] = 1 ;
buf[Con_Floor] = 0;
}
P1=0xff;
floor_data[Con_Floor] = 0 ;
}
EA = 1 ;//开中断
}
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
EA=1;
EX0=1;
IT0=1;
dula=0;
wela=0;
lcden=0;
write_ds(0x0B,0x26);
read_ds(0x0c);
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
//
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
//
miao=read_ds(0);
fen=read_ds(2);
shi=read_ds(4);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
delayms(5000);
write_com(0x80);
write_com(0x01);
//
for(num=0;num<15;num++)
{
write_date(welcome[num]);
delay(20);
}
delay(3000);
write_com(0x01);
write_com(0x80+0x10);
for(num=0;num<8;num++)
{
write_date(floor[num]);
delay(20);
}
write_com(0x80+0x50);
for(num=0;num<11;num++)
{
write_date(state[num]);
delay(20);
}
for(num=0;num<16;num++)
{
write_com(0x18);
delay(50);
}
}
void writefloor(int i)
{
write_com(0x80+0x17);
write_date(0x30+i);
}
void writestate(int flaggg)
{
uint i ;
write_com(0x80+0x57);
if(flaggg==1)
{
for(i=0;i<strlen(down);i++)
{
write_date(down[i]);
}
}
if(flaggg==2)
{
for(i=0;i<strlen(idle);i++)
{
write_date(idle[i]);
}
}
if(flaggg==0)
{
for(i=0;i<strlen(up);i++)
{
write_date(up[i]);
}
}
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(flag1==1)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
flag1=0;
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
flag1=0;
}
}
}
if(s4==0)
{
delay(5);
if(s4==0)
{
flag1=0;
miao=read_ds(0);
fen=read_ds(2);
shi=read_ds(4);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
}
}
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
flag=1;
flag1=0;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
flag=0;
write_ds(0,miao);
write_ds(2,fen);
write_ds(4,shi);
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(1);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(1);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void write_ds(uchar add,uchar date)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;
ds_date=P0;
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}
//
/**************************************************************\
* 名称: send_uart(unsigned char ch)
* 功能: 向串口发送一个字符
* 输入: 无
* 输出: 无
\**************************************************************/
void send_uart(uchar ch)
{
SBUF = ch;
while(0 == TI);//当TI为1时跳出死循环(表明数据已从串口发出),并进入中断处理程序,不过在中断处理程序中并不会对TI进行任何操作,转而执行下面的清0语句
TI = 0;
}/* end function send_uart */
/**************************************************************\
* 名称: send_AT_CMGS
* 功能: 发送AT+CMGS=***********,选择目的手机号
* 输入: 无
* 输出: 无
\**************************************************************/
void send_AT_CMGS(uchar *phone_num)
{
uint i ;
for(i = 0; i < strlen(AT_CMGS); i++)
{
send_uart(AT_CMGS[i]);
delayms(10);
}
delayms(10);
send_uart(0X22); //双引号
delayms(10);
for(i = 0; i < strlen(phone_num)-1; i++)
{
send_uart(phone_num[i]);
delayms(10);
}
delayms(10);
send_uart(0X22);
delayms(10);
send_uart('\r'); //发送回车符号
delayms(10);
send_uart('\n'); //发送换行符号
delayms(100);
}/* end function send_AT_CMGS */
/**************************************************************\
* 名称: send_text
* 功能: 发送短信内容
* 输入: 无
* 输出: 无
\**************************************************************/
void send_text(uchar *text)
{
uint i ;
for(i = 0; i < strlen(text); i++)
{
send_uart(text[i]);
delayms(10);
}
delayms(10);
}/* end function send_text */
/**************************************************************\
* 名称: send_AT_IPR
* 功能: 设置模块波特率为9600bps
* 输入: 无
* 输出: 无
***************************************************************/
void send_AT_IPR(void)//设置波特率9600
{
uint i;
for(i = 0; i < strlen(AT_IPR); i++)
{
send_uart(AT_IPR[i]);
delayms(10);
}
delayms(10);
send_uart('\r'); //发送回车符号
delayms(10);
send_uart('\n');
delayms(200);
}/* end function send_AT_IPR */
/*************************************************************\
*名称:send_AT_CNMI()
*功能:发送CNMI
\*************************************************************/
void send_AT_CNMI(void)//设置短信提示方式
{
uint i;
for (i = 0; i < strlen(AT_CNMI) ; i++)
{
send_uart(AT_CNMI[i]);
delayms(10);
}
delayms(10);
send_uart('\r');
delayms(10);
send_uart('\n');
delayms(200);
}
/*************************************************************\
*功能:发送读命令
\*************************************************************/
void send_AT_CMGR()
{
uint i;
for (i = 0 ; i < strlen(AT_CMGR) ; i++)
{
send_uart(AT_CMGR[i]);
delayms(10);
}
delayms(10);
}
/**************************************************************\
* 名称: send_AT_CMGF
* 功能: 短信AT指令,发送AT+CMGF=1,设置文本模式
* 输入: 无
* 输出: 无
***************************************************************/
void send_AT_CMGF(void)//设置短信的读模式
{
uint i ;
for(i = 0; i < strlen(AT_CMGF); i++)
{
send_uart(AT_CMGF[i]);
delayms(10);
}
delayms(10);
send_uart('\r'); //发送回车符号
delayms(10);
send_uart('\n');
delayms(200);
}/* end function send_AT_CMGF */
/**************************************************************\
* 名称: send_AT_CSCS
* 功能: 发送AT+CSCS="GSM",选择TE的字符集
* 输入: 无
* 输出: 无
\**************************************************************/
void send_AT_CSCS(void)//设置字符集为"GSM"
{
uint i ;
for(i = 0;i < strlen(AT_CSCS); i++)
{
send_uart(AT_CSCS[i]);
delayms(10);
}
delayms(10);
send_uart(0X22); //双引号
delayms(10);
send_uart('G');
delayms(10);
send_uart('S');
delayms(10);
send_uart('M');
delayms(10);
send_uart(0X22);
delayms(10);
send_uart('\r'); //发送回车符号
delayms(10);
send_uart('\n');
delayms(200);
}/* end function send_AT_CSCS */
/**************************************************************\
* 函数名及功能:delayms —— 延时函数(毫秒级),晶振频率为11.0592MHz
* 入口参数: 欲延时毫秒数,必须为正整数
* 出口参数: 无
* 备注: 此函数需要根据晶振频率修改j的初值
\**************************************************************/
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=113;j>0;j--);
}/* end function delayms */
/**************************************************************\
* 名称: com_int()
* 功能: 串口中断子函数
* 输入: 无
* 输出: 无
\**************************************************************/
void com_int(void) interrupt 4
{
EA=0; //关总中断
if(1 == RI) //当硬件接收到一个数据时,RI会置高位
{
buffer[com_dat] = SBUF; //存取串口接收的数据
RI = 0; //软件置RI为0
if(buffer[com_dat]=='#')
{
flag2 = 1; //接收短信内容结束
com_dat++;//#号不一定是最后一个字符!!!
}
else
{
com_dat++;
}
}
EA = 1; //开总中断
}/* end function com_int */
/**************************************************************\
* 名称: com_init()
* 功能: 串口初始化,晶振11.0592MHz,波特率9600bps
* 输入: 无
* 输出: 无
\**************************************************************/
void com_init(void)
{
TMOD=0X20;
TH1=253;
TL1=253;
TR1=1;
EA=1;
ES=1;
SM0=0;
SM1=1;
REN=1;
}
/************************************************************\
*名称:checkinfo()
*功能:检查是否有数据到达
\************************************************************/
uint checkinfo()
{
uint i=0;
if(buffer[0]!=0&&flag2==0)//短信到达的提示命令已经被单片机接收
{
while(buffer[i])
{
if(buffer[i]==',')
return 1 ;//有短信到达
i++;
}
}
return 0;//数据暂时不能接收
}
/************************************************************\
*名称:ReceiveData()
*功能:接收数据并返回
\************************************************************/
uchar ReceiveData(uchar *buf , uchar *buf2)
{
//这是为了发送接收数据的命令
uint i=0;
uint j ;
send_AT_CMGR();
delayms(10);
while(buffer[i] != ',')//检查时顺便将buffer[i]清0
{
buffer[i] = 0 ;
i++ ;
}
buffer[i] = 0 ;//将,清0
i++;
buffer[i++]=0;//将空格清0
while(buffer[i])
{
if(buffer[i]>='0'&&buffer[i]<='9')
{
send_uart(buffer[i]);
buffer[i]=0;//发完数据后将该位清0
delayms(10);
}
else
break;//数据接收完后跳出
i++;
}
delayms(10);
send_uart('\r');
delayms(10);
send_uart('\n');
delayms(100);
com_dat = 0 ;//为下次接收数据做准备
//这是为了检测需要的数据
delayms(3000);
i = 0 ;
j = 0 ;
while(1)
{
if(buffer[0]!=0&&flag2==1)
{
flag2=0;
while(buffer[i]!='#')
{
if (buffer[i] == '\"')
{
sign_flag++;
}
if (sign_flag == 3)
{
buf2[j++]=buffer[i+1];//接收电话号码
}
i++;
}
sign_flag = 0;
*buf = buffer[i-1];//目的地点
return buffer[i-2];//模拟的楼层数不超过10楼,所以可只返回一个字符,起点
}
}
}
/**************************************************************\
*名称:init_GPRS()
*功能:初始化GPRS模块
\**************************************************************/
void init_GPRS()
{
uint i = 0 ;
delayms(1000);
send_AT_IPR();//设置波特率
delayms(15000);
send_AT_CMGF();//设置短信格式
delayms(1000);
send_AT_CSCS();//设置字符集
delayms(1000);
send_AT_CNMI();//设置短信提示方式
delayms(3000);
while(buffer[i])//将初始化时接收到的数据清0
{
buffer[i] = 0 ;
i++ ;
}
com_dat = 0 ;//为下一次接收做准备
}
void main()
{
init();//初始化时钟芯片,液晶显示屏
//
delayms(20000);//避开开机时的无用数据
com_init();//串口初始化
delayms(1500);
init_GPRS();//给gprs设置必要的参数
while(1)
{
keyscan();//只是在时间不准确时会被按下,其它时间,不予理会
if(flag==0)//表示没有键盘按下
{
up_down_logic();
}
}
}
void exter() interrupt 0
{
uchar c;
flag1=1;
c=read_ds(0x0c);
}