Sim900+单片机开发,实现打电话发短信

来源:互联网 发布:兄弟连php视频百度云 编辑:程序博客网 时间:2024/03/29 08:05

一、简介

       本模块是我们做的“基于物联网的老年人关怀系统”的子模块,实现的功能是:当检测到温度异常时,就向指定的监护人打电话或者发短信

二、所需设备

        Sim900开发板、sim卡、单片机(STC12C5A60S2)、4根杜邦线

三、工作原理

        单片机向Sim900发送AT命令,Sim900收到相应命令后执行相应的功能

四、开发前准备

       1, 1 张中国移动 SIM 卡(未停机,并开通 GPRS 功能(否则不能测试 GPRS 功能) )

       2, 1 个外部直流电源(保证能给 SIM900A 提供 2A 电流)

五、连线

       ATK-SIM900引脚定义:

      SIM900:发送————STXD;接收————SRXD

      串口助手或单片机:发送————RTXD,接收————RRXD

      STC12C5460S2引脚定义:

      串行口1: 发送————TxD/P3.1; 接收————RxD/P3.0

      串行口2: 发送————TxD2/P1.3;接收————RxD2/P1.2

      连接:

       ATK-SIM900上的STXD与SRXD分别与STC12C5460S2上TXD/P3.1和RXD/p3.0相连

       ATK-SIM900上的RRXD与RTXD分别与STC12C5460S2上的P1.3和P1.2相连

六、程序


/************************************************************

 // File Name: main.c

*************************************************************/
/*程序说明:
本程序可以根据发送的命令的不同实现不同功能,为了便于看效果,我实现了向特定号码打电话,当然你可以改成短信等
1.我们的程序全部都是通过单片机串口2与SIM900通讯,串口1用于获得SIM900返回的数据
2.在开发板上放入您的手机卡,接好天线,打开电源,接入耳机。
3.把程序编译后下载到单片机中,使用STC—ISP下载,具体请参照教程。
4.这里,我只是简简单单的实验了下打电话,并且是持续打,没有什么控制,你可以改一下程序,比如按键控制*/



#include "stc12c5a.h"
#include "systerm.h"
#include "gprs.h"
#include "timer.h"

void main()
{
Timer0Init();
Uart1Init(0,1,253);//初始化串口,设置波特率115200
Uart2Init(0,1,253);//初始化串口,设置波特率115200

        //启动Sim900要按下复位键大概3秒钟
GPRS_RST = 0;//Sim900 复位键拉低
DelaySec(3);//延时3秒
GPRS_RST = 1;//Sim900 复位键拉高
//Sim900启动完成
Uart2Sends("AT\r\n");
DelaySec(3);
Uart2Sends("AT\r\n");
DelaySec(3);
Uart2Sends("ATD10086;\r\n");
DelaySec(5000);
}





/************************************************************

 // File Name: gprs.c

************************************************************/



