发现一个两年前写的东西,可以自定义闹钟个数(为了稳妥我设置最多6个),超时报警,1分钟无人按下取消闹钟会发送短信给用户。
有个问题就是GA6走AT指令,发完短信有程序概率GG,也懒得去修改了。
确定好用,之前开出工厂板,焊接上就能跑,需要自己取,本人不提供任何技术支持。
单片机源程序如下:
- #include "REG51.h"
- #include "oled.h"
- #include "bmp.h"
- #include "24c02.h"
- #include "ds1302.h"
- #include "string.h"
- #include "GA6_module_errors.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define Buf_Max 70 //串口1缓存长度
- #define STABLE_TIMES 20 //等待上电后稳定
- #define UART1_SendLR() UART1_SendData(0X0D)
- //DS1302引脚定义,可根据实际情况自行修改端口定义
- uint aa;
- unsigned char pp;
- bit close;
- bit dunxin_Flag = 0;
- bit led = 0;
- //初始时间定义
- uchar time_buf[8] = {0x20,0x10,0x09,0x14,0x23,0x59,0x50,0x02};//初始时间
- uchar readtime[14];//当前时间
- uchar set[16] = {0x02,0x00,0x00,0x05,0x00,0x05,0x01,0x08,0x01,0x07,0x00,0x00,0x00,0x08,0x03,0x00};//年月日的每一位
- uchar sec_buf=0; //秒缓存
- uchar sec_flag=0; //秒标志位
- //多组闹钟设置变量区
- uchar nao_change;
- uchar nao_number; //闹钟总个数
- uchar nao_this; //当前时那个闹钟
- uchar nao_temp_number[4]; //存放当前修改闹钟处
- uchar ten_delay[4];
- xdata uchar Uart1_Buf[Buf_Max];
- uchar First_Int = 0;
- static uchar *phone_num = "AT+CMGS=\"15142345200\""; //拨打电话,修改这里可以修改拨打的电话。
- uint count_20ms;
- int ret;
- //功能:延时1毫秒
- //入口参数:x
- //出口参数:无
- //说明:晶振为12M
- /***********************按键定义*************************************************/
- sbit key1=P2^0;
- sbit key2=P2^1;
- sbit key3=P2^2;
- sbit key4=P0^1;
- uchar status=0,sta=0;//按键功能选择定义(年0,月1,日2,时3,分4 )
- /////////////////////////////////////////////
- sbit key_stop = P0^2;
- ////////////////
- sbit BEEZ = P0^7;
- sbit LED_B = P2^3;
- sbit LED_G = P2^4;
- sbit LED_R = P2^5;
- void delay_ms1(uint ms); //延时ms个20ms ms*20ms
- void CLR_Buf(void); //清串口接收缓存
- uchar Find(uchar *a); //查找字符串
- void UART1_SendData(uchar dat); //串口1发送 1字节
- void UART1_SendString(char *s);//串口1发送 字符串
- void UART1_Send_Command(char *s);
- uchar UART1_Send_AT_Command(uchar *b,uchar *a,uchar wait_time,uint interval_time);//at命令发送
- uchar UART1_Send_AT_Command_END(uchar *b,uchar *a,uchar wait_time,uint interval_time);
- uchar Wait_CREG(uchar query_times);
- //
- void Timer0Init(void) //20毫秒@115200
- {
- TMOD &= 0xF0;
- TMOD |= 0x01; //
- TL0 = (65536-20000)%256; //
- TH0 = (65536-20000)/256; //
- TF0 = 0; //
- ET0 = 1; //
- TR0 = 1; //开始计时
- }
- void Uart1Init(void) //9600bps@11.05926MHz
- {
- PCON &= 0x7F; //
- SCON = 0x50; //
- TMOD &= 0x0F; //
- TMOD |= 0x20; //
- TL1 = 0xFD; //
- TH1 = 0xFD; //
- ET1 = 0; //
- TR1 = 1; //
- ES = 1; //
- }
- int check_status(void)
- {
- int ret;
-
- ret = UART1_Send_AT_Command("AT","OK",3,50);//测试通信是否成功
- if(ret == 0)
- {
- return COMMUNITE_ERROR;
- }
-
- ret = UART1_Send_AT_Command("AT+CPIN?","READY",2,50);//查询卡是否插上
- if(ret == 0)
- {
- return NO_SIM_CARD_ERROR;
- }
-
- ret = Wait_CREG(3);//查询卡是否注册到网络
- if(ret == 0)
- {
- return SIM_CARD_NO_REG_ERROR;
- }
- return 1;
- }
- /***************************************************************
- 注:当然你可以返回其他值,来确定到底是哪一步发送指令出现失败了。
- ****************************************************************/
- int send_text_message(char *content)
- {
- uchar ret;
- char end_char[2];
-
- end_char[0] = 0x1A;//结束字符
- end_char[1] = '\0';
-
- //设置存储位置
- ret = UART1_Send_AT_Command("AT+CPMS=\"SM\",\"ME\",\"SM\"","OK",3,100);
- if(ret == 0)
- {
- return AT_CPMS_ERROR;
- }
-
- ret = UART1_Send_AT_Command("AT+CMGF=1","OK",3,50);//配置为TEXT模式
- if(ret == 0)
- {
- return AT_CMGF_ERROR;
- }
-
-
- ret = UART1_Send_AT_Command("AT+CSCS=\"GSM\"","OK",3,50);//设置字符格式
- if(ret == 0)
- {
- return AT_CSCS_ERROR;
- }
-
- ret = UART1_Send_AT_Command(phone_num,">",3,50);//输入收信人的电话号码
- if(ret == 0)
- {
- return AT_CMGS_ERROR;
- }
-
- UART1_SendString(content); //此函数发送短信内容 不加回车换行
- ret = UART1_Send_AT_Command_END(end_char,"OK",1,250);//发送结束符,等待返回ok,等待5S发一次,因为短信成功发送的状态时间比较长
- if(ret == 0)
- {
- return END_CHAR_ERROR;
- }
-
- return 1;
- }
- ///////
- void delay(uint t)
- {
- uint b;
- for(;t;t--)
- for(b=0;b<121;b++);
- }
- void Delay_xms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<112;j++);
- }
- /******************************************************************************/
- /*****************************按键功能函数*************************************/
- void key_1() //选择变量函数
- {
-
- key1=1;
- if(key1==0)
- delay(10);
- {
- if(key1==0)
- {
- if(++status>12)
- {
- if(++sta>4)
- {
- sta = 0;
- status = 0;
- }
- } //1控制年千位的变化,2控制年百位的变化,3控制年十位的变化
- } //4控制年个位的变化,5控制月十位的变化,6月个位,
- while(key1==0);
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- void key_4()
- {
- key4= 1;
- if(key4==0)
- {
- delay(10);
- if(key4==0)
- {
- if(++nao_change>2)
- {
- nao_change = 0;
- }
- }
- }
- while(key4==0);
- }
- ////////////////////////////////////////////////////////////////////////////////
- /******************************************************************************/
- void key_2() //加函数
- {
-
- key2=1;
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- switch(status)
- {
- case 1:if(++set[0]>9)set[0]=0;break;
- case 2:if(++set[1]>9)set[1]=0;break;
- case 3:if(++set[2]>1)set[2]=0;break;
- case 4:if(++set[3]>9)set[3]=1;break;
- case 5:if(++set[4]>9)set[4]=0;break;
- case 6:if(++set[5]>9)set[5]=0;break;
- case 7:if(++set[6]>9)set[6]=0;break;
- case 8:if(++set[7]>9)set[7]=0;break;
- case 9:if(++set[8]>9)set[8]=0;break;
- case 10:if(++set[9]>9)set[9]=0;break;
- case 11:if(++set[10]>9)set[10]=0;break;
- case 12:if(++set[11]>9)set[11]=0;break;
- }
-
- switch(sta)
- {
- case 1:if(++set[12]>2)set[12]=0;break;
- case 2:if(++set[13]>9)set[13]=0;break;
- case 3:if(++set[14]>5)set[14]=0;break;
- case 4:if(++set[15]>9)set[15]=0;break;
- }
-
- switch(nao_change)
- {
- case 1:if(++nao_number>6)nao_number=6;write24c02(250,nao_number);break; //这里写修改闹钟总个数
- case 2:if(++nao_this>nao_number)nao_this=nao_number;write24c02(251,nao_this);break; //这里修改当前数值
- }
-
- }
- while(key2==0);
- }
- }
- /*****************************************************************************/
- void key_3()//减函数
- {
-
- key3=1;
- if(key3==0)
- {
- delay(10);
- if(key3==0)
- {
- switch(status)
- {
- case 1:if((set[0]--)<=0)set[0]=9;break;
- case 2:if((set[1]--)<=0)set[1]=9;break;
- case 3:if((set[2]--)<=0)set[2]=1;break;
- case 4:if((set[3]--)<1)set[3]=9;break;
- case 5:if((set[4]--)<=0)set[4]=9;break;
- case 6:if((set[5]--)<=0)set[5]=9;break;
- case 7:if((set[6]--)<=0)set[6]=9;break;
- case 8:if((set[7]--)<=0)set[7]=9;break;
- case 9:if((set[8]--)<=0)set[8]=9;break;
- case 10:if((set[9]--)<=0)set[9]=9;break;
- case 11:if((set[10]--)<=0)set[10]=9;break;
- case 12:if((set[11]--)<=0)set[11]=9;break;
- // case 13:if((set[12]--)<=0)set[12]=9;break;
- // case 14:if((set[13]--)<=0)set[13]=9;break;
- // case 15:if((set[14]--)<=0)set[14]=9;break;
- // case 16:if((set[15]--)<=0)set[15]=9;break;
- }
- switch(sta)
- {
- case 1:if((set[12]--)<=0)set[12]=2;break;
- case 2:if((set[13]--)<=0)set[13]=9;break;
- case 3:if((set[14]--)<=0)set[14]=5;break;
- case 4:if((set[15]--)<=0)set[15]=9;break;
- }
-
- switch(nao_change)
- {
- case 1:if((nao_number--)<=1)nao_number=1;write24c02(250,nao_number);break; //这里写修改闹钟总个数
- case 2:if((nao_this--)<=1)nao_this=1;
- if(nao_this>nao_number)nao_this=nao_number;
- write24c02(251,nao_this);break; //这里修改当前数值
- }
-
- }
- while(key3==0);
- }
- }
- /*****************************************************************************/
- void key_time() //按键设置时间的处理
- {
- if(status>0)
- {
- ds1302_write_time(time_buf,set);
- }
- }
- ///////////////////////////////闹钟/////////////////////
- void naozhong() //闹钟
- {
- if((readtime[8]==set[12])&&(readtime[9]==set[13])&&(readtime[10]==set[14])&&(readtime[11]==set[15])&&(readtime[12]==0)&&(readtime[13]==0))
- {
- led = 1;
- ten_delay[0] = set[12];
- ten_delay[1] = set[13];
- ten_delay[2] = set[14];
- ten_delay[3] = set[15]+1;
- if(nao_this>=nao_number)
- {
- nao_this=1;
- }
-
- nao_this++;
- write24c02(251,nao_this);
- }
- if((readtime[8]==ten_delay[0])&&(readtime[9]==ten_delay[1])&&(readtime[10]==ten_delay[2])&&(readtime[11]==ten_delay[3]))
- {
- //响应闹钟10分钟后,发送短信
- dunxin_Flag = 1;
- led = 0;
- }
- }
- void stop()
- {
-
- key_stop=1;
- if(led == 1)
- {
- if(key_stop==0)
- delay(10);
- {
- if(key_stop==0)
- {
- led =0;
- }
- while(key_stop==0);
- //记录此刻时间点 6 到 9
- write24c02(100,set[6]);
- write24c02(101,set[7]);
- write24c02(102,set[8]);
- write24c02(103,set[9]);
- }
- }
- }
- void Time_chack()
- {
- set[0] = readtime[2];
- set[1] = readtime[3];
- set[2] = readtime[4];
- set[3] = readtime[5];
- set[4] = readtime[6];
- set[5] = readtime[7];
- set[6] = readtime[8];
- set[7] = readtime[9];
- set[8] = readtime[10];
- set[9] = readtime[11];
- set[10] = readtime[12];
- set[11] = readtime[13];
- }
- void BEEZ_Waring()
- {
- if(led)
- {
- BEEZ = 0; //opens
- LED_B = 0;
- LED_G = 0;
- LED_R = 0;
- }
- else
- {
- BEEZ = 1;
- LED_B = 1;
- LED_G = 1;
- LED_R = 1;
- }
- }
- /////////////////////////////////////////////////////////
- int main(void)
- {
- uchar i;
-
- BEEZ = 1;
- LED_B = 1;
- LED_G = 1;
- LED_R = 1;
- //读取闹钟时间
- // write24c02(250,1);write24c02(251,1);//初始化闹钟个数
- //
- nao_number = read24c02(250);
- nao_this= read24c02(251);
- //读取结束
- Delay_xms(50);//等待系统稳定
- ds1302_init(); //DS1302初始化
- // Uart_init(0); //波特率初始化为2400
- Delay_xms(10);
- // ds1302_write_time(); //写入初始值
- OLED_Init(); //初始化OLED
- OLED_Clear();
-
- OLED_InitDIsply_DS1302(); //显示固定UI
- //up all right
- Uart1Init(); //串口初始化
- Timer0Init();//TIM0初始化
- EA = 1; //开启总中断
- for(i = 0;i < STABLE_TIMES;i++)//等待网络稳定
- {
- delay_ms1(50);
- }
- while(1)
- {
-
- set[12] = read24c02(nao_this*4-3); //1 5
- set[13] = read24c02(nao_this*4-2); //2 6
- set[14] = read24c02(nao_this*4-1); //3 7
- set[15] = read24c02(nao_this*4-0); //4 8
-
- ds1302_read_time(time_buf,readtime); //读取时间
- //set = readtime
- //start 0 to over 11
-
- Time_chack();
-
- OLED_Disply_DS1302(readtime,set);
- //显示吃药时间
- OLED_ShowNum(45,6,(read24c02(100)),1,16);//
- OLED_ShowNum(54,6,(read24c02(101)),1,16);
- OLED_ShowNum(72,6,(read24c02(102)),1,16);
- OLED_ShowNum(81,6,(read24c02(103)),1,16);
-
- OLED_ShowNum(0,6,nao_number,1,16);
- OLED_ShowNum(18,6,nao_this,1,16);
-
- Disply_Time_Mark(status,sta,nao_change);
- key_1();
- key_2();
- key_3();
- key_4();
- key_time();
- naozhong();
- stop();
-
- if(!((nao_temp_number[0] == set[12]) && (nao_temp_number[1] == set[13]) && (nao_temp_number[2] == set[14]) &&(nao_temp_number[3] == set[15])))
- {
- write24c02(nao_this*4-3,set[12]); //this 1 存放到 1 0 this 2 存放到 5 1
- write24c02(nao_this*4-2,set[13]); //this 1 存放到 2 0 this 2 存放到 6 1
- write24c02(nao_this*4-1,set[14]); //this 1 存放到 3 5 this 2 存放到 7 0
- write24c02(nao_this*4-0,set[15]); //this 1 存放到 4 5 this 2 存放到 8 0
- nao_temp_number[0] = set[12];
- nao_temp_number[1] = set[13];
- nao_temp_number[2] = set[14];
- nao_temp_number[3] = set[15];
- }
- BEEZ_Waring();
- if(dunxin_Flag)
- {
- dunxin_Flag = 0;
- if(ret == 1)
- {
- ret = send_text_message("waring!");//发送TEXT短信
- }
- }
- }
-
- }
- void Timer0_ISR() interrupt 1
- {
- TR0=0;//关定时器
- TL0 = (65536-20000)%256; //重设定时器初值
- TH0 = (65536-20000)/256; //
-
- if(count_20ms > 0) //20ms延时计数器
- {
- count_20ms--;
- }
-
- TR0=1;//开定时器
- }
- /********************* UART1中断函数************************/
- void UART1_ISR (void) interrupt 4
- {
- if (RI)
- {
- RI = 0; //清除RI位
- Uart1_Buf[First_Int] = SBUF; //将接收到的字符串存到缓存中
- First_Int++; //缓存指针向后移动
- if(First_Int >= Buf_Max) //如果缓存满,将缓存指针指向缓存的首地址
- {
- First_Int = 0;
- }
- }
- if (TI)
- {
- TI = 0; //清除TI位
- }
- }
- /*******************************************************************************
- * 函数名 : CLR_Buf
- * 描述 : 清除串口2缓存数据
- * 输入 :
- * 输出 :
- * 返回 :
- * 注意 :
- *******************************************************************************/
- void CLR_Buf(void)
- {
- uchar k;
- for(k=0;k<Buf_Max;k++) //将缓存内容清零
- {
- Uart1_Buf[k] = 0x00;
- }
- First_Int = 0; //接收字符串的起始存储位置
- }
- /*******************************************************************************
- * 函数名 : Find
- * 描述 : 判断缓存中是否含有指定的字符串
- * 输入 :
- * 输出 :
- * 返回 : unsigned char:1 找到指定字符,0 未找到指定字符
- * 注意 :
- *******************************************************************************/
- uchar Find(uchar *a)
- {
- ES = 0; //改进程序
- if(strstr(Uart1_Buf,a)!=NULL)
- {
- ES = 1;
- return 1;
- }
- else
- {
- ES = 1;
- return 0;
- }
-
- }
- /*******************************************************************************
- * 函数名 : Wait_CREG
- * 描述 : 等待模块注册成功
- * 输入 :
- * 输出 :
- * 返回 :
- * 注意 :
- *******************************************************************************/
- uchar Wait_CREG(uchar query_times)
- {
- uchar i;
- uchar k;
- uchar j;
- i = 0;
- CLR_Buf();
- while(i == 0)
- {
- UART1_Send_Command("AT+CREG?");
- delay_ms1(100);
-
- for(k=0;k<Buf_Max;k++)
- {
- if((Uart1_Buf[k] == '+')&&(Uart1_Buf[k+1] == 'C')&&(Uart1_Buf[k+2] == 'R')&&(Uart1_Buf[k+3] == 'E')&&(Uart1_Buf[k+4] == 'G')&&(Uart1_Buf[k+5] == ':'))
- {
-
- if((Uart1_Buf[k+7] == '1')&&((Uart1_Buf[k+9] == '1')||(Uart1_Buf[k+9] == '5')))
- {
- i = 1;
- return 1;
- }
-
- }
- }
- j++;
- if(j > query_times)
- {
- return 0;
- }
-
- }
- return 0;
- }
- /*----------------------------
- UART1 发送串口数据
- -----------------------------*/
- void UART1_SendData(uchar dat)
- {
- ES=0; //关串口中断
- SBUF=dat;
- while(TI!=1); //等待发送成功
- TI=0; //清除发送中断标志
- ES=1; //开串口中断
- }
- /*----------------------------
- UART1 发送字符串
- -----------------------------*/
- void UART1_SendString(char *s)
- {
- while(*s)//检测字符串结束符
- {
- UART1_SendData(*s++);//发送当前字符
- }
- }
- /**********************************
- 发送命令
- **********************************/
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
writebug代码.zip
(131.24 KB, 下载次数: 8)
|