本文通过串口通信,使用STC15系列单片机实现发短信打电话功能。

一. 注意事项

1. 首先要确定手机卡已经注册到网络,具备打电话发短信功能

2. 正确的硬件连接:

P3.0-----STXD或者5VT

P3.1-----SRXD或者5VR

GND---GND(保证模块和单片机都接地)

3. 确认单片机上的晶振,根据晶振修改自己的程序。

4.推荐先将单片机与电脑相连,确定单片机发送的数据是正确的。如果发送的是乱码,请检查晶振与单片机的串口波特率。之前本人就是因为波特率不同步导致无法发送。

二. 代码实现

首先进行初始化,注意串口中断的中断号为4。


void Inti() //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xDC; //设定定时初值
TH1 = 0xDC; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
void interrupt_() interrupt 4
{ uchar temp;
temp=SBUF;
rec_data[rec_num++]=temp;
if(rec_num>=50)
rec_num=0;
else
;
RI=0;//接收中断信号清零,表示将继续接收 }

然后建立发送数组,返回数组的函数。

//串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
str++;
}
}
void Uart1BYTE(uchar temp)
{
SBUF=temp;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0; }
uchar hand(uchar *ptr)//GSM模块返回数据数组
{
if(strstr(rec_data,ptr)!=NULL)
return 1;
else
return 0;
}

也要记得清除返回数组的数据。防止造成干扰。

