思路:

寄件:验证数字密码锁:成功则随机开启锁 进行寄件 产生随机码 保存 给指定手机号发送取件码
取件:输入取件码取件

主界面:

/*
*@auth:火红色祥云
*@time:2020-01-27  18-48-27
*@E-mail:201926154@qq.com
*/char Init_Buffer[5]="0000";//用于清空盒子int main(void)
{   int i;delay_init();     //延时函数初始化   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Key_Config();Box_Init();OLED_Init();uart_init(115200);TIM3_Int_Init(4999,7199);//用于产生随机数的种子系数AT24CXX_Init();         //IIC初始化 usart3_init(115200);   //sim800cinitUART2();//服务器串口初始化/*清空取件码的空间*/for(i=0;i<5;i++){AT24CXX_Write(i*5,"0000",5);}/*初始化服务器,服务器自检*/OLED_ShowString(0,0,"WiFiServerCheck");if(initESP8266()!=0)OLED_ShowString(0,2,"Init OK!");else OLED_ShowString(0,2,"Init ERROR!");if(connectAP(SSID,PWD,defaltIP)!=0)OLED_ShowString(0,4,"Connect AP OK!");else OLED_ShowString(0,4,"Con AP ERROR!");if(CreatServer()!=0)OLED_ShowString(0,6,"Creat AP OK!");else OLED_ShowString(0,6,"Creat AP ERROR!");delay_ms(500);OLED_Clear();/*初始化服务器,服务器自检*/   while(1){       int num0=0,EmpBoxNum;ProServerDate();//等待手机端的验证码EmpBoxNum=EmptyBox();OLED_ShowString(0,0," SmartExpress ");OLED_ShowString(0,2,"EmptyBox:");OLED_ShowNum(80,2,EmpBoxNum,1,16);OLED_ShowString(0,4,"KEY13:Save");OLED_ShowString(0,6,"KEY15:Get");num0=KeyScan();if(num0){switch(num0){case 13:SaveExpress();break;case 15:GetExpress();break;default:break;}}}
}

第一部分:矩阵键盘

/**
** PF12-15,列,输出。 PF8-PB11,行,输入
**左侧从下至上依次8-15
**/
void Key_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);/********4行输出*********/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOF, &GPIO_InitStructure);/********4列输入*********/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOF, &GPIO_InitStructure);
}int KeyScan(void)
{uchar KeyVal;GPIO_Write(GPIOF,((GPIOF->ODR&0xf0ff)|0x0f00));     //不管其余12位0xf0ff,先让PF8到PF11全部输出高。if((GPIOF->IDR&0xf000)==0x0000)                                 //如果PF12到PF15全为零则没有按键按下return 0;else{  delay_ms(5);    //延时5ms去抖动if((GPIOF->IDR&0xf000)==0x0000)return 0;}GPIO_Write(GPIOF,((GPIOF->ODR&0xf0ff)|0x0100));  //仅将PF8置高    switch(GPIOF->IDR&0xf000)   //第一行,由低到高,同理,不赘述{case 0x1000: KeyVal=13; break;case 0x2000: KeyVal=14;  break;case 0x4000: KeyVal=15;  break;case 0x8000: KeyVal=16;  break;}while((GPIOF->IDR&0xf000)>0);     //等待按键释放GPIO_Write(GPIOF,((GPIOF->ODR&0xf0ff)|0x0200));   //仅将PF9置高switch(GPIOF->IDR & 0xf000)             {case 0x1000: KeyVal=9;    break;case 0x2000: KeyVal=10;  break;case 0x4000: KeyVal=11;  break;case 0x8000: KeyVal=12;  break;}while((GPIOF->IDR & 0xf000)>0);GPIO_Write(GPIOF,((GPIOF->ODR&0xf0ff)|0x0400));  //仅将PF10置高switch(GPIOF->IDR & 0xf000)                {case 0x1000: KeyVal=5;    break;case 0x2000: KeyVal=6;   break;case 0x4000: KeyVal=7;   break;case 0x8000: KeyVal=8;   break;}while((GPIOF->IDR & 0xf000)>0);GPIO_Write(GPIOF,((GPIOF->ODR&0xf0ff)|0x0800));  //仅将PF11置高switch(GPIOF->IDR&0xf000)              {case 0x1000: KeyVal=1;    break;case 0x2000: KeyVal=2;   break;case 0x4000: KeyVal=3;   break;case 0x8000: KeyVal=4;   break;}while((GPIOF->IDR&0xf000)>0);return KeyVal;
}

