STC12C5a单片机控制SIM900收发短信,接听电话
时间:10-02
整理:3721RD
点击:
经过3天的熟悉,单片机STC12C5A60S2控制SIM900发短信,接收短信,接收电话,终于通了,其中需要修改的地方,希望大家指导一下,共同学习,共同进步~
//-------------------------------------------------------------------
#include "head.h"
//串口程序
void initUart(){ // 串口初始化
SCON=0x50; // 串口工作方式2
TMOD|=0x20; // 定时器工作方式2
TH1=0xfd; //定时器初值高位
//PCON=0x00; //
TR1=1; //
EA=1; //
//ES=1; //打开串口
}
//串口1发送字符串
void Uart1SendStr(uchar *buf)
{
while (*buf != '\0')
{
Uart1SendByte(*buf++);
}
delay_ms(50);// DelayTime(200);
}
//串口1发送单个字节
void Uart1SendByte(uchar dat)
{
ES=0;
SBUF=dat;
while(TI==0);
TI=0;
ES=1;
}
//串口2初始化
void Uart2Init()
{
S2CON=0x50; //8位数据,可变波特率
BRT=0xFd; //波特率为2400
//AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
AUXR |= 0x11; //启动独立波特率发生器
IE2=0x01; //串口2中断
EA=1; //CPU开中断
//串口2中断允许位
}
//串口2发送单个字节
void Uart2SendByte(uchar dat)
{
IE2=0; //?
S2BUF=dat;
while((S2CON&0x02)==0);
S2CON&=0xFD;
IE2=1;
}
void Uart2SendStr(uchar *buf)
{
while (*buf != '\0')
{
Uart2SendByte(*buf++);
}
delay_ms(50);//DelayTime(200); //我注释掉的
}
//--------------------------------------------------------------------
#include "head.h"
//gsm 发送短信
char xdata RsBuf[RsBuf_N]; //定义串口接收数据缓冲区
uchar xdata aimData[20]={0};
uchar RsPoint; //缓存数组大小变化值
extern int tempAim;
// 通讯中断接收程序 中断函数无返回值
void uart_rx2(void) interrupt 8 //放在这里 和放在main()里面是一样的
{
if((RsPoint<RsBuf_N)&&S2RI) //必须判断RI是否为1
//if(RI)
{
S2CON &= 0xfe ; //S2RI=0;
RsBuf[RsPoint++]=S2BUF;
//RsBuf[RsPoint]=0x00; //将下一个数据清零 ?
//SendASC(RsBuf[RsPoint-1]);
}
S2CON &= 0xfe ;
}
//清除缓冲区 clear_RsBuf
void clearRsBuf(void)
{ uchar j;
for(j=0;j<RsBuf_N;j++)
{
RsBuf[j]=0; //'0'
}
RsPoint=0; //使再次接收到的内容从0开始缓存
}
//握手函数,检测字符串是否是串口接收到的字符串的子字符串
uchar hand(uchar *ptr)
{
if(strstr(RsBuf,ptr)!=NULL)
return 1;
else
return 0;
}
//GSM初始化
uchar gsmInit(void) //AT测试
{
clearRsBuf();
Uart2SendStr("ATI\r\n");
delay1ms(1000);
Uart1SendStr(RsBuf);
//****************************等待应答"OK"
if(!hand("OK")){
clearRsBuf();
return 0;
}
clearRsBuf();
delay1ms(1000);
return 1;
}
//GSM的短信显示模式,短信提醒,是否读到手机卡
uchar gsmSetInit(){
clearRsBuf();
delay1ms(1000);
Uart2SendStr("AT+CPIN?\r\n");//查看是否读到手机卡
delay_ms(500);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGF=1\r\n"); //设置短消息模式 TEXT
delay_ms(500);//等待接受数据完成
Uart1SendStr(RsBuf);
clearRsBuf();
delay1ms(500);
Uart2SendStr("AT+CSCS="); //配置字符集
Uart2SendByte(0x22);
Uart2SendStr("GSM");
Uart2SendByte(0x22);
Uart2SendStr("\r\n");
delay_ms(500);//等待接受数据完成
Uart1SendStr(RsBuf);
clearRsBuf();
delay1ms(500);
Uart2SendStr("AT+CSCA=\"+8613010171500\"\r\n"); //设置中心号码,注意移动和联通中心号码不同
delay1ms(500);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
//设置有新短信时提醒其位置 AT+CNMI=2,1
Uart2SendStr("AT+CNMI=2,1\r\n");
delay1ms(500);
Uart1SendStr(RsBuf);
delay1ms(500);
clearRsBuf();
Uart2SendStr("AT+CMGD=1,4\r\n");
delay_ms(1000);
Uart1SendStr(RsBuf);
clearRsBuf();
return 1;
}
/***********************发送TEXT短信息********************************
*功 能: TEXT模式发送短信息
*形 参: char *dialnum 目的号码+8613333333333 char *text发送内容
*返 回 值: 1 发送成功 0 发送失败
*备 注:发送TEXT短信息之前应该先1,设置短消息模式 AT+CMGF=? (0)=PDU (1)=TEXT
2,设置短消息中心 AT+CSCA=“+8613800531500”回车
*****************************************************************/
void TransmitText(char *text) //发送号码 发送内容,字母或数字
{
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGS="); //信息发送指令 AT+CMGS=//
Uart2SendByte('"');
Uart2SendStr("157XXXXXXXXX"); //手机号码的引号丢了! 已经加上
Uart2SendByte('"'); //"AT+CMGS=\"15764222353\"\r\n"
Uart2SendStr("\r\n"); //发送回车指令//
delay_ms(500);
Uart2SendStr(text);
delay_ms(500);
Uart2SendByte(0x1a);
delay1ms(800);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGD=1,4\r\n");//删除所有短信内容
Uart1SendStr(RsBuf);
delay_ms(500);
}
//接收短信 ,并删除所接受的短信
uchar receive()
{ char *p; //指向接受到的短信内容开始位置
uchar i=0; //
if(hand("CMTI")){ //接收到短信的标志
clearRsBuf();
delay_ms(1000);
Uart2SendStr("AT+CMGR=1\r\n");
delay_ms(1000);
// Uart1SendStr(RsBuf);
clearRsBuf();
while(!hand("OK")){
clearRsBuf();
i++;
Uart2SendStr("AT+CMGR=1\r\n");
delay_ms(2000);
Uart1SendStr(RsBuf);
if(i>2){
break;
}
}
delay_ms(1000);
if(hand("ON")){
p=strstr(RsBuf,"ON");
sprintf(aimData,"%s",p);//将短信内容存储到aimData缓存数组中
Uart1SendStr("hello man\r\n");
Uart1SendStr(aimData);
Uart1SendStr("\r\n");
clearRsBuf();
// return 1;
}
else{
Uart1SendStr("nothing \r\n");
clearRsBuf();
//return 2;
}
Uart2SendStr("AT+CMGD=1,4\r\n");//删除所有短信
delay_ms(1000);
Uart1SendStr(RsBuf);
i=0;
while(!hand("OK")){
clearRsBuf();
i++;
Uart2SendStr("AT+CMGD=1,4\r\n");
delay_ms(1000);
Uart1SendStr(RsBuf);
if(i>2) {
break;
}
}
clearRsBuf();
return 1;
}
return 0;
}
//数据处理函数
void dataProce() //数据格式:ON*****,*星号为数据
{
int shi,ge,num;
uchar s[4]={0};
shi=(aimData[2]-48)*10;
ge=aimData[3]-48;
num =shi+ge; //用于调控温度
tempAim=num;
sprintf(s,"%2d",num);
Uart1SendStr("\r\n");
Uart1SendStr(s);
}
//--------------------------------------------------------------------------------------------------------------------------
#include "head.h"
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
//void DelayTime(uint n)
//{ uint x;
// while (n--)
// {
// x = 5000;
// while(x--);
// }
//}
void delay1ms(unsigned int t) //1ms延时
{
unsigned int i;
unsigned int j;
for(j=t;j>0;j--)
for(i=124 * 8;i>0;i--);
}
void delay_ms(unsigned int i) // -0.018084490741us
{
while(i--)
{
unsigned char a,b;
for(b=18;b>0;b--)
for(a=152;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
}
//-----------------------------------------------------------------------------------------------------
#include "head.h"
void main(){
initUart(); // 串口初始化
Uart2Init();
ES=1;
while(!gsmInit()); //AT测试
gsmSetInit();
while(1){
if(hand("RING")||hand("ring")){ //GSM部分
Uart1SendStr("ring\r\n");
clearRsBuf();
}
if(receive()){
dataProce();
delay_ms(1000);
TransmitText("text ok!");
}
}
}
Head.h 中把上面的函数声明都加进去就行了
函数都经过测设了,可以运行。
希望大家指导~~~~~
2015/3/22 zizhu1s
//-------------------------------------------------------------------
#include "head.h"
//串口程序
void initUart(){ // 串口初始化
SCON=0x50; // 串口工作方式2
TMOD|=0x20; // 定时器工作方式2
TH1=0xfd; //定时器初值高位
//PCON=0x00; //
TR1=1; //
EA=1; //
//ES=1; //打开串口
}
//串口1发送字符串
void Uart1SendStr(uchar *buf)
{
while (*buf != '\0')
{
Uart1SendByte(*buf++);
}
delay_ms(50);// DelayTime(200);
}
//串口1发送单个字节
void Uart1SendByte(uchar dat)
{
ES=0;
SBUF=dat;
while(TI==0);
TI=0;
ES=1;
}
//串口2初始化
void Uart2Init()
{
S2CON=0x50; //8位数据,可变波特率
BRT=0xFd; //波特率为2400
//AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
AUXR |= 0x11; //启动独立波特率发生器
IE2=0x01; //串口2中断
EA=1; //CPU开中断
//串口2中断允许位
}
//串口2发送单个字节
void Uart2SendByte(uchar dat)
{
IE2=0; //?
S2BUF=dat;
while((S2CON&0x02)==0);
S2CON&=0xFD;
IE2=1;
}
void Uart2SendStr(uchar *buf)
{
while (*buf != '\0')
{
Uart2SendByte(*buf++);
}
delay_ms(50);//DelayTime(200); //我注释掉的
}
//--------------------------------------------------------------------
#include "head.h"
//gsm 发送短信
char xdata RsBuf[RsBuf_N]; //定义串口接收数据缓冲区
uchar xdata aimData[20]={0};
uchar RsPoint; //缓存数组大小变化值
extern int tempAim;
// 通讯中断接收程序 中断函数无返回值
void uart_rx2(void) interrupt 8 //放在这里 和放在main()里面是一样的
{
if((RsPoint<RsBuf_N)&&S2RI) //必须判断RI是否为1
//if(RI)
{
S2CON &= 0xfe ; //S2RI=0;
RsBuf[RsPoint++]=S2BUF;
//RsBuf[RsPoint]=0x00; //将下一个数据清零 ?
//SendASC(RsBuf[RsPoint-1]);
}
S2CON &= 0xfe ;
}
//清除缓冲区 clear_RsBuf
void clearRsBuf(void)
{ uchar j;
for(j=0;j<RsBuf_N;j++)
{
RsBuf[j]=0; //'0'
}
RsPoint=0; //使再次接收到的内容从0开始缓存
}
//握手函数,检测字符串是否是串口接收到的字符串的子字符串
uchar hand(uchar *ptr)
{
if(strstr(RsBuf,ptr)!=NULL)
return 1;
else
return 0;
}
//GSM初始化
uchar gsmInit(void) //AT测试
{
clearRsBuf();
Uart2SendStr("ATI\r\n");
delay1ms(1000);
Uart1SendStr(RsBuf);
//****************************等待应答"OK"
if(!hand("OK")){
clearRsBuf();
return 0;
}
clearRsBuf();
delay1ms(1000);
return 1;
}
//GSM的短信显示模式,短信提醒,是否读到手机卡
uchar gsmSetInit(){
clearRsBuf();
delay1ms(1000);
Uart2SendStr("AT+CPIN?\r\n");//查看是否读到手机卡
delay_ms(500);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGF=1\r\n"); //设置短消息模式 TEXT
delay_ms(500);//等待接受数据完成
Uart1SendStr(RsBuf);
clearRsBuf();
delay1ms(500);
Uart2SendStr("AT+CSCS="); //配置字符集
Uart2SendByte(0x22);
Uart2SendStr("GSM");
Uart2SendByte(0x22);
Uart2SendStr("\r\n");
delay_ms(500);//等待接受数据完成
Uart1SendStr(RsBuf);
clearRsBuf();
delay1ms(500);
Uart2SendStr("AT+CSCA=\"+8613010171500\"\r\n"); //设置中心号码,注意移动和联通中心号码不同
delay1ms(500);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
//设置有新短信时提醒其位置 AT+CNMI=2,1
Uart2SendStr("AT+CNMI=2,1\r\n");
delay1ms(500);
Uart1SendStr(RsBuf);
delay1ms(500);
clearRsBuf();
Uart2SendStr("AT+CMGD=1,4\r\n");
delay_ms(1000);
Uart1SendStr(RsBuf);
clearRsBuf();
return 1;
}
/***********************发送TEXT短信息********************************
*功 能: TEXT模式发送短信息
*形 参: char *dialnum 目的号码+8613333333333 char *text发送内容
*返 回 值: 1 发送成功 0 发送失败
*备 注:发送TEXT短信息之前应该先1,设置短消息模式 AT+CMGF=? (0)=PDU (1)=TEXT
2,设置短消息中心 AT+CSCA=“+8613800531500”回车
*****************************************************************/
void TransmitText(char *text) //发送号码 发送内容,字母或数字
{
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGS="); //信息发送指令 AT+CMGS=//
Uart2SendByte('"');
Uart2SendStr("157XXXXXXXXX"); //手机号码的引号丢了! 已经加上
Uart2SendByte('"'); //"AT+CMGS=\"15764222353\"\r\n"
Uart2SendStr("\r\n"); //发送回车指令//
delay_ms(500);
Uart2SendStr(text);
delay_ms(500);
Uart2SendByte(0x1a);
delay1ms(800);
Uart1SendStr(RsBuf);
clearRsBuf();
delay_ms(500);
Uart2SendStr("AT+CMGD=1,4\r\n");//删除所有短信内容
Uart1SendStr(RsBuf);
delay_ms(500);
}
//接收短信 ,并删除所接受的短信
uchar receive()
{ char *p; //指向接受到的短信内容开始位置
uchar i=0; //
if(hand("CMTI")){ //接收到短信的标志
clearRsBuf();
delay_ms(1000);
Uart2SendStr("AT+CMGR=1\r\n");
delay_ms(1000);
// Uart1SendStr(RsBuf);
clearRsBuf();
while(!hand("OK")){
clearRsBuf();
i++;
Uart2SendStr("AT+CMGR=1\r\n");
delay_ms(2000);
Uart1SendStr(RsBuf);
if(i>2){
break;
}
}
delay_ms(1000);
if(hand("ON")){
p=strstr(RsBuf,"ON");
sprintf(aimData,"%s",p);//将短信内容存储到aimData缓存数组中
Uart1SendStr("hello man\r\n");
Uart1SendStr(aimData);
Uart1SendStr("\r\n");
clearRsBuf();
// return 1;
}
else{
Uart1SendStr("nothing \r\n");
clearRsBuf();
//return 2;
}
Uart2SendStr("AT+CMGD=1,4\r\n");//删除所有短信
delay_ms(1000);
Uart1SendStr(RsBuf);
i=0;
while(!hand("OK")){
clearRsBuf();
i++;
Uart2SendStr("AT+CMGD=1,4\r\n");
delay_ms(1000);
Uart1SendStr(RsBuf);
if(i>2) {
break;
}
}
clearRsBuf();
return 1;
}
return 0;
}
//数据处理函数
void dataProce() //数据格式:ON*****,*星号为数据
{
int shi,ge,num;
uchar s[4]={0};
shi=(aimData[2]-48)*10;
ge=aimData[3]-48;
num =shi+ge; //用于调控温度
tempAim=num;
sprintf(s,"%2d",num);
Uart1SendStr("\r\n");
Uart1SendStr(s);
}
//--------------------------------------------------------------------------------------------------------------------------
#include "head.h"
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
//void DelayTime(uint n)
//{ uint x;
// while (n--)
// {
// x = 5000;
// while(x--);
// }
//}
void delay1ms(unsigned int t) //1ms延时
{
unsigned int i;
unsigned int j;
for(j=t;j>0;j--)
for(i=124 * 8;i>0;i--);
}
void delay_ms(unsigned int i) // -0.018084490741us
{
while(i--)
{
unsigned char a,b;
for(b=18;b>0;b--)
for(a=152;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
}
//-----------------------------------------------------------------------------------------------------
#include "head.h"
void main(){
initUart(); // 串口初始化
Uart2Init();
ES=1;
while(!gsmInit()); //AT测试
gsmSetInit();
while(1){
if(hand("RING")||hand("ring")){ //GSM部分
Uart1SendStr("ring\r\n");
clearRsBuf();
}
if(receive()){
dataProce();
delay_ms(1000);
TransmitText("text ok!");
}
}
}
Head.h 中把上面的函数声明都加进去就行了
函数都经过测设了,可以运行。
希望大家指导~~~~~
2015/3/22 zizhu1s
高手啊
共同学习,嘿嘿,加油~
学习,学习,学习,学习
怎么写头文件?
大哥,有模块电路吗
谢谢分享学习一下
请问小编,可否实现下面功能: 向SIM900A卡拨打电话,然后GSM自动挂断,然后单片机控制一个超声波测距实现对水位的测量,然后单片机把这个测得的数据以短信的形式发给来电的好吗,我正在调这个程序,不太好写,特来请教,谢谢
不错!
学习下,谢 了!
看起来好牛,学习学习