#include "gprs.h"
#include "systerm.h"
/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:char Uart2Init(char smod,char brtx12,unsigned char reload)
// 作用: 初始化用于连接gprs的串口2 ,串口2只能设置为独立波特率提供波特率
并打开串口2中断和全局中断
// 参数: smod s2smod位 0/1
brtx12 brtx12位  0/1
reload reload寄存器数值  0-255
// 返回: -1 s2smod位错误,没有写入0/1
-2 brtx12位错误,没有写入0/1
0
////////////////////////////////////////////////////////////////////////////////////////////////////*/
char Uart2Init(char s2smod,char brtx12,unsigned char reload)
{
S2CON = 0X50;//8位可变波特率,无奇偶位
BRT = reload;//设置独立波特率发生器波特率


if(s2smod == 1)
{
AUXR |= S2SMOD;   //S2SMOD = 1;//波特率倍速位
}
else if(s2smod == 0)
{
AUXR &= (~S2SMOD);   //S2SMOD = 0;//取消波特率倍速位
}
else
{
return -1;
}

if(brtx12 == 1)
{
AUXR |= BRTx12;//BRTx12 = 1;1T模式
}
else if(brtx12 == 0)
{
AUXR &= (~BRTx12);//BRTx12 = 0;12T模式
}
else
{
return -2;
}

AUXR |= BRTR;//开启波特率发生器
IE2 |= ES2;// ES2 = 1;   //允许串口2中断
EA = 1;   //开总中断
return 0;
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:void Uart2Send(char i)
// 作用: 用于gprs连接的串口1向gps发送1字节数据
// 参数: i 要发送的数据
// 返回: void
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart2Send(char i)
{
unsigned char temp = 0;

IE2 &= (~ES2);//关闭串口2中断//ES2 = 0;
S2CON &= (~S2TI);//S2TI = 0;
S2BUF = i;//装入数据
do
{
temp = S2CON;
temp = temp & 0x02;//temp = S2TI;
}while(temp == 0);//判断是否发送完毕


S2CON &= (~S2TI);//S2TI = 0;
IE2 |= ES2;//ES2 = 1;

}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:void Uart2Sends(char* data_at)
// 作用: 发送字符串到串口2 
// 参数: char* data_at 字符串头地址
// 返回:
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart2Sends(char* data_at)
{


unsigned char cnt=0;


IE2 &= (~ES2);//关闭串口2中断//ES2 = 0;
S2CON &= (~S2TI);//S2TI = 0;



while(*(data_at+cnt))//判断一串数据是否结束
{
S2BUF = *(data_at+cnt);//装入数据
while((S2CON & S2TI) == 0);
S2CON &= (~S2TI);//S2TI = 0;
cnt++;


}


S2CON &= (~S2TI);//S2TI = 0;
IE2 |= ES2;//ES2 = 1;
}




/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:char Uart1Init(char smod,char brtx12,unsigned char reload)
// 作用: 初始化用于连接gps的串口1 ,将串口1设置位独立波特率发生器提供波特率,
并打开串口1中断和全局中断
// 参数: smod smod位 0/1
brtx12 brtx12位  0/1
reload reload寄存器数值  0-255
// 返回: -1 smod位错误,没有写入0/1
-2 brtx12位错误,没有写入0/1
0
////////////////////////////////////////////////////////////////////////////////////////////////////*/
//串口设置位独立波特率提供波特率,和串口2使用同一个波特率,也可以使用定时器1来提供波特率
char Uart1Init(char smod,char brtx12,unsigned char reload)
{
SCON =  0X50;//8位可变波特率,无奇偶位(SM0=0,SM1=1),使能串口接收模块(REN=1)
BRT = reload;//设置独立波特率发生器波特率


if(smod == 1)
{
PCON |= SMOD;   //SMOD = 1;//波特率倍速位
}
else if(smod == 0)
{
PCON &= (~SMOD);   //SMOD = 0;//取消波特率倍速位
}
else
{
return -1;
}

if(brtx12 == 1)
{
AUXR |= BRTx12;//BRTx12 = 1;1T模式
}
else if(brtx12 == 0)
{
AUXR &= (~BRTx12);//BRTx12 = 0;12T模式
}
else
{
return -2;
}

  AUXR |= S1BRS;//串口1设置为使用独立波特率发生器
AUXR |= BRTR;//开启波特率发生器

ES = 1;   //开串口中断
EA = 1;   //开总中断
return 0;
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:void Uart1Send(char i)
// 作用: 用于gps连接的串口1向gps发送1字节数据
// 参数: i 要发送的数据
// 返回: void
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart1Send(char i)
{
ES = 0; //关串口中断
TI = 0; //清空发送完中断请求标志位
SBUF = i;  //将数据放入寄存器发送
while(TI == 0);//等待发送完毕,发送完毕 TI == 1
TI = 0; //清空发送完中断请求标志位
ES = 1; //开串口中断
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名:void Uart1Sends(char* at)
// 作用: 发送字符串到串口1
// 参数: char* at 字符串头地址
// 返回:
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart1Sends(char* at)
{
unsigned char cnt=0;


ES=0;//关串行口中断
while(*(at+cnt))//判断一串数据是否结束
{
SBUF=*(at+cnt);//发送数据
while(TI==0); //查询发送是否结束
TI=0; //清除发送一标志位
cnt++; //准备发送一个数据
}
ES=1;//开串行口中断
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名: void Uart1InterruptReceive(void) interrupt 4
// 作用: 接收gps模块传来的定位信号,并将GPRMC信息中的各种信息存入gprmc结构体内,详见gprmc结构体
// 参数: void
// 返回: void
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart1InterruptReceive(void) interrupt 4
{
char tmp = 0;
unsigned char i = 0;
if(RI)
{
ES=0;//关串行口中断
RI=0;//接收中断信号清零,表示将继续接收
while(RI!=0);
while(ES!=0);

tmp = SBUF;
ES=1;//开串行口中断
}
}


/*////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数名: void Uart2InterruptReceive(void)
// 作用:  串口2的中断函数,用于保存接收到的gprs传来的数据,
当 GprsFlagInfoAble=1,时说明当前保存到gprs_dat_recv[0]-gprs_dat_recv[GprsRecvCntAt]中存放的是一个完整的at回复指令,
必须马上读出出来,否则下一个数据到来后该指令将被取代。
GprsFlagInfoStart 在接收信息时该位置1,接收完一组完整at回复指令清0
// 参数:  void
// 返回:  void
////////////////////////////////////////////////////////////////////////////////////////////////////*/
void Uart2InterruptReceive(void) interrupt 8
{
unsigned char tmp = 0;
char i = 0;


IE2 &= (~ES2);//关闭串口2中断//ES2 = 0;
if(S2CON & S2RI)//if(S2RI == 1)
{


S2CON &= (~S2RI);//S2RI = 0;
tmp = S2BUF;
Uart1Send(tmp);
}
else
{
S2CON &= (~S2TI);//S2TI = 0;
}


IE2 |= ES2;//ES2 = 1;
}











/************************************************************

 // File Name: timer.c

************************************************************/



#include "timer.h" 
#include "stc12c5a.h"

volatile unsigned char data timer0_cnt = 0;
volatile int data sec_cnt = 0;

void Timer0Init(void)
{


TMOD=0x01;                     //设置定时器0为工作方式1
TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
TL0=(65536-45872)%256;


EA=1;                          //开总中断
ET0=1;                        //开定时器0中断
    TR0=1;                         //启动定时器0
}


void timer0() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;


timer0_cnt++;


if(timer0_cnt == 20)
{
timer0_cnt = 0;
sec_cnt++;
}

}


void DelaySec(unsigned char sec)
{
sec_cnt = 0;
while(sec_cnt < sec);
}

七、后记
       朋友,如果有任何问题,请留言,我定会及时回复!

               

0 0
原创粉丝点击