發現一個兩年前寫的東西,可以自定義鬧鐘個數(為了穩妥我設置最多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.png (6.86 KB, 下載次數: 31)
下載附件
2020-6-13 22:37 上傳
所有資料51hei提供下載:
writebug代碼.zip
(131.24 KB, 下載次數: 8)
2020-6-13 16:29 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|