void clear_rec_data()
{
uchar i;
for(i=0;i<strlen(rec_data);i++)
{
rec_data[i]='0';
}
rec_num=0;
}
//延时函数1s钟
void DelaySec(int sec)
{
unsigned char i, j, k,m; for(m=0; m<sec; m++)
{
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
}

主函数如下:首先将单片机和模块的波特率进行统一。然后再进行短信的发送。注意在发送语句之间需要有一定的延迟时间。

#include <STC15F2K60S2.H>
#include <string.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define FOSC_110592M
uchar rec_data[50];//以下是GSM模块返回数据数组
uchar rec_num; void main()
{
uchar i = 0;
P2=0xa0;
P0=0x00;
P2=0x80;
P0=0xff;
Inti();
Uart1Sends("AT\r\n"); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
while(!hand("OK"))
{
clear_rec_data();
i++;
Uart1Sends("AT\r\n");//
DelaySec(1);//延时
if(i>=5)
{
break;
}
} clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
DelaySec(1);//延时
P0=0x00;//初始化和检验完毕,led灯产生信号。
//发送英文短信短信
Uart1Sends("AT+CSCS=\"GSM\"\r\n"); //
DelaySec(1);//延时
Uart1Sends("AT+CSCA?\r\n"); //短信中心号码
DelaySec(1);//延时
Uart1Sends("AT+CMGF=1\r\n"); //方式1
DelaySec(1);//延时
Uart1Sends("AT+CMGS=\"1561288121*\"\r\n"); //此处修改短信接收方电话号
DelaySec(1);//延时
Uart1Sends("I am xx"); //此处修改短信内容
DelaySec(1);//延时
Uart1BYTE(0X1A);
DelaySec(5);//延时
//拨打电话代码
Uart1Sends("ATD1561288121*;\r\n"); //拨打电话
while(1);
}

扩展部分:

查询信号质量,判断手机卡,检测是否连接上网络,是否插入等其他初始化内容(如果能够确保该初始化正确,可以不用考虑下面的代码部分)。

//	Uart1Sends("AT+CSQ\r\n");//查询信号质量
// DelaySec(1);//延时
// i=0;
// while(!hand("OK")) //检测此条指令GSM模块是否执行OK
// {
// clear_rec_data();
// i++;
// Uart1Sends("AT+CSQ\r\n");//
// DelaySec(1);//延时
// if(i>=5)
// {
// break;
// //return;
// }
// }
// P0=0x00;
// clear_rec_data();
// DelaySec(1);//延时
// Uart1Sends("AT+CPIN?\r\n");//查看是否读到手机卡
// DelaySec(1);//延时
// i=0;
// while(!hand("READY")) //检测SIM模块是否收到SIM卡READY
// {
// clear_rec_data();
// i++;
// Uart1Sends("AT+CPIN?\r\n");//是否注册到网络
// DelaySec(1);//延时
// if(i>=5)
// {
// break;
// //return;
// }
// else
// ;
// }
// clear_rec_data();
// DelaySec(1);//延时

三. 最终简化程序


/************************************************************ 首先要确定模块已经注册到网络,手机卡能使用打电话发短信,并且没有设置PIN。
然后正确的硬件连接 P3.0-----STXD或者5VT P3.1-----SRXD或者5VR GND---GND。
但对于51单片机而言,只能接TTL。
然后确认单片机上的晶振,根据晶振修改自己的程序。
本人推荐先将单片机与电脑相连,确定单片机发送的数据是正确的。
如果发送的是乱码,请检查晶振与单片机的串口波特率。 *************************************************************/ #include <STC15F2K60S2.H>
#include <string.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define FOSC_110592M
uchar rec_data[50];//GSM模块返回数据数组
uchar rec_num; void SerialInti() //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xDC; //设定定时初值
TH1 = 0xDC; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
void Serial_interrupt() interrupt 4
{ uchar temp;
temp=SBUF;
rec_data[rec_num++]=temp;
if(rec_num>=50)
rec_num=0;
else
;
RI=0;//接收中断信号清零,表示将继续接收 } //串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
str++;
}
}
void Uart1BYTE(uchar temp)
{
SBUF=temp;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0; } uchar hand(uchar *ptr)
{
if(strstr(rec_data,ptr)!=NULL)
return 1;
else
return 0;
} void clear_rec_data()
{
uchar i;
for(i=0;i<strlen(rec_data);i++)
{
rec_data[i]='0';
}
rec_num=0;
}
//延时函数1s钟
void DelaySec(int sec)
{
unsigned char i, j, k,m; for(m=0; m<sec; m++)
{
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
} void main()
{
uchar i = 0;
P2=0xa0;
P0=0x00;
P2=0x80;
P0=0xff;
SerialInti();
Uart1Sends("AT\r\n"); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
while(!hand("OK"))
{
clear_rec_data();
i++;
Uart1Sends("AT\r\n");//
DelaySec(1);//延时
if(i>=5)
{
break;
}
}
clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
DelaySec(1);//延时
P0=0x00;//初始化和检验完毕,led灯产生信号。
//发送英文短信短信
Uart1Sends("AT+CSCS=\"GSM\"\r\n"); //
DelaySec(1);//延时
Uart1Sends("AT+CSCA?\r\n"); //短信中心号码
DelaySec(1);//延时
Uart1Sends("AT+CMGF=1\r\n"); //方式1
DelaySec(1);//延时
Uart1Sends("AT+CMGS=\"1561288121*\"\r\n"); //此处修改短信接收方电话号
DelaySec(1);//延时
Uart1Sends("I am xx"); //此处修改短信内容
DelaySec(1);//延时
Uart1BYTE(0X1A);
DelaySec(5);//延时
//拨打电话代码
Uart1Sends("ATD1561288121*;\r\n"); //拨打电话
while(1);
}

四. 发送中文短信

本功能的实现需要使用unicode编码字符,详情见-->本人博客


/************************************************************
首先要确定模块已经注册到网络,手机卡能使用打电话发短信,并且没有设置PIN。
然后正确的硬件连接 P3.0-----STXD或者5VT P3.1-----SRXD或者5VR GND---GND。
但对于51单片机而言,只能接TTL。
然后确认单片机上的晶振,根据晶振修改自己的程序。
本人推荐先将单片机与电脑相连,确定单片机发送的数据是正确的。
如果发送的是乱码,请检查晶振与单片机的串口波特率。
*************************************************************/ #include <STC15F2K60S2.H>
#include <string.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define FOSC_110592M
uchar rec_data[50];//GSM模块返回数据数组
uchar rec_num; void lInti() //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xDC; //设定定时初值
TH1 = 0xDC; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
void Serial_interrupt() interrupt 4
{ uchar temp;
temp=SBUF;
rec_data[rec_num++]=temp;
if(rec_num>=50)
rec_num=0;
else
;
RI=0;//接收中断信号清零,表示将继续接收 } //串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
str++;
}
}
void Uart1BYTE(uchar temp)
{
SBUF=temp;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0; } uchar hand(uchar *ptr)
{
if(strstr(rec_data,ptr)!=NULL)
return 1;
else
return 0;
} void clear_rec_data()
{
uchar i;
for(i=0;i<strlen(rec_data);i++)
{
rec_data[i]='0';
}
rec_num=0;
}
//延时函数1s钟
void DelaySec(int sec)
{
unsigned char i, j, k,m; for(m=0; m<sec; m++)
{
_nop_();
_nop_();
i = 43;
j = 6;
k = 203;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
} void main()
{
uchar i = 0;
P2=0xa0;
P0=0x00;
P2=0x80;
P0=0xff;
Inti();
Uart1Sends("AT\r\n"); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
while(!hand("OK"))
{
clear_rec_data();
i++;
Uart1Sends("AT\r\n");//
DelaySec(1);//延时
if(i>=5)
{
break;
}
}
clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
DelaySec(1);//延时
P0=0x00;//初始化和检验完毕,led灯产生信号。
//发送中文短信短信
Uart1Sends("AT+CMGF=1\r\n"); //
DelaySec(1);//延时
Uart1Sends("AT+CSMP=17,167,2,25\r\n");
DelaySec(1);//延时
Uart1Sends("AT+CSCS=\"UCS2\"\r\n");
DelaySec(1);//延时
Uart1Sends("AT+CMGS=\"0031003500360031003200380038003100320031****\"\r\n"); //此处修改短信接收方电话号
DelaySec(1);//延时
Uart1Sends("621172314f60"); //此处修改短信内容
DelaySec(1);//延时
Uart1BYTE(0X1A);
DelaySec(5);//延时
//拨打电话代码
Uart1Sends("ATD1561288121*;\r\n"); //拨打电话
while(1);
}

通过STC15F2K60S2控制SIM900A发中英文短信,打电话的更多相关文章

  1. linux下GPRS模块使用AT命令实现拨接电话,发中英文短信

    开发板           :fl2440 cpu                :  s3c2440(arm9) 开发模块       :A7(GPRS/GPS) 远程登陆软件:PUTTY **** ...

  2. SIM900A—发送、接收中英文短信

    文章目录 一.SMS简介 二.短信的控制模式与编码 1.Text Mode 2.PDU Mode 3.GSM编码 4.UCS2编码 三.收发英文短信 1.AT+CPMS查询短信数量 2.AT+CNMI ...

  3. 用“网建”平台发手机短信的C#代码

    一直都用这个平台发手机短信的,今天做新项目的时候用到了,但是上来博客搜索不到,只好翻以前的源代码翻了好久才找到了,先记下来,以作备用: using System; using System.Colle ...

  4. 用python twilio模块实现发手机短信的功能

    前排提示:这个模块不是用于对陌生人进行短信轰炸和电话骚扰的,这个模块也没有这个功能,如果是抱着这个心态来的,可以关闭网页了 语言:python 步骤一:安装twilio模块 pip install t ...

  5. eclipse开发安卓 发短信打电话发送邮件功能

    1.在mainfiest中添加   //添加拨打电话的功能    <uses-permission android:name="android.permission.CALL_PHON ...

  6. 短信控制的 智能插头(sim900a arduino uno)

    https://www.arduino.cn/thread-19432-1-2.html 1.所需工具:(1)arduino UNO,(2)sim900a模块,(3)单路继电器,(4)220v ac转 ...

  7. SIM900A 通过RS232串口进行短信的发送。

    一.基本数据 1.SIM900A模块支持RS232串口和LVTTL串口.保留了232口,在学习或者开发时可以监听51低端单片机和模块指令执行情况,能更快的找出原因,节省开发和学习的时间. 2.此模块供 ...

  8. iOS开发中打电话发短信等功能的实现

    在APP开发中,可能会涉及到打电话.发短信.发邮件等功能.比如说,通常一个产品的"关于"页面,会有开发者的联系方式,理想情况下,当用户点击该电话号码时,能够自动的帮用户拨出去,就涉 ...

  9. IOS,发短信,发邮件,打电话

    今天把APP里常用小功能 例如发短信.发邮件.打电话.全部拿出来简单说说它们的实现思路. 1.发短信实现打电话的功能,主要二种方法,下面我就分别说说它们的优缺点.1.1.发短信(1)——URL // ...

随机推荐

  1. Swift中的感叹号( ! )与问号( ? )之谜

    基本了解 在Swift代码会经常看到定义属性或方法参数时类型后面会紧跟一个感叹号( ! )或问号( ? ), 刚开始接触Swift的童鞋就可能不太明白之代表什么意思,一头雾水,开始凌乱了. 本文将带你 ...

  2. Flutter 学习路线图

    Flutter 学习路线图 如果你真的觉得很难,坚持不了了,那就放弃,既然放弃了就不要抱怨没有得到. 选择你热爱的,坚持你选择的,不抱怨放弃的. 前言 Flutter越来越火,学习Flutter的人越 ...

  3. hibernate连接oracle

    <?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC           & ...

  4. CF1327D Infinite Path 题解

    原题链接 太坑了我谔谔 简要题意: 求一个排列的多少次幂能达到另一个排列.排列的幂定义见题.(其实不是新定义的,本来就是这么乘的) 很显然,这不像快速幂那样可以结合律. 既然这样,就从图入手. 将 \ ...

  5. 【洛谷】P2444 [POI2000]病毒——AC自动机

    题目链接 题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段, ...

  6. 一个完整的机器学习项目在Python中演练(三)

    大家往往会选择一本数据科学相关书籍或者完成一门在线课程来学习和掌握机器学习.但是,实际情况往往是,学完之后反而并不清楚这些技术怎样才能被用在实际的项目流程中.就像你的脑海中已经有了一块块"拼 ...

  7. 学习Angular1

    教程: 参考教程: https://www.runoob.com/angularjs/angularjs-tutorial.html 一.angular的简介AngularJS 是一个 JavaScr ...

  8. 寻找一把进入 Alibaba Sentinel 的钥匙(文末附流程图)

    经过前面几篇文章的铺垫,我们正式来探讨 Sentinel 的 entry 方法的实现流程.即探究进入 Alibaba Sentinel 核心的一把钥匙. @ 目录 1.SphU.entry 流程分析 ...

  9. C. Yet Another Walking Robot Round #617 (Div. 3)()(map + 前后相同状态的存储)

    C. Yet Another Walking Robot time limit per test 1 second memory limit per test 256 megabytes input ...

  10. 如何让Java应用成为杀不死的小强?(中篇)

    各位坐稳扶好,我们要开车了.不过在开车之前,我们还是例行回顾一下上期分享的要点. 上期我们抛了一个砖:“如何实现 Java 应用进程的状态监控,如果被监控的进程 down 掉,是否有机制能启动起来?” ...