标题:
基于15f2k61s2以及GSM 8的中文短信收发单片机程序
[打印本页]
作者:
CZP1234
时间:
2017-8-3 09:34
标题:
基于15f2k61s2以及GSM 8的中文短信收发单片机程序
1、使用单片机串口2与模块通信;接法如下
STC单片机15f2k61s2 GPRS模块
P1.0(RXD2)->RXD
P1.1(TXD2)->TXD
GND ->GND
0.png
(38.33 KB, 下载次数: 67)
下载附件
2017-8-3 16:32 上传
晶振选用22.1184MHz (可选用内部晶振)
2、板子上电后运行指示灯RUNING_LED会以一秒的频率闪烁;
3、打开代码修改短信中心号、接收方手机号和短信内容,编译成功后下载到单片机里面,就可以实现发送一条中文短信,中文短信具体的解析可以参考串口调试笔记
单片机源程序如下:
/**********************************************************************************
* 工程名 :
* 描述 :通过手机发送短信控制LED
* 实验平台:STC15XX
* 库版本 :
**********************************************************************************/
#include "string.h"
#include "delay.h"
#include "uart.h"
#define uchar unsigned char
#define uint unsigned int
#define Buf1_Max 32 //串口1缓存长度
#define Buf2_Max 200 //串口2缓存长度
/************* 本地常量声明 **************/
sbit RUNING_LED = P2^6; //运行指示灯
sbit LED = P2^3; //控制指示灯
sbit PWR_MG323 = P2^0;
sbit l1 = P4^5; //控制指示灯
sbit l2 = P4^1;
sbit yw=P1^5;
static unsigned char *content="0891683108706505F011000D91688133102684F80008AA2c745E876079D1628063D0919260A8FF0C5F53524D533A57DF70DF96FE91CF8D856807FF0C8BF76CE8610FFF01";//瑞蝠科技提醒您,当前区域烟雾量超标,请注意!
/************************短信内容解析**************************************/
/*
//短信中心号(倒序) 目标手机(倒序) 短信内容(测试已经完成)
8613800756500F 8618330162488F
0891 683108706505F0 11000D91 688133102684F8 0008AA0C 70DF96FE91CF8D856807FF01
*/
/************* 本地变量声明 **************/
xdata u8 Uart2_Buf[Buf2_Max];
xdata u8 Uart1_Buf[Buf1_Max];
u8 Times=0,First_Int = 0,shijian=0;
uchar num;
uchar phone[]="\"18330162488\"";
//u8 Time_count=0;
bdata u8 Flag;//定时器标志位
sbit Timer0_start =Flag^0; //定时器0延时启动计数器
sbit Uart2_Start =Flag^1; //串口2开始接收数据
sbit Uart2_End =Flag^2; //串口2接收数据结束
xdata uchar tab1[]="0010\0";
xdata uchar tab2[]="0020\0";
xdata uchar tab3[]="0030\0";
//uchar dj=1;
bit a=0;
/************* 本地函数声明 **************/
void GPIO_config(void); //端口初始化配置
void Timer0Init(void); //定时器0初始化
void CLR_Buf2(void); //清除串口2接收缓存
u8 Find(u8 *a); //查找字符串
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time); //发送AT指令函数
void Set_Pdu_Mode(void);//设置短信模式PDU
void Set_Text_Mode(void);
void Wait_CREG(void); //查询等待模块注册成功
void Send_Pdu_Sms(void);//发送一条中文短信
void Send_Pdu_Sms1(void);
void Check_New_Message(void);
uchar zh(void);
void Send_Text_Sms(void);
void ChangeNum(uchar* num, uchar* des);
void CLR_Buf1(void);
/*******************************************************************************
* 函数名 : main
* 描述 : 主函数
* 输入 :
* 输出 :
* 返回 :
* 注意 : 串口2负责与MG323模块通信,串口1用于串口调试,可以避免在下载程序时数据
还发送到模块
*******************************************************************************/
void main(void)
{
uchar f=0,i=0,n=0;
uchar sz[7]={0x42,0x4d,0xe1,0x00,0x00,0x01,0x70};
GPIO_config();
Uart1Init();
Uart2Init();
Timer0Init();
EA=1; //开总中断
Wait_CREG(); //查询等待模块注册成功
Second_AT_Command("AT+CMGD=1,4","OK",3);// 删除sim卡上已发的和未发的全部短信
Second_AT_Command("AT+CMGD=1,2","OK",3);// 删除已读短信
Set_Text_Mode();
l1=0;
delay_ms(1000);
for(n=0;n<3;n++)
{
for( i=0;i<7;i++)
UART1_SendData(sz[i]);
delay_ms(1000);
}
while(f==0)
{
f=zh();
}
Send_Text_Sms();
l2=0;
while(1)
{
Check_New_Message();
//
if(yw==0)
{
delay_ms(10);
if(yw==0&&a==0)
{
Set_Pdu_Mode();//设置短信为PDU模式
Send_Pdu_Sms();//发送一条短消息
Set_Text_Mode();
// Send_Text_Sms();
a=1;
}
}
if(yw==1)
a=0;
}
delay_ms(1000);
}
/*******************************************************************************
* 函数名 : Uart1
* 描述 : 串口1中断服务入口函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Uart1() interrupt 4
{
if (RI)
{
RI = 0; //清除RI位
Uart1_Buf[num]=SBUF;
num++;
if(num>=32)
num=0;
}
if (TI)
{
TI = 0; //清除TI位
}
}
/*******************************************************************************
* 函数名 : Uart2
* 描述 : 串口2中断服务入口函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Uart2() interrupt 8
{
IE2 &= ~0x01; //关闭串口2中断
if (S2CON & S2RI)
{
S2CON &= ~S2RI; //清除S2RI位
Uart2_Buf[First_Int] = S2BUF; //将接收到的字符串存到缓存中
First_Int++; //缓存指针向后移动
if(First_Int > Buf2_Max) //如果缓存满,将缓存指针指向缓存的首地址
{
First_Int = 0;
}
}
if (S2CON & S2TI)
{
S2CON &= ~S2TI; //清除S2TI位
}
IE2 |= 0x01; //使能串口2中断
}
/*******************************************************************************
* 函数名 : Timer0_ISR
* 描述 : 定时器0中断服务入口函数,20ms中断一次
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
static u8 Time_count=0;
TR0=0;//关定时器
Time_count++;
if(Time_count>=50)
{
Time_count = 0;
RUNING_LED =~RUNING_LED;
}
if(Timer0_start)
Times++;
if(Times > (50*shijian))
{
Timer0_start = 0;
Times = 0;
}
TR0=1;//开定时器
}
/*******************************************************************************
* 函数名 : GPIO_config
* 描述 : IO口配置函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void GPIO_config(void)
{
P3M1 &= 0XC3; //配置P32~P35为推挽输出
P3M0 |= ~0XC3;
LED=0;
RUNING_LED=0;
}
void Timer0Init(void) //20毫秒@22.1184MHz
{
AUXR &= 0x7F; //12T模式
TMOD &= 0xF0; //设置定时器模式 16位重载
TL0 = 0x00; //设定定时器初值
TH0 = 0x70; //设定定时器初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
/*******************************************************************************
* 函数名 : CLR_Buf2
* 描述 : 清除串口2缓存数据
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void CLR_Buf2(void)
{
u16 k;
for(k=0;k<Buf2_Max;k++) //将缓存内容清零
{
Uart2_Buf[k] = 0x00;
}
First_Int = 0; //接收字符串的起始存储位置
}
void CLR_Buf1(void)
{
u16 k;
for(k=0;k<Buf2_Max;k++) //将缓存内容清零
{
Uart1_Buf[k] = 0x00;
}
num = 0; //接收字符串的起始存储位置
}
/*******************************************************************************
* 函数名 : Find
* 描述 : 判断缓存中是否含有指定的字符串
* 输入 :
* 输出 :
* 返回 : unsigned char:1 找到指定字符,0 未找到指定字符
* 注意 :
*******************************************************************************/
u8 Find(u8 *a)
{
if(strstr(Uart2_Buf,a)!=NULL)
return 1;
else
return 0;
}
/*******************************************************************************
* 函数名 : Second_AT_Command
* 描述 : 发送AT指令函数
* 输入 : 发送数据的指针、发送等待时间(单位:S)
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Second_AT_Command(u8 *b,u8 *a,u8 wait_time)
{
u8 i;
u8 *c;
c = b; //保存字符串地址到c
CLR_Buf2();
i = 0;
while(i == 0)
{
if(!Find(a)) //查找需要应答的字符
{
if(Timer0_start == 0)//超时重新发送命令
{
b = c; //将字符串地址给b
for (b; *b!='\0';b++)
{
UART2_SendData(*b);
}
UART2_SendLR();
Times = 0;
shijian = wait_time;
Timer0_start = 1; //开始计时
}
}
else
{
i = 1;
Timer0_start = 0;
}
}
CLR_Buf2();
}
/*******************************************************************************
* 函数名 : Set_Pdu_Mode
* 描述 : 设置短信为TEXT文本模式
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Set_Pdu_Mode(void)
{
Second_AT_Command("ATE0","OK",3); //取消回显
Second_AT_Command("AT+CMGF=0","OK",3); //设置PDU模式
Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3);//所有操作都在SIM卡中进行
}
/*******************************************************************************
* 函数名 : Send_Pdu_Sms
* 描述 : 发送PDU文本短信
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Send_Pdu_Sms(void)
{
Second_AT_Command("AT+CMGS=59",">",3); //发送数据长度:27(具体的计算方法看串口调试比较)接收到“>”才发送短信内容
UART2_SendString(content); //发送短信内容
UART2_SendData(0X1A); //发送结束符
}
/*******************************************************************************
* 函数名 : GPS
* 描述 : 发送PDU文本短信
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
//void GPS(void)
//{
// Second_AT_Command("AT+CGNSPWR=1\r\n","OK",2); //打开GPS电源
// delay_ms(100);
// Second_AT_Command("AT+CGNSSEQ=\"RMC\"\r\n","OK",2);//定义NMEA解析
// Second_AT_Command("AT+CGNSINF\r\n","+CGNSINF: 1,1,",3);//等待定位成功
// Second_AT_Command("AT+CGNSURC=0\r\n","OK",1); //设置GPS输出参数
//}
/*******************************************************************************
* 函数名 : Wait_CREG
* 描述 : 等待模块注册成功
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Wait_CREG(void)
{
u8 i;
u8 k;
i = 0;
CLR_Buf2();
while(i == 0)
{
CLR_Buf2();
UART2_SendString("AT+CREG?");//查询模块网络注册状态
UART2_SendLR();
delay_ms(5000);
for(k=0;k<Buf2_Max;k++)
{
if(Uart2_Buf[k] == ':')
{
if((Uart2_Buf[k+4] == '1')||(Uart2_Buf[k+4] == '5')) //表明网络注册成功
{
i = 1;
// UART1_SendString("信号检测中\n");
break;
}
}
}
}
}
void Set_Text_Mode(void)
{
Second_AT_Command("ATE0","OK",3);
//取消回显
Second_AT_Command("AT+CNMI=3,2,0,0,0","OK",3); //新短信直接输出
Second_AT_Command("AT+CMGF=1","OK",3); //TEXT模式
Second_AT_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3); //所有操作都在SIM卡中进行
}
void Send_Text_Sms(void)
{
unsigned char temp[50]="AT+CMGS=";
unsigned char temp1[70]="\0";
strcat(temp,phone); //字符串拼接函数(库函数)
Second_AT_Command(temp,">",3); //等待接收到“>”才发送短信内容
strcat(temp1,"PM1.0:");
strcat(temp1,tab1); //字符串拼接函数(库函数)
strcat(temp1,"ug/m3\nPM2.5:"); //字符串拼接函数(库函数)
strcat(temp1,tab2); //字符串拼接函数(库函数)
strcat(temp1,"ug/m3\nPM10 :"); //字符串拼接函数(库函数)
strcat(temp1,tab3);
strcat(temp1,"ug/m3\n"); //字符串拼接函数(库函数)
UART2_SendString(temp1); //发送短信内容
UART1_SendString(temp1); //发送短信内容
UART2_SendData(0X1A); //发送结束符
l2=~l2;
}
void Check_New_Message(void)
{
u8 temp=0;
uchar *hao,j,f;
if(strstr(Uart2_Buf,"+CMT")!=NULL) //若缓存字符串中含有"+CMT"就表示有新的短信
{
l2=~l2;
delay_ms(50);//等待数据全部接收完成
// UART1_SendString(Uart2_Buf);
if(strstr(Uart2_Buf,"67E58BE2")!=NULL)
{
// UART1_SendString("验证通过\n");
hao=strstr(Uart2_Buf,"+CMT");
for(j=0;j<11;j++)
{
phone[j+1]=*(hao+j+10);
}
while(f==0)
{
f=zh();
}
Set_Text_Mode();
Send_Text_Sms();
}
CLR_Buf2();
}
}
uchar zh()
{
uint pm1,pm2,pm10;
uchar i,dj;
uchar cx[]={0x42,0x4d,0xe2,0x00,0x00,0x01,0x71};
CLR_Buf1();
for(i=0;i<7;i++)
UART1_SendData(cx[i]);
delay_ms(1000);
if(Uart1_Buf[0]==0x42&&Uart1_Buf[1]==0x4d&&Uart1_Buf[2]==0x00&&Uart1_Buf[3]==0x1c)
{
// pm1=Uart1_Buf[4]*256+Uart1_Buf[5];
// pm2=Uart1_Buf[6]*256+Uart1_Buf[7];
// pm10=Uart1_Buf[8]*256+Uart1_Buf[9];
pm1=Uart1_Buf[10]*256+Uart1_Buf[11];
pm2=Uart1_Buf[12]*256+Uart1_Buf[13];
pm10=Uart1_Buf[14]*256+Uart1_Buf[15];
// CLR_Buf1();
tab1[0]=pm1/1000+0x30;
tab1[1]=pm1%1000/100+0x30;
tab1[2]=pm1%100/10+0x30;
tab1[3]=pm1%10+0x30;
if(tab1[0]==0x00)
{
tab1[0]=' ';
if(tab1[1]==0x00)
{
tab1[1]=' ';
if(tab1[2]==0x00)
tab1[2]=' ';
}
}
tab2[0]=pm2/1000+0x30;
tab2[1]=pm2%1000/100+0x30;
tab2[2]=pm2%100/10+0x30;
tab2[3]=pm2%10+0x30;
if(tab2[0]==0x00)
{
tab2[0]=' ';
if(tab2[1]==0x00)
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
4.发送中文短信.rar
(99.78 KB, 下载次数: 20)
2017-8-3 09:33 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1