【谢绝转载!】【谢绝转载!】【谢绝转载!】
【说明】
实物连接图如下:
【短信控制】
发送短信到GSM模块,收到相应的指令对应板子上的灯亮灭。
然后模块会向手机发送一条中文短信
【源代码】目前仍然处于开发中。。。。。
/******************************
工程名 :短信控制家电
1 先用USB转TTL模块测试模块好用,并修改波特率到9600(AT+IPR=9600)再用单片机调试
2 51单片机晶振 11.0592MHz,12M不可以用
3 如果模块无开机自启动电路,需要先按接线图中说明进行开机
版本号:V1
手机发送“当前状态”到模块,控制LED灯;
模块并发送两条语句给手机
*******************************/
#include "string.h"
#include "STC12C2052AD.h"
#define cache_max 200 //串口接收缓存长度
xdata unsigned char uart_cache[cache_max]; // xdata 把变量存在flash中,而不存在RAM中
//code 定义的数据要放在ROM里面,写入后就不能再更改
bdata unsigned char Flag; //定时器标志位 bdata 把变量定义为可拆成8位寻址
sbit Timer_start =Flag^0; //延时计数功能开关
sbit RUNING = P3^7; //运行指示灯
sbit LED1 = P1^1; //控制电脑开机 关机
sbit LED2 = P1^2; //控制电脑开机 关机
sbit LED3 = P1^3; //控制电脑开机 关机
sbit LED4 = P1^4; //控制电脑开机 关机
sbit LED5 = P1^5; //控制电脑开机 关机
unsigned char code *status="5F53524D72B66001"; //当前状态
unsigned char code *computer_on="753581115F00673A"; //电脑开机
unsigned char code *computer_off="753581115173673A"; //电脑关机
unsigned char Times=0; // 定时器中断次数累加
unsigned char First_Int = 0; // 串口字符串
unsigned char delay=0; //延时长度
void SendData(unsigned char dat){ // 发一个8位数据到串口SBUF
ES=0;
SBUF=dat;
while(TI!=1);
TI=0;
ES=1;
}
void SendString(unsigned char *s){ // 发多个8位数据到串口SBUF
while(*s)
SendData(*s++);
}
void SendLR(void) { // 发回车换行
SendString("\r\n");
}
void DELAY_MS (unsigned int a){ // 延时
unsigned int i;
while ( --a != 0 )
for (i=0;i<=600;i++);
}
void Uart1Init(void) { //9600bps@11.0592MHz
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1; //开串口中断
}
void Uart1() interrupt 4{
uart_cache[First_Int] = SBUF; //将接收到的字符串存到缓存中
First_Int++; //缓存指针向后移动
if(First_Int > cache_max) //如果缓存满,将缓存指针指向缓存的首地址
First_Int = 0;
RI = 0; //清除RI位
}
void Timer0Init(void) { //20毫秒@11.0592MHz
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //
TMOD |= 0x01; //设置定时器模式,16位定时器
TL0 = 0x00; //设置定时器初值
TH0 = 0xB8; //设置定时器初值
TF0 = 0; //清TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1; //开总中断
}
void Timer0_ISR() interrupt 1{
static unsigned char Time_count=0; // 定时器计数器 static全局生命周期
TR0=0; //关定时器
TL0 = 0x00; //重设定时器初值
TH0 = 0xB8; //重设定时器初值
Time_count++;
if(Time_count>=50) {
Time_count = 0;
RUNING =~RUNING;
}
if(Timer_start) Times++; //如果收到允许定时,开始计时
if(Times > (50*delay)){ //如果Times 到达设定时间
Timer_start = 0;
Times = 0; // 通知程序 计时时间已到
}
TR0=1; //开定时器
}
void CLR_Buf1(void){
unsigned int k;
for(k=0;k<cache_max;k++) //将缓存内容清零
uart_cache[k] = 0x00;
First_Int = 0; //接收字符串的起始存储位置
}
unsigned char Find(unsigned char *a) { //查找字符串
if(strstr(uart_cache,a)!=NULL) return 1;
else return 0;
}
void Send_Command(unsigned char *b,unsigned char *a,unsigned char wait_time)
{
unsigned char i;
unsigned char *c;
c = b; //保存字符串地址到c
CLR_Buf1();
i = 0;
while(i == 0) {
if(Find(a)==NULL) { //查找需要应答的字符
if(Timer_start == 0){
b = c; //将字符串地址给b
for (b; *b!='\0';b++)
SendData(*b);
SendLR();
Times = 0;
delay = wait_time;
Timer_start = 1; // 开启定时器,
}
}
else {
i = 1;LED2=!LED2;DELAY_MS(1000);
Timer_start = 0;
}
}
CLR_Buf1();
}
void Set_Text_Mode(void) { //设置短信为TEXT文本模式
Send_Command("ATE0","OK",3); //取消回显
Send_Command("AT+CNMI=3,2,0,0,0","OK",3); //新短信直接输出
Send_Command("AT+CMGF=1","OK",3); //TEXT模式
Send_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3); //所有操作都在SIM卡中进行
}
void Check_New_Message(void) { //检查是否有新信息,并执行信息内容指令
unsigned char temp=0;
if(strstr(uart_cache,"13429678754")!=NULL) { //若缓存字符串中含有"13429678754"就表示有新的短信
DELAY_MS(300); LED2=0; //等待数据全部接收完成
// computer_ctrol=!computer_ctrol;
// 判断到【当前状态】字符
if(strstr(uart_cache,status)!=NULL) { LED3=0; //读取【当前状态】并发送
Send_Command("AT+CSMP=17,167,2,25","OK",3); //设置文本模式参数
Send_Command("AT+CSCS=\"UCS2\"","OK",3); //设置字符集
Send_Command("AT+CMGS=\"00310033003400320039003600370038003700350034\"",">",3);//手机号码13429678754 有回车
Send_Command("662554E5FF0C4F60597DFF01000d000a726980547F51",">",3);//手机号码13429678754 有回车
SendData(0x1a);// 开始发送 返回OK
}
CLR_Buf1(); // 清空SBUF缓存
}
}
void Wait_CREG(void) { //等待模块注册成功
unsigned char i;
unsigned char k;
i = 0;
CLR_Buf1();
while(i == 0) {
CLR_Buf1(); LED1=1;
SendString("AT+CREG?"); //查询模块网络注册状态
SendLR();
DELAY_MS(1000);
for(k=0;k<cache_max;k++) {
if(uart_cache[k] == ':') {
if((uart_cache[k+4] == '1')||(uart_cache[k+4] == '5')){ //表明网络注册成功
i = 1; LED1=0;DELAY_MS(1000);
break;
}
}
}
}
}
void main(void){
Timer0Init(); //初始化定时器0
Uart1Init(); //初始化串口9600
Send_Command("AT","OK",3);
Wait_CREG(); //查询等待模块注册成功
Set_Text_Mode(); //设置短信为TEXT模式
Send_Command("AT+CMGD=1,4","OK",3);//删除卡上所有短信
while(1) {
Check_New_Message();
}
}
字符串合并
/******************************
工程名 :短信控制家电
1 先用USB转TTL模块测试模块好用,并修改波特率到9600(AT+IPR=9600)再用单片机调试
2 51单片机晶振 11.0592MHz,12M不可以用
3 如果模块无开机自启动电路,需要先按接线图中说明进行开机
版本号:V1
手机发送“当前状态”到模块,控制LED灯;
模块并发送两条语句给手机
*******************************/
#include "STC12C2052AD.h"
#define cache_max 200 //串口接收缓存长度,不宜太大,k=0;k<cache_max;k++会死机
//xdata 把变量存在flash中,而不存在RAM中,写入后可以更改
//code 定义的数据要放在ROM里面,写入后就不能再更改
xdata unsigned char uart_cache[cache_max]; // 缓存长度
xdata unsigned char send_cache[190]=""; // 缓存长度
bdata unsigned char Flag; //定时器标志位 bdata 把变量定义为可拆成8位寻址
sbit Timer_start =Flag^0; //延时计数功能开关
char NULL=0;
sbit RUNING = P3^7; //运行指示灯
sbit LED1 = P1^7; //控制电脑开机 关机
sbit LED2 = P1^2; //控制电脑开机 关机
sbit LED3 = P1^3; //控制电脑开机 关机
sbit LED4 = P1^4; //控制电脑开机 关机
sbit LED5 = P1^5; //控制电脑开机 关机
unsigned char code status[]="5F53524D72B66001"; //当前状态
unsigned char code computer_on[]="753581115F00673A"; //电脑开机
unsigned char code computer_off[]="753581115173673A"; //电脑关机
unsigned char Times=0; // 定时器中断次数累加
unsigned char First_Int = 0; // 串口字符串
unsigned char delay=0; //延时长度
char * search(const char *str1, const char *str2){
int n;
if (*str2) {
while(*str1) {
for(n = 0; *(str1+n) == *(str2+n); n++ ) {
if (!*(str2+n+1)) {
return (char *)str1;
}
}
str1++;
}
return NULL;
}
return NULL;
}
char* strcat ( char * dst , const char * src ){
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return(dst); /* return dst */
}
void SendData(unsigned char dat){ // 发一个8位数据到串口SBUF
ES=0;
SBUF=dat;
while(TI!=1);
TI=0;
ES=1;
}
void SendString(unsigned char *s){ // 发多个8位数据到串口SBUF
while(*s)
SendData(*s++);
}
void SendLR(void) { // 发回车换行
SendString("\r\n");
}
void DELAY_MS (unsigned int a){ // 延时
unsigned int i;LED1=~LED1;
while ( --a != 0 )
for (i=0;i<=600;i++);
}
void Uart1Init(void) { //9600bps@11.0592MHz
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1; //开串口中断
}
void Uart1() interrupt 4{
uart_cache[First_Int] = SBUF; //将接收到的字符串存到缓存中
First_Int++; //缓存指针向后移动
if(First_Int > cache_max) //如果缓存满,将缓存指针指向缓存的首地址
First_Int = 0;
RI = 0; //清除RI位
}
void Timer0Init(void) { //20毫秒@11.0592MHz
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //
TMOD |= 0x01; //设置定时器模式,16位定时器
TL0 = 0x00; //设置定时器初值
TH0 = 0xB8; //设置定时器初值
TF0 = 0; //清TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA=1; //开总中断
}
void Timer0_ISR() interrupt 1{
static unsigned char Time_count=0; // 定时器计数器 static全局生命周期
TR0=0; //关定时器
TL0 = 0x00; //重设定时器初值
TH0 = 0xB8; //重设定时器初值
Time_count++;
if(Time_count>=50) {
Time_count = 0;
RUNING =~RUNING;
}
if(Timer_start) Times++; //如果收到允许定时,开始计时
if(Times > (50*delay)){ //如果Times 到达设定时间
Timer_start = 0;
Times = 0; // 通知程序 计时时间已到
}
TR0=1; //开定时器
}
void CLR_Buf1(void){
unsigned int k;
for(k=0;k<cache_max;k++) //将缓存内容清零
uart_cache[k] = 0x00;
First_Int = 0; //接收字符串的起始存储位置
}
unsigned char Find(unsigned char *a) { //查找字符串
if(search(uart_cache,a)!=NULL) return 1;
else return 0;
}
void Send_Command(unsigned char *b,unsigned char *a,unsigned char wait_time)
{
unsigned char i;
unsigned char *c;
c = b; //保存字符串地址到c
CLR_Buf1();
i = 0;
while(i == 0) {
if(Find(a)==NULL) { //查找需要应答的字符
if(Timer_start == 0){
b = c; //将字符串地址给b
for (b; *b!='\0';b++)
SendData(*b);
SendLR();
Times = 0;
delay = wait_time;
Timer_start = 1; // 开启定时器,
}
}
else {
i = 1;
Timer_start = 0;
}
}
CLR_Buf1();
}
void Set_Text_Mode(void) { //设置短信为TEXT文本模式
Send_Command("ATE0","OK",3); //取消回显
Send_Command("AT+CNMI=3,2,0,0,0","OK",3); //新短信直接输出
Send_Command("AT+CMGF=1","OK",3); //TEXT模式
Send_Command("AT+CPMS=\"SM\",\"SM\",\"SM\"","OK",3); //所有操作都在SIM卡中进行
}
void Wait_CREG(void) { //等待模块注册成功
unsigned char i;
unsigned char k;
i = 0;
CLR_Buf1();
while(i == 0) {
CLR_Buf1();
SendString("AT+CREG?"); //查询模块网络注册状态
SendLR();
DELAY_MS(1000);
for(k=0;k<cache_max;k++) {
if(uart_cache[k] == ':') {
if((uart_cache[k+4] == '1')||(uart_cache[k+4] == '5')){ //表明网络注册成功
i = 1;
break;
}
}
}
}
}
void Check_New_Message(void) { //检查是否有新信息,并执行信息内容指令
unsigned char temp=0;
unsigned char d[39]="";
unsigned char *s1=" View View View View";
unsigned char *s2=" hahahahahaha";
strcat(d,s1);
strcat(d,s2);
//若缓存字符串中含有"13429678754"就表示有新的短信
if(search(uart_cache,"13429678754")!=NULL) {
DELAY_MS(300); //等待数据全部接收完成
// computer_ctrol=!computer_ctrol;
// 判断到【当前状态】字符
if(search(uart_cache,status)!=NULL) { //读取【当前状态】并发送
// Send_Command("AT+CSMP=17,167,2,25","OK",3); //设置文本模式参数
// Send_Command("AT+CSCS=\"UCS2\"","OK",3); //设置字符集
// //手机号码13429678754 有回车
Send_Command("AT+CMGS=\"00310033003400320039003600370038003700350034\"",">",3);
Send_Command(d,">",3);
// Send_Command(computer_off,">",3);
SendData(0x1a);// 开始发送 返回OK
}
CLR_Buf1(); // 清空SBUF缓存
}
}
void main(void){
Timer0Init(); //初始化定时器0
Uart1Init(); //初始化串口9600
Send_Command("AT","OK",3);
Wait_CREG(); //查询等待模块注册成功
Set_Text_Mode(); //设置短信为TEXT模式
Send_Command("AT+CMGD=1,4","OK",3);//删除卡上所有短信
while(1) {
Check_New_Message();
}
}
转载于:https://blog.51cto.com/990487026/1710772