zoukankan      html  css  js  c++  java
  • 通过STC15F2K60S2控制SIM900A发中英文短信,打电话

    本文通过串口通信,使用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!='')
    	{
    		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
    "); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
    	while(!hand("OK")) 
    	{
    		clear_rec_data();
    		i++;
    		Uart1Sends("AT
    ");//
    		DelaySec(1);//延时
    		if(i>=5)
    		{
    			break;
    		}
    	}
    	
    	clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
    	DelaySec(1);//延时
    	P0=0x00;//初始化和检验完毕,led灯产生信号。
    //发送英文短信短信
    	Uart1Sends("AT+CSCS="GSM"
    "); //
    	DelaySec(1);//延时
    	Uart1Sends("AT+CSCA?
    "); //短信中心号码
    	DelaySec(1);//延时
    	Uart1Sends("AT+CMGF=1
    ");  //方式1
    	DelaySec(1);//延时
    	Uart1Sends("AT+CMGS="1561288121*"
    ");  //此处修改短信接收方电话号
    	DelaySec(1);//延时
    	Uart1Sends("I am xx");  //此处修改短信内容
    	DelaySec(1);//延时
    	Uart1BYTE(0X1A);
    	DelaySec(5);//延时
    	//拨打电话代码
    	Uart1Sends("ATD1561288121*;
    ");  //拨打电话
    	while(1);
    }

    扩展部分:

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

    //	Uart1Sends("AT+CSQ
    ");//查询信号质量
    //	DelaySec(1);//延时
    //	i=0;
    //	while(!hand("OK")) //检测此条指令GSM模块是否执行OK
    //	{
    //		clear_rec_data();
    //		i++;
    //		Uart1Sends("AT+CSQ
    ");//
    //		DelaySec(1);//延时
    //		if(i>=5)                                                 
    //		{
    //			break;
    //			//return;
    //		}
    //	}
    //	P0=0x00;
    //	clear_rec_data();
    //	DelaySec(1);//延时
    //	Uart1Sends("AT+CPIN?
    ");//查看是否读到手机卡
    //	DelaySec(1);//延时
    //	i=0;
    //	while(!hand("READY")) //检测SIM模块是否收到SIM卡READY
    //	{
    //		clear_rec_data();
    //		i++;
    //		Uart1Sends("AT+CPIN?
    ");//是否注册到网络
    //		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!='')
    	{
    		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
    "); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
    	while(!hand("OK")) 
    	{
    		clear_rec_data();
    		i++;
    		Uart1Sends("AT
    ");//
    		DelaySec(1);//延时
    		if(i>=5)
    		{
    			break;
    		}
    	}
    	clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
    	DelaySec(1);//延时
    	P0=0x00;//初始化和检验完毕,led灯产生信号。
    //发送英文短信短信
    	Uart1Sends("AT+CSCS="GSM"
    "); //
    	DelaySec(1);//延时
    	Uart1Sends("AT+CSCA?
    "); //短信中心号码
    	DelaySec(1);//延时
    	Uart1Sends("AT+CMGF=1
    ");  //方式1
    	DelaySec(1);//延时
    	Uart1Sends("AT+CMGS="1561288121*"
    ");  //此处修改短信接收方电话号
    	DelaySec(1);//延时
    	Uart1Sends("I am xx");  //此处修改短信内容
    	DelaySec(1);//延时
    	Uart1BYTE(0X1A);
    	DelaySec(5);//延时
    //拨打电话代码
    	Uart1Sends("ATD1561288121*;
    ");  //拨打电话
    	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!='')
    	{
    		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
    "); //同步波特率,如果将模块配置固定波特率,此条指令就不需要发了
    	while(!hand("OK")) 
    	{
    		clear_rec_data();
    		i++;
    		Uart1Sends("AT
    ");//
    		DelaySec(1);//延时
    		if(i>=5)
    		{
    			break;
    		}
    	}
    	clear_rec_data();//删除存储的GSM模块返回的数据,以便于以后继续判断
    	DelaySec(1);//延时
    	P0=0x00;//初始化和检验完毕,led灯产生信号。
    //发送中文短信短信
    	Uart1Sends("AT+CMGF=1
    "); //
    	DelaySec(1);//延时
    	Uart1Sends("AT+CSMP=17,167,2,25
    "); 
    	DelaySec(1);//延时
    	Uart1Sends("AT+CSCS="UCS2"
    ");  
    	DelaySec(1);//延时
    	Uart1Sends("AT+CMGS="0031003500360031003200380038003100320031****"
    ");  //此处修改短信接收方电话号
    	DelaySec(1);//延时
    	Uart1Sends("621172314f60");  //此处修改短信内容
    	DelaySec(1);//延时
    	Uart1BYTE(0X1A);
    	DelaySec(5);//延时
    //拨打电话代码
    	Uart1Sends("ATD1561288121*;
    ");  //拨打电话
    	while(1);
    }
    博客园
  • 相关阅读:
    放大图 带回弹效果
    用recyclerview实现对话(通过接口实现)
    java 问号表达式
    recyclerview的使用
    我遇到的报错信息整理
    横竖屏切换
    NOIP 2017提高组自测 奶酪
    小蝌蚪找妈妈 牛客
    牛客练习赛50 C tokitsukaze and Soldier
    洛谷P1630 求和
  • 原文地址:https://www.cnblogs.com/wang-zefeng/p/12555648.html
Copyright © 2011-2022 走看看