通过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!='\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);
}

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
STM32F103C8T6是一款常用的单片机,而SIM900A是一款常用的GSM模块,可以用于短信。下面是使用STM32F103C8T6控制SIM900A送中文短信的步骤: 1. 首先,连接STM32F103C8T6和SIM900A模块。将STM32F103C8T6的串口引脚(例如USART1)连接到SIM900A模块的串口引脚(例如SIM900A的RXD和TXD引脚)。 2. 在STM32F103C8T6上配置串口通信。使用STM32的串口库函数,设置串口的波特率、数据位、停止位等参数,并使能串口。 3. 初始化SIM900A模块。通过串口向SIM900A送AT指令,检查模块是否正常工作,并等待模块的响应。 4. 设置SIM900A模块短信格式。通过送AT指令设置短信格式为文本模式,并等待模块的响应。 5. 编写短信的代码。使用STM32的串口库函数,向SIM900A送AT指令来设置短信接收号码和短信内容。注意,中文字符需要使用Unicode编码进行转换。 6. 短信。通过送AT指令,将短信送给SIM900A模块,并等待模块的响应。 7. 检查短信送状态。通过送AT指令,查询短信送状态,并等待模块的响应。 8. 处理SIM900A模块的响应。根据SIM900A模块返回的响应,判断短信是否送成功。 请注意,以上步骤仅为一般性的指导,具体的实现细节还需要根据具体的硬件和软件环境进行调整。另外,还需要参考STM32F103C8T6和SIM900A模块的相关文档和资料进行具体的编程和配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会咬鸢的风

愿技术也有温情,给所需人以价值

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值