第二部分:ESP8266驱动部分(USART2)

/*.h*/
/*连接AP宏定义*/
#define SSID "qq"
#define PWD  "qwertyuiop789000"
#define defaltIP "192.168.137.111"/*发送接收缓冲区长度宏定义*/
#define TXBUFFER_LEN 50
#define RXBUFFER_LEN 30/*.c*/
u8 TXBuffer[TXBUFFER_LEN] = {0};  //网络通信数据发送缓冲
u8 RXBuffer[RXBUFFER_LEN] = {0};  //网络通信数据接收缓冲
char empty_buffer[5]="0000";//用于清空盒子,下次使用
/*** 功能:外设串口初始化* 参数:*       无*/
void initUART2(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure; /*配置USART2和GPIO时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);/*GPIO配置*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);/* UART2配置 */USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//定义NVIC初始化结构体NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;                         //指定配置的中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;               //设置子优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                          //使/失能中断NVIC_Init(&NVIC_InitStructure); USART_Init(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE);USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
}/*** 功能:指定某个UART发送一个字节* 参数:USARTx:使用的目标串口x为1-3*       byte:待发送字节* 返回值:None*/
static void sendByte(USART_TypeDef *USARTx, u16 byte)
{USART_ClearFlag(USARTx, USART_FLAG_TC);             //软件清除发送完成标志位USART_SendData(USARTx, byte);                       //发送一个字节while (!USART_GetFlagStatus(USARTx, USART_FLAG_TC));//等待发送完成USART_ClearFlag(USARTx, USART_FLAG_TC);             //软件清除发送完成标志位
}/*** 功能:指定某个串口发送字符串* 参数:USARTx:使用的目标串口x为1-3*       str:字符串指针* 返回值:None*/
void sendString(USART_TypeDef *USARTx, char *str)
{while (*str){sendByte(USARTx,*str++);}
}/*** 功能:串口2中断服务函数* 参数:None* 返回值:None*/
void USART2_IRQHandler(void)
{static u8 i = 0;if(USART_GetITStatus(USART2, USART_IT_RXNE)) //判断接收数据寄存器是否有数据{RXBuffer[i++] = USART_ReceiveData(USART2);if(i==RXBUFFER_LEN)                     //超出接收缓冲范围,可能的情形是ESP8266复位,为防止溢出必须设置索引                  {i = RXBUFFER_LEN-1;}}if(USART_GetITStatus(USART2, USART_IT_IDLE)){USART_ReceiveData(USART2);              //读一次UART可以清除空闲标志位i = 0;}
}/*** 功能:查找字符串中是否包含另一个字符串* 参数:*       dest:待查找目标字符串*       src:待查找内容*       retry_cn:查询超时时间* 返回值:查找结果,非0为查找成功,0为失败* 说明:*       当发出一个AT指令后,需要一段时间等待ESP8266回复,因此就需要等待一段时间,*       这个时间通常是几百ms(除了连接服务器和AP指令),本程序一般指令通常等待*       2S,耗时的连接AP和服务器的设置等待为8S,其实花不了那么多时间,但如果发生超时*       就一定可以判断是通信问题*/
u8 findStr(u8* dest,u8* src,u16 retry_cn)
{u16 retry = retry_cn;                   //超时时间u8 result_flag = 0;                     //查找结果while(strstr((char*)dest,(char*)src)==0 && --retry!=0)//等待串口接收完毕或超时退出{delay_ms(10);}if(retry==0)                            //如果超时则有问题,此时返回0{return 0;}result_flag = 1;                        //执行到这里说明一切正常, 表示查找成功if(result_flag){return 1;}else {return 0;}
}/*** 功能:初始化ESP8266* 参数:None* 返回值:初始化结果,非0为初始化成功,0为失败*/
u8 initESP8266(void)
{sendString(USART2,"+++");          //退出透传 delay_ms(500);sendString(USART2,"AT+RST\r\n");   //重启ESP8266 delay_ms(500);if(checkESP8266()==0)              //使用AT指令检查ESP8266是否存在{return 0;}memset(RXBuffer,0,RXBUFFER_LEN);   //清空接收缓冲sendString(USART2,"ATE0\r\n");     //关闭回显  if(findStr(RXBuffer,"OK",200)==0)  //设置不成功{return 0;      }return 1;                         //设置成功
}/*** 功能:恢复出厂设置* 参数:None* 返回值:None* 说明:此时ESP8266中的用户设置将全部丢失回复成出厂状态*/
void restoreESP8266(void)
{sendString(USART2,"+++");           //退出透传delay_ms(500);sendString(USART2,"AT+RESTORE\r\n");//恢复出厂 NVIC_SystemReset();                 //同时重启单片机
}/*** 功能:检查ESP8266是否正常* 参数:None* 返回值:ESP8266返回状态*        非0 ESP8266正常*        0 ESP8266有问题  */
u8 checkESP8266(void)
{memset(RXBuffer,0,RXBUFFER_LEN); //清空接收缓冲sendString(USART2,"AT\r\n");     //发送AT握手指令if(findStr(RXBuffer,"OK",200)!=0)//ESP8266正常{return 1;  }else                            //ESP8266不正常 {return 0;}
}/*** 功能:连接热点* 参数:*         ssid:热点名*         pwd:热点密码* 返回值:*         连接结果,非0连接成功,0连接失败* 说明: *         失败的原因有以下几种(UART通信和ESP8266正常情况下)*         1. WIFI名和密码不正确*         2. 路由器连接设备太多,未能给ESP8266分配IP*/
u8 connectAP(u8* ssid,u8* pwd,u8* defaltip)
{memset(RXBuffer,0,RXBUFFER_LEN);                       sendString(USART2,"AT+CWMODE?\r\n");                       //查询此时WIFI工作模式if(findStr(RXBuffer,"CWMODE:1",200)==0)                    //如果此时不是MODE1模式,即不是STATION模式{memset(RXBuffer,0,RXBUFFER_LEN);     sendString(USART2,"AT+CWMODE=1\r\n");              //设置为STATION模式if(findStr(RXBuffer,"OK",200)==0){return 0;}             }memset(TXBuffer,0,RXBUFFER_LEN);                            //清空发送缓冲memset(RXBuffer,0,RXBUFFER_LEN);                            //清空接收缓冲sprintf((char*)TXBuffer,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pwd);//连接目标APsendString(USART2,(char*)TXBuffer);if(findStr(RXBuffer,"OK",800)!=0)                           //连接成功且分配到IP{memset(TXBuffer,0,RXBUFFER_LEN);                            //清空发送缓冲memset(RXBuffer,0,RXBUFFER_LEN);                            //清空接收缓冲sprintf((char*)TXBuffer,"AT+CIPSTA=\"%s\"\r\n",defaltIP);//设置默认IPsendString(USART2,(char*)TXBuffer);if(findStr(RXBuffer,"OK",800)!=0) return 1;elsereturn 0;}return 0;
}/*** 功能:连接热点* 参数:*         ssid:热点名*         pwd:热点密码* 返回值:*         连接结果,非0连接成功,0连接失败* 说明: *         失败的原因有以下几种(UART通信和ESP8266正常情况下)*         1. WIFI名和密码不正确*         2. 路由器连接设备太多,未能给ESP8266分配IP*/
u8 CreatServer(void)
{memset(RXBuffer,0,RXBUFFER_LEN);                       sendString(USART2,"AT+CIPMUX=1\r\n");                  //设置建立一个TCP服务器if(findStr(RXBuffer,"OK",200)!=0)                //如果此时不是MODE1模式,即不是STATION模式{memset(RXBuffer,0,RXBUFFER_LEN);     sendString(USART2,"AT+CIPSERVER=1,8080\r\n");//开启TCP Server ,端口设置为8080if(findStr(RXBuffer,"OK",200)!=0)return 1;     elsereturn 0;}elsereturn 0;
}/*** 功能:处理从手机端接收的控制数据* 参数:24C02中的验证码* 返回值:None* 说明:*/
void ProServerDate()
{   int match,boxID;u8 codenum[5]={"9999"};u8 boxadd[2];for(match=0;match<5;match++){AT24CXX_Read(match*5,codenum,5);//读取取件码,此时取件码为字符串数字if((char*)strstr((char*)RXBuffer,(char*)codenum))//匹配成功{memset(RXBuffer,0,RXBUFFER_LEN);//清空接受缓存AT24CXX_Read(match*2+30,boxadd,2);//读取BoxID,此时ID为字符串数字boxID=atoi((char*)boxadd);           //把字符串数字转化为整型数字OLED_Clear();OLED_ShowString(0,0,"OpenBoxID:");OLED_ShowNum(0,2,boxID+1,3,16);OLED_ShowString(0,6,"TakeAwayPack");//打开对应门锁switch(boxID){case 0:Box0=1;//打开第1个快递箱delay_ms(1000);Box0=0;//拉低电平,放入完毕后手动上锁AT24CXX_Write(boxID*5,(u8*)empty_buffer,5);//清空已取走快递的取件码break;case 1:Box1=1;//打开第2个快递箱delay_ms(1000);Box1=0;//拉低电平,放入完毕后手动上锁AT24CXX_Write(boxID*5,(u8*)empty_buffer,5);//清空已取走快递的取件码break;case 2:AT24CXX_Write(boxID*5,(u8*)empty_buffer,5);//清空已取走快递的取件码break;case 3:AT24CXX_Write(boxID*5,(u8*)empty_buffer,5);//清空已取走快递的取件码break;case 4:AT24CXX_Write(boxID*5,(u8*)empty_buffer,5);//清空已取走快递的取件码break;default:break;}delay_ms(500);OLED_Clear();}}}

第三部分:Random随机数产生部分(定时器用来产生随机数的种子)

#include "random.h"
#include "usart.h"
#include "stdlib.h"int times=0;
void TIM3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能//定时器TIM3初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值   TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器TIM_Cmd(TIM3, ENABLE);  //使能TIMx
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否{times+=50;TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 if(times==10000)times=0;}
}  int GreatCode(void)
{int randcode;//产生的随机数srand(times);//随机数的种子系数randcode=rand()%9000+1000;    //生成1000-9999范围的随机数rand()%(b-a+1)+a,范围:(a,b)return randcode;
}

第四部分:SIM8000C发送短信驱动部分(USART3)

/*USART3驱动*/
/*.h*/
#define USART3_MAX_RECV_LEN     600                 //最大接收缓存字节数
#define USART3_MAX_SEND_LEN     600                 //最大发送缓存字节数
#define USART3_RX_EN            1                   //0,不接收;1,接收.extern u8  USART3_RX_BUF[USART3_MAX_RECV_LEN];         //接收缓冲,最大USART3_MAX_RECV_LEN字节
extern u8  USART3_TX_BUF[USART3_MAX_SEND_LEN];      //发送缓冲,最大USART3_MAX_SEND_LEN字节
extern vu16 USART3_RX_STA;                          //接收数据状态void usart3_init(u32 bound);                //串口2初始化
void u3_printf(char* fmt,...);/*.c*/
//串口接收缓存区
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];              //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8  USART3_TX_BUF[USART3_MAX_SEND_LEN];             //发送缓冲,最大USART3_MAX_SEND_LEN字节//蓝牙扫描下:   timer=1S
//非蓝牙扫描下: timer=10ms
//通过判断接收连续2个字符之间的时间差不大于timer来决定是不是一次连续的数据.
//如果2个字符接收间隔超过timer,则认为不是1次连续数据.也就是超过timer没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART3_RX_STA=0;      void USART3_IRQHandler(void)
{u8 res;          if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据{     res =USART_ReceiveData(USART3);        if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据{ if(USART3_RX_STA<USART3_MAX_RECV_LEN)    //还可以接收数据{TIM_SetCounter(TIM7,0);             //计数器清空                       if(USART3_RX_STA==0)              //使能定时器7的中断 {TIM_Cmd(TIM7,ENABLE);           //使能定时器7}USART3_RX_BUF[USART3_RX_STA++]=res;    //记录接收到的值    }else {USART3_RX_STA|=1<<15;                //强制标记接收完成} }}
}   //初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void usart3_init(u32 bound)
{  NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                         //GPIOB时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);                          //串口3时钟使能USART_DeInit(USART3);  //复位串口3//USART3_TX   PB10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                                     //PB10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                   //复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //初始化PB10//USART3_RX    PB11GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                          //浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);                                         //初始化PB11USART_InitStructure.USART_BaudRate = bound;                                    //波特率一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;                    //字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;                         //一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;                            //无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式USART_Init(USART3, &USART_InitStructure);       //初始化串口3USART_Cmd(USART3, ENABLE);                      //使能串口 //使能接收中断USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);  //开启中断   //设置中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器TIM7_Int_Init(99,7199);       //10ms中断USART3_RX_STA=0;           //清零TIM_Cmd(TIM7,DISABLE);      //关闭定时器7}//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{  u16 i,j; va_list ap; va_start(ap,fmt);vsprintf((char*)USART3_TX_BUF,fmt,ap);va_end(ap);i=strlen((const char*)USART3_TX_BUF);        //此次发送数据的长度for(j=0;j<i;j++)                           //循环发送数据{while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   USART_SendData(USART3,USART3_TX_BUF[j]); }
}/*sim800c驱动*/
u8 flag=0;//SIM800C发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
//其他,期待应答结果的位置(str的位置)
u8* sim800c_check_cmd(u8 *str)
{char *strx=0;if(USART3_RX_STA&0X8000)     //接收到一次数据了{ USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符strx=strstr((const char*)USART3_RX_BUF,(const char*)str);} return (u8*)strx;
}
//SIM800C发送命令
//cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
u8 sim800c_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{u8 res=0; USART3_RX_STA=0;if((u32)cmd<=0XFF){while((USART3->SR&0X40)==0);//等待上一次数据发送完成  USART3->DR=(u32)cmd;}else u3_printf("%s\r\n",cmd);//发送命令if(ack&&waittime)     //需要等待应答{while(--waittime)  //等待倒计时{ delay_ms(10);if(USART3_RX_STA&0X8000)//接收到期待的应答结果{if(sim800c_check_cmd(ack))break;//得到有效数据 USART3_RX_STA=0;} }if(waittime==0)res=1; }return res;
}
//接收SIM800C返回数据(蓝牙测试模式下使用)
//request:期待接收命令字符串
//waittimg:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
//       1,发送失败
u8 sim800c_wait_request(u8 *request ,u16 waittime)
{u8 res = 1;if(request && waittime){while(--waittime){   if(USART3_RX_STA &0x8000)//接收到期待的应答结果{if(sim800c_check_cmd(request)) break;//得到有效数据USART3_RX_STA=0;}}if(waittime==0)res=0;}return res;
}void sim_send_sms(int code)
{u8 pn[11];u8 pnstr[11]="";u8 key=0,pnum,pnlen=0;u8 cmdstr[30]="";u8 codestr[5]="";OLED_Clear();OLED_ShowString(0,0,"InputPhoneNum:");while(1){key=KeyScan();if(key==16){pnlen=0;break;}if(key){switch(key){case 1:pnum=1;break;case 2:pnum=2;break;case 3:pnum=3;break;case 5:pnum=4;break;case 6:pnum=5;break;case 7:pnum=6;break;case 9:pnum=7;break;case 10:pnum=8;break;case 11:pnum=9;break;case 14:pnum=0;break;default:flag=1;break;}if(flag==0){pn[pnlen]=pnum;OLED_ShowNum(pnlen*8,2,pnum,1,16);pnlen++;flag=1;}if(pnlen==11){sprintf((char*)pnstr,"%d%d%d%d%d%d%d%d%d%d%d",pn[0],pn[1],pn[2],pn[3],pn[4],pn[5],pn[6],pn[7],pn[8],pn[9],pn[10]);pnlen=0;break;}}else {delay_ms(10);      flag=0;//放手时,归零以便下次重新计数}}OLED_Clear();if(sim800c_send_cmd("AT","OK",200)==0)//测试{OLED_ShowString(0,0,"Init 1th Step OK");}if(sim800c_send_cmd("AT+CMGF=1","OK",200)==0)//设置文本模式{OLED_ShowString(0,2,"Init 2th Step OK");}if(sim800c_send_cmd("AT+CSCS=\"GSM\"","OK",200)==0)//设置GSM模式{OLED_ShowString(0,4,"Init 3th Step OK");}sprintf((char*)cmdstr,"AT+CMGS=\"%s\"",pnstr);if(sim800c_send_cmd(cmdstr,">",200)==0)                   //发送短信命令+电话号码{          sprintf((char*)codestr,"Your Code is:%d",code);u3_printf("%s",codestr);                                //发送短信内容到GSM模块 if(sim800c_send_cmd((u8*)0X1A,"+CMGS:",1000)==0)//发送结束符,等待发送完成(最长等待10秒钟,因为短信长了的话,等待时间会长一些){OLED_ShowString(0,6,"Send Successful!");}else{OLED_ShowString(0,6,"Send Failed!");}USART3_RX_STA=0;}delay_ms(1000);
}/*定时器驱动(蓝牙用的)*/
extern vu16 USART3_RX_STA;//配置TIM7预装载周期值
void TIM7_SetARR(u16 period)
{TIM_SetCounter(TIM7,0);//计数器清空TIM7->ARR&=0x00;//先清预装载周期值为0TIM7->ARR|= period;//更新预装载周期值}//定时器7中断服务程序
void TIM7_IRQHandler(void)
{   if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)//是更新中断{                TIM_ClearITPendingBit(TIM7, TIM_IT_Update  );  //清除TIM7更新中断标志    USART3_RX_STA|=1<<15;    //标记接收完成TIM_Cmd(TIM7, DISABLE);  //关闭TIM7 }
}//通用定时器7中断初始化
//这里时钟选择为APB1的2倍,而APB1为42M
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//通用定时器中断初始化
//这里始终选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
void TIM7_Int_Init(u16 arr,u16 psc)
{   NVIC_InitTypeDef NVIC_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);//TIM7时钟使能    //定时器TIM7初始化TIM_TimeBaseStructure.TIM_Period = arr;                     //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc;                   //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);             //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE );                   //使能指定的TIM7中断,允许更新中断TIM_Cmd(TIM7,ENABLE);//开启定时器7NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;       //子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器}

丰巢取快递系统(二)相关推荐

  1. 丰巢取快递系统(一)

    丰巢系统设计 apk部分 安卓开发版本AndroidStudio3.5.3 /*.xml 布局*/ <?xml version="1.0" encoding="ut ...

  2. 计算机毕业设计Java“小蜜蜂”校园代取快递系统(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Java"小蜜蜂"校园代取快递系统(源码+系统+mysql数据库+lw文档) 计算机毕业设计Java"小蜜蜂"校园代取快递系统(源码+系统+mys ...

  3. 基于java“小蜜蜂”校园代取快递系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署

    基于java"小蜜蜂"校园代取快递系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署 基于java"小蜜蜂"校园代取快递系统计算机毕业设计源码+ ...

  4. [附源码]Python计算机毕业设计Django校园代取快递系统

    项目运行 环境配置: Pychram社区版+ python3.7.7 + Mysql5.7 + HBuilderX+list pip+Navicat11+Django+nodejs. 项目技术: dj ...

  5. Springboot毕设项目校园代取快递系统03w4xjava+VUE+Mybatis+Maven+Mysql+sprnig)

    Springboot毕设项目校园代取快递系统03w4xjava+VUE+Mybatis+Maven+Mysql+sprnig) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysq ...

  6. [附源码]计算机毕业设计springboot校园代取快递系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  7. [附源码]计算机毕业设计校园代取快递系统Springboot程序

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  8. 计算机毕业设计Node.js+Vue校园代取快递系统(程序+源码+LW+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue ...

  9. java毕业设计“小蜜蜂”校园代取快递系统mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计"小蜜蜂"校园代取快递系统mybatis+源码+调试部署+系统+数据库+lw java毕业设计"小蜜蜂"校园代取快递系统mybatis+源码+调 ...

最新文章

  1. 动视暴雪员工大罢工:因CEO被曝多次包庇高管性侵下属、本人曾性骚扰助理
  2. 输入几个数字,用逗号隔开系列例题
  3. JavaScript代码规范
  4. 第五人格pcmac_第五人格:未上线,勘探员已经让庄园内的CP乱了分寸,祭司最绝...
  5. java 向上转型_java向上转型和向下转型
  6. R6饮料AK赛(NOIP模拟赛)/省选专练HDU 5713 K个联通块
  7. opencv+python 自动绿帽机
  8. [翻译 EF Core in Action 2.3] 理解EF Core数据库查询
  9. mysql 查看表属性约束_mysql表属性、索引、约束
  10. 他刷题5个月,直通Google,薪资Triple,总结出这套刷题笔记,今天首次公开!
  11. JS获取当前页面的URL参数
  12. ISP芯片架构及算法初理解
  13. 应用排行榜第一名脸萌仅仅是刹那的烟火
  14. 基于Mono.Cecil的静态注入
  15. 【转载】快速入门(完整):Python实例100个(基于最新Python3.7版本)
  16. windows下VS中各种C++库的集成
  17. 这个能力很重要,但大多数人没有
  18. 编写电话号码查询系统
  19. 美云智数营销云荣获“2021年中国轻工业数字化杰出解决方案”
  20. 如何完成述职报告或年终总结PPT

热门文章

  1. 破案了!不会讲笑话不会作诗的chatGPT!
  2. 键盘录入(身高和体重)
  3. McAfee解读风险管理之道 企业安全面临新挑战
  4. 忘了账号——如何查看本地mysql账号
  5. 【无限互联】iOS开发视频教程— 2.8 iPhone开发之swtch语句
  6. “≡”3个横杠的等号的意思
  7. 一首关于远方和理想的小诗
  8. Building MFC application with /MD[d] (CRT dll version)requires MFC shared dll version~~~~
  9. 微信开发者工具下载及调试
  10. [战略]Fans未来战略--第3篇--以文会友