一、操作系统
参考正点原子移植ucosII的三个文件夹
二、主函数
main.h
#ifndef __MAIN_H
#define __MAIN_H
#include "stm32f10x.h"
void LED1_State(void);
void BEEP_alarm(void);
void BEEP1_State(void);
void GoodsNum_State(void);
void Cli_Open(void);
//自定义函数
void Lcd_Hardware_Init(void);//0
void Lcd_Open_Sta(int,int);//2
void Lcd_End(int,u32); //4
void Lcd_Not_Activited(void);
void Lcd_Buy_Sta(void);
void Door_State(void);
extern u32 Cli_Money;
#endif
main.c
#include "stm32f10x.h"
#include "main.h"
#include "delay.h"
#include "usart1.h"
#include "usart2.h"
#include "timer1.h"
#include "timer2.h"
#include "timer3.h"
#include "timer4.h"
#include "wifi.h"
#include "led.h"
#include "mqtt.h"
#include "key.h"
#include "iic.h"
#include "beep.h"
#include "includes.h"
#include "rc522.h"
#include "lcd.h"
#include "relay.h"
#include "HX711.h"
/UCOSII任务堆栈设置///
//START 任务
//设置任务优先级
#define START_TASK_PRIO 15 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 64
//创建任务堆栈空间
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数接口
void start_task(void *pdata);
//MQTT任务
//设置任务优先级
#define MQTT_TASK_PRIO 5
//设置任务堆栈大小
#define MQTT_STK_SIZE 128
//创建任务堆栈空间
OS_STK MQTT_TASK_STK[MQTT_STK_SIZE];
//任务函数接口
void mqtt(void *pdata);
//LCD1任务
//设置任务优先级
#define LCD1_TASK_PRIO 7
//设置任务堆栈大小
#define LCD1_STK_SIZE 128
//创建任务堆栈空间
OS_STK LCD1_TASK_STK[LCD1_STK_SIZE];
//任务函数接口
void Lcd_Main(void *pdata);
//LCD3任务
//设置任务优先级
#define LCD3_TASK_PRIO 4
//设置任务堆栈大小
#define LCD3_STK_SIZE 128
//创建任务堆栈空间
OS_STK LCD3_TASK_STK[LCD3_STK_SIZE];
//任务函数接口
void Lcd_Buy_Fresh(void *pdata);
//CLIENT任务
//设置任务优先级
#define CLI_TASK_PRIO 6
//设置任务堆栈大小
#define CLI_STK_SIZE 256
//创建任务堆栈空间
OS_STK CLI_TASK_STK[CLI_STK_SIZE];
//任务函数接口
void client_task(void *pdata);
//按键扫描任务
//设置任务优先级
#define KEY_TASK_PRIO 3
//设置任务堆栈大小
#define KEY_STK_SIZE 64
//任务堆栈
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数
void key_task(void *pdata);
//复位去皮任务
//设置任务优先级
#define PI_TASK_PRIO 8
//设置任务堆栈大小
#define PI_STK_SIZE 64
//任务堆栈
OS_STK PI_TASK_STK[PI_STK_SIZE];
//任务函数
void pi_task(void *pdata);
OS_EVENT * msg_key; //按键邮箱事件块指针
//
u32 Cli_Money;
//人工去皮,复位重力传感器
void pi_task(void *pdata){
u32 key=0;
u8 err;
while(1)
{
key=(u32)OSMboxPend(msg_key,10,&err);
switch(key)
{
case KEY0_PRES://控制DS1
LED0=0;
Get_Maopi_2(); //获取皮重
LED0=1;
break;
case KEY1_PRES://发送信号量
LED0=0;
Get_Maopi(); //获取皮重
LED0=1;
break;
case WKUP_PRES:
LED0=0;
Get_Maopi(); //获取皮重
Get_Maopi_2(); //获取皮重
LED0=1;
break;
}
delay_ms(10);
}
}
//卡无激活页面
void Lcd_Not_Activited()
{
LCD_Clear(WHITE);
LCD_ShowString(30,50,210,24,16,"Drag Vending machine!!");
LCD_ShowString(30,80,200,16,16,"NOT ACTIVITED!!");
LCD_ShowString(30,100,200,16,16,"Please change one!!");
delay_ms(2000);
}
//贩卖机初始化页面
void Lcd_Hardware_Init()
{
LCD_Clear(WHITE);
LCD_ShowString(30,50,210,24,16,"Drag Vending machine!!");
LCD_ShowString(30,80,200,16,16,"Hardware_Init!!");
LCD_ShowString(30,100,200,16,16,"Please Wait!!");
}
//LCD1主页
void Lcd_Main(void *pdata)
{
while(1){
LCD_Clear(WHITE);
LCD_ShowString(30,40,210,24,24,"Welcome! !");
LCD_ShowString(30,70,200,16,16,"No.01");
LCD_ShowString(30,90,200,16,16,"Drag Vending machine");
LCD_ShowString(30,110,200,16,16,"please swipe your card");
LCD_ShowString(30,130,200,12,12,"( RFID )");
delay_ms(2000);
}
}
//LCD2主页
void Lcd_Open_Sta(int Cli_ID,int money_is_enough)
{
LCD_Clear(WHITE);
LCD_ShowString(30,40,210,24,16,"ID :");
LCD_ShowNum(30,70,Cli_ID,2,12);//传递客户信息
if(money_is_enough){
LCD_ShowString(30,90,200,16,16,"Unlock success!");
delay_ms(2000);
}
else
{
LCD_ShowString(30,110,200,16,16,"balance not enough");
LCD_ShowString(30,130,200,12,12,"Unlock fail");
LCD_ShowString(30,150,200,12,12,"Please recharge!");
delay_ms(2000);
}
}
//LCD3购物车
void Lcd_Buy_Sta()
{
LCD_Clear(WHITE);
LCD_ShowString(30,40,210,24,24,"Shopping Cart");
LCD_ShowString(30,70,200,16,12,"Buy No.1 drag : psc");
LCD_ShowString(30,110,200,16,12,"Buy No.2 drag : psc");
LCD_ShowString(30,130,200,12,12,"enough money?:");
LCD_ShowString(30,150,200,12,12,"total: yuan");
delay_ms(2000);
}
//刷新购物车情况
//LCD3购物车
void Lcd_Buy_Fresh(void *pdata)
{
int Ori_Good1_Num; //药品1开门前数量
int Ori_Good2_Num; //药品2开门前数量
int Buy_Good1_Num;
int Buy_Good2_Num;
u32 cost=0;
while(1){
//初始化获取药品信息
Ori_Good1_Num=Goods1_State(); //药品1开门前数量
delay_ms(500);
Ori_Good2_Num=Goods2_State(); //药品2开门前数量
u1_printf("\r\nlcd显示初始药品1有:%d 个 初始药品2有:%d 个\r\n",Ori_Good1_Num,Ori_Good2_Num);
while(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1)){
//获取实际购物状态
Buy_Good1_Num=Ori_Good1_Num-Goods1_State();
delay_ms(500);
Buy_Good2_Num=Ori_Good2_Num-Goods2_State();
u1_printf("\r\n购买药品1有:%d 个 购买药品2有: %d 个\r\n",Buy_Good1_Num,Buy_Good2_Num);
cost=Buy_Good1_Num*2+Buy_Good2_Num*3; //药品1为20元/个 药品2为30元/个
//LCD 刷新购买药品数量
LCD_Fill(130,70,140,83,WHITE); //覆盖函数
LCD_ShowNum(30+100,70,Buy_Good1_Num,2,12); //刷新NUM1
LCD_Fill(130,110,140,123,WHITE); //覆盖函数
LCD_ShowNum(30+100,110,Buy_Good2_Num,2,12); //刷新NUM2
//LCD 刷新enough
if(cost<Cli_Money){
LCD_Fill(160,130,173,143,WHITE);//覆盖no函数
LCD_ShowString(30+90,130,200,12,12,"yes");
}else{
LCD_Fill(116,130,137,143,WHITE);//覆盖yes函数
LCD_ShowString(30+130,130,200,12,12,"no");
}
// LCD_ShowNum(30+35,150,total,2,12);
//LCD 刷新cost
LCD_Fill(80,150,93,163,WHITE); //覆盖函数
LCD_ShowNum(80,150,cost,3,12);
}
delay_ms(2000);
}
}
//LCD4主页
void Lcd_End(int Cli_ID,u32 balance)
{
LCD_Clear(WHITE);
LCD_ShowString(30,40,210,24,16,"welcome next time!");
LCD_ShowString(30,70,200,16,16,"ID :");
LCD_ShowNum(80,70,Cli_ID,2,12);
LCD_ShowString(30,90,200,16,16,"balance :");
POINT_COLOR=BLUE;
LCD_ShowNum(130,90,balance,3,16);
POINT_COLOR=RED;
delay_ms(3000);
}
int main(void)
{
delay_init(); //延时功能初始化
Usart1_Init(9600); //串口1功能初始化,波特率9600,PA9 PA10,ch340,向外传输内容
Usart2_Init(115200); //串口2功能初始化,波特率115200 ,PA2 PA3 esp8266模块与单片机连接
TIM4_Init(30,7200); //TIM4初始化,定时时间 300*7200*1000/72000000 = 30ms
LED_Init(); //LED初始化
LCD_Init(); //LCD初始化
RALAY_Init(); //继电器初始化
BEEP_Init();
InitioHX711();
Get_Maopi(); //获取皮重
Get_Maopi_2(); //获取皮重
KEY_Init(); //按键初始化
RC522_Init(); //初始化射频卡模块
WiFi_ResetIO_Init(); //PB2 初始化WiFi的复位IO
MQTT_Buff_Init(); //初始化接收,发送,命令数据的 缓冲区 以及各状态参数
AliIoT_Parameter_Init(); //初始化连接阿里云IoT平台MQTT服务器的参数
Lcd_Hardware_Init();
u1_printf("INit完毕\r\n");
TIM2_ENABLE_30S();
OSInit(); //初始化UCOSII
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
OSStart();
}
//开始任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
u1_printf("start_task\r\n");
pdata = pdata;
msg_key=OSMboxCreate((void*)0); //创建消息邮箱
OSStatInit(); //初始化统计任务.这里会延时1秒钟左右
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(mqtt,(void *)0,(OS_STK*)&MQTT_TASK_STK[MQTT_STK_SIZE-1],MQTT_TASK_PRIO);
OSTaskCreate(client_task,(void *)0,(OS_STK*)&CLI_TASK_STK[CLI_STK_SIZE-1],CLI_TASK_PRIO);
OSTaskCreate(Lcd_Main,(void *)0,(OS_STK*)&LCD1_TASK_STK[LCD1_STK_SIZE-1],LCD1_TASK_PRIO);
OSTaskCreate(Lcd_Buy_Fresh,(void *)0,(OS_STK*)&LCD3_TASK_STK[LCD3_STK_SIZE-1],LCD3_TASK_PRIO);
OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);
OSTaskCreate(pi_task,(void *)0,(OS_STK*)&PI_TASK_STK[PI_STK_SIZE-1],PI_TASK_PRIO);
OSTaskSuspend(LCD1_TASK_PRIO); //挂起Lcd_Main任务.
OSTaskSuspend(LCD3_TASK_PRIO); //挂起Lcd_Buy_Sta任务.
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
//按键扫描任务
void key_task(void *pdata)
{
u8 key;
u1_printf("KEY\r\n");
while(1)
{
key=KEY_Scan(0);
if(key)OSMboxPost(msg_key,(void*)key);//发送消息
delay_ms(1000);
}
}
//rc522任务
void client_task(void *pdata)
{
u1_printf("\r\nclient_task ok\r\n");
while(1)
{
u1_printf("进入cliopen函数");
Cli_Open();
u1_printf("退出cliopen函数");
delay_ms(2000);
}
}
void Cli_Open() //消费者消费
{
feedback=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1);
//LED换回门锁反馈信号
if(feedback==Bit_SET){ //门锁没开
CARD data;
char temp[256];
int Close_Enable=0; //判断是否够钱能关门
int n=0; //用于报警计时
int cost=0;
int Buy_Good1_Num=0;
int Buy_Good2_Num=0;
int Ori_Good1_Num=0; //药品1开门前数量
int Ori_Good2_Num=0; //药品2开门前数量
int money_is_enough=0; //0为不够钱 1为够钱
int Cli_ID=0; //0为未知
if(IC_Card_Read(&data)==MI_OK)
{
//停止上报药品数量数据
TIM_Cmd(TIM2,DISABLE);
//判断用户编号
if(data.phone[0]=='1') Cli_ID=1;
else if (data.phone[0]=='4') Cli_ID=4;
else if (data.phone[0]=='3') Cli_ID=3;
//判断卡是否已经激活
if(data.stat==66)
{
u1_printf("用户信息 : %s\r\n",data.phone);
u1_printf("消费前的余额 : %d \r\n",data.money);
//
if(data.money>0){
money_is_enough=1;
Cli_Money=data.money;
}
//余额足够才能消费
if(money_is_enough)
{
//电子锁打开
GPIO_SetBits(GPIOE,GPIO_Pin_0);
//delay_ms(1000);
//MQTT上报
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"DoorState\":1},\"version\":\"1.0.0\"}"); //构建开锁数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加数据,发布给服务器
//挂起主页任务
OSTaskSuspend(LCD1_TASK_PRIO);
delay_ms(200);
//LCD显示欢迎光临,开锁成功 //每显示新页面要先刷新
u1_printf("欢迎光临,开锁成功\r\n");
Lcd_Open_Sta(Cli_ID,money_is_enough);
//取消挂起购物车页面任务(显示购物车页面)
Lcd_Buy_Sta();
OSTaskResume(LCD3_TASK_PRIO); //唤醒主页三任务
delay_ms(200);
//复位继电器 避免关不了锁
GPIO_ResetBits(GPIOE,GPIO_Pin_0);
//传感器测量购物前情况
Ori_Good1_Num=Goods1_State();
delay_ms(500);
Ori_Good2_Num=Goods2_State();
u1_printf("\r\n初始药品1有:%d 个 初始药品2有: %d 个\r\n",Ori_Good1_Num,Ori_Good2_Num);
//等待选购商品
//不够钱不能关锁 循环直到关锁
while(!Close_Enable){
Buy_Good1_Num=Ori_Good1_Num-Goods1_State();
delay_ms(500);
Buy_Good2_Num=Ori_Good2_Num-Goods2_State();
cost=Buy_Good1_Num*2+Buy_Good2_Num*3; //药品1为20元/个 药品2为30元/个
if(data.money<cost){
Close_Enable=0;
//不准关锁
GPIO_SetBits(GPIOE,GPIO_Pin_0);
}else{
GPIO_ResetBits(GPIOE,GPIO_Pin_0);
feedback=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1);
if(feedback==Bit_SET){
u1_printf("退出购物车状态");
Close_Enable=1;
goto P1;
}
Close_Enable=0;
}
if(n>30){
BEEP=1;
}
n++;
delay_ms(1000);
}
P1: //关门后停止报警
BEEP=0;
//开启上报药品数量数据
TIM_Cmd(TIM2,ENABLE);
//MQTT上报
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"DoorState\":0},\"version\":\"1.0.0\"}"); //构建开锁数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加门锁数据,发布给服务器
memset(temp,0,sizeof(temp));
delay_ms(100);
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"Cli_ID\":%d},\"version\":\"1.0.0\"}",Cli_ID); //构建开锁数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加用户数据,发布给服务器
memset(temp,0,sizeof(temp));
delay_ms(100);
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"Buy_Good1_Num\":%2d,\"Buy_Good2_Num\":%2d},\"version\":\"1.0.0\"}",Buy_Good1_Num,Buy_Good2_Num); //构建购买药品数量数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加购买数据,发布给服务器
memset(temp,0,sizeof(temp));
//清屏、挂起购物车页面任务
OSTaskSuspend(LCD3_TASK_PRIO);
if(cost>0){ //重新写入到卡里
data.money-=cost;
cost=0;
RC522_PcdWrite(1, (u8*)&data); //写数据到第addr块,data入的数据值。;
u1_printf("消费后的余额:%d\r\n",data.money);
//LCD显示余额(四号页面)
Lcd_End(Cli_ID,data.money);
//2s后取消挂起主页任务
OSTaskResume(LCD1_TASK_PRIO); //唤醒主页1任务
}else{ //没有消费不用重写
u1_printf("没有消费\r\n");
//LCD显示余额(四号页面)
Lcd_End(Cli_ID,data.money);
//2s后取消挂起主页任务
OSTaskResume(LCD1_TASK_PRIO); //唤醒主页1任务
}
}
else
{
//LCD显示欢迎光临,余额不足,开锁失败
Lcd_Open_Sta(Cli_ID,money_is_enough);
u1_printf("余额不足,消费失败...\r\n");
}
}
//卡已经挂失
else if(data.stat==88)
{
u1_printf("此卡已挂失.请先解锁后再进行消费流程.\r\n");
//LCD
OSTaskSuspend(LCD1_TASK_PRIO);
Lcd_Not_Activited();
OSTaskResume(LCD1_TASK_PRIO);
}
//卡没有激活
else
{
u1_printf("此卡没有激活.请先激活后再进行消费流程.\r\n");
//LCD
OSTaskSuspend(LCD1_TASK_PRIO);
Lcd_Not_Activited();
//delay_ms(2000);
OSTaskResume(LCD1_TASK_PRIO);
}
//复位--释放选中的卡片
RC522_PcdReset();
}
}
}
//LED1判断开关1状态,并发布给服务器
void Door_State(void)
{
char temp[BUFF_UNIT]; //定义一个临时缓冲区
feedback=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1);
if(feedback==Bit_SET) sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"DoorState\":0},\"version\":\"1.0.0\"}"); //需要回复关闭状态给服务器
else sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"DoorState\":1},\"version\":\"1.0.0\"}"); //需要回复打开状态给服务器
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加数据,发布给服务器
}
//药柜编号上报函数
void SELL_ID_State(void)
{
char temp[BUFF_UNIT]; //定义一个临时缓冲区
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"SELL_ID\":1},\"version\":\"1.0.0\"}");
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加数据,发布给服务器
}
//药品数量上报函数
void GoodsNum_State()
{
char temp[256];
int Goods1_Num=0;
int Goods2_Num=0;
//传感器检测数据
Goods1_Num=Goods1_State();
delay_ms(500);
Goods2_Num=Goods2_State();
//传感器检测数据
Goods1_Num=Goods1_State();
delay_ms(500);
Goods2_Num=Goods2_State();
//传感器检测数据
Goods1_Num=Goods1_State();
delay_ms(500);
Goods2_Num=Goods2_State();
//传感器检测数据
Goods1_Num=Goods1_State();
delay_ms(500);
Goods2_Num=Goods2_State();
//MQTT上报
u1_printf("药品1有:%u psc 药品2有:%u psc\r\n",Goods1_Num,Goods2_Num);
sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"Goods1_Num\":%u,\"Goods2_Num\":%2u},\"version\":\"1.0.0\"}",Goods1_Num,Goods2_Num); //构建回复药品数量数据
MQTT_PublishQs0(P_TOPIC_NAME,temp,strlen(temp)); //添加数据,发布给服务器
}
//MQTT连接任务
void mqtt(void *pdata)
{
u1_printf("MQTT\r\n");
while(1) //主循环
{
if(Connect_flag==1){ //Connect_flag=1同服务器建立了连接,我们可以发布数据和接收推送了
//处理发送缓冲区数据
if(MQTT_TxDataOutPtr != MQTT_TxDataInPtr){ //if成立的话,说明发送缓冲区有数据了
//3种情况可进入if
//第1种:0x10 连接报文
//第2种:0x82 订阅报文,且ConnectPack_flag置位,表示连接报文成功
//第3种:SubcribePack_flag置位,说明连接和订阅均成功,其他报文可发
if((MQTT_TxDataOutPtr[2]==0x10)||((MQTT_TxDataOutPtr[2]==0x82)&&(ConnectPack_flag==1))||(SubcribePack_flag==1)){
u1_printf("发送数据:0x%x\r\n",MQTT_TxDataOutPtr[2]); //串口提示信息
MQTT_TxData(MQTT_TxDataOutPtr); //发送数据
MQTT_TxDataOutPtr += BUFF_UNIT; //指针下移
if(MQTT_TxDataOutPtr==MQTT_TxDataEndPtr) //如果指针到缓冲区尾部了
MQTT_TxDataOutPtr = MQTT_TxDataBuf[0]; //指针归位到缓冲区开头
}
}//处理发送缓冲区数据的else if分支结尾
//处理接收缓冲区数据
if(MQTT_RxDataOutPtr != MQTT_RxDataInPtr){ //if成立的话,说明接收缓冲区有数据了
u1_printf("接收到数据:");
//处理CONNACK报文
//if判断,如果第一个字节是0x20,表示收到的是CONNACK报文
//接着我们要判断第4个字节,看看CONNECT报文是否成功
if(MQTT_RxDataOutPtr[2]==0x20){
switch(MQTT_RxDataOutPtr[5]){
case 0x00 : u1_printf("CONNECT报文成功\r\n"); //串口输出信息
ConnectPack_flag = 1; //CONNECT报文成功,订阅报文可发
break; //跳出分支case 0x00
case 0x01 : u1_printf("连接已拒绝,不支持的协议版本,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x01
case 0x02 : u1_printf("连接已拒绝,不合格的客户端标识符,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x02
case 0x03 : u1_printf("连接已拒绝,服务端不可用,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x03
case 0x04 : u1_printf("连接已拒绝,无效的用户名或密码,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x04
case 0x05 : u1_printf("连接已拒绝,未授权,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case 0x05
default : u1_printf("连接已拒绝,未知状态,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支case default
}
}
//if判断,第一个字节是0x90,表示收到的是SUBACK报文
//接着我们要判断订阅回复,看看是不是成功
else if(MQTT_RxDataOutPtr[2]==0x90){
switch(MQTT_RxDataOutPtr[6]){
case 0x00 :
case 0x01 : u1_printf("订阅成功\r\n"); //串口输出信息
SubcribePack_flag = 1; //SubcribePack_flag置1,表示订阅报文成功,其他报文可发送
Ping_flag = 0; //Ping_flag清零
TIM3_ENABLE_30S(); //启动30s的PING定时器
//TIM2_ENABLE_30S(); //启动30s的上传 药品数据 数据的定时器
SELL_ID_State(); //上报药店ID
Door_State();
OSTaskResume(LCD1_TASK_PRIO); //订阅完毕显示主页面1
delay_ms(3000);
break; //跳出分支
default : u1_printf("订阅失败,准备重启\r\n"); //串口输出信息
Connect_flag = 0; //Connect_flag置零,重启连接
break; //跳出分支
}
}
//if判断,第一个字节是0xD0,表示收到的是PINGRESP报文
else if(MQTT_RxDataOutPtr[2]==0xD0){
u1_printf("PING报文回复\r\n"); //串口输出信息
if(Ping_flag==1){ //如果Ping_flag=1,表示第一次发送
Ping_flag = 0; //要清除Ping_flag标志
}else if(Ping_flag>1){ //如果Ping_flag>1,表示是多次发送了,而且是2s间隔的快速发送
Ping_flag = 0; //要清除Ping_flag标志
TIM3_ENABLE_30S(); //PING定时器重回30s的时间
}
}
//if判断,如果第一个字节是0x30,表示收到的是服务器发来的推送数据
//我们要提取控制命令
else if((MQTT_RxDataOutPtr[2]==0x30)){
u1_printf("服务器等级0推送\r\n"); //串口输出信息
MQTT_DealPushdata_Qs0(MQTT_RxDataOutPtr); //处理等级0推送数据
}
MQTT_RxDataOutPtr += BUFF_UNIT; //指针下移
if(MQTT_RxDataOutPtr==MQTT_RxDataEndPtr) //如果指针到缓冲区尾部了
MQTT_RxDataOutPtr = MQTT_RxDataBuf[0]; //指针归位到缓冲区开头
}//处理接收缓冲区数据的else if分支结尾
//处理命令缓冲区数据
if(MQTT_CMDOutPtr != MQTT_CMDInPtr){ //if成立的话,说明命令缓冲区有数据了
u1_printf("命令:%s\r\n",&MQTT_CMDOutPtr[2]); //串口输出信息
if(strstr((char *)MQTT_CMDOutPtr+2,"\"params\":{\"DoorState\":1}")){//如果搜索到"params":{"Door_Ser_Sta":1}说明服务器下发打开开关1
//管理员开锁
GPIO_SetBits(GPIOE,GPIO_Pin_0);
u1_printf("开锁");
delay_ms(2500);
Door_State(); //判断开关状态,并发布给服务器
delay_ms(2000);
GPIO_ResetBits(GPIOE,GPIO_Pin_0);//复位 避免关不了锁
while(feedback==Bit_RESET){
feedback=GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_1);
}
u1_printf("关锁");
Door_State();
}
MQTT_CMDOutPtr += BUFF_UNIT; //指针下移
if(MQTT_CMDOutPtr==MQTT_CMDEndPtr) //如果指针到缓冲区尾部了
MQTT_CMDOutPtr = MQTT_CMDBuf[0]; //指针归位到缓冲区开头
}//处理命令缓冲区数据的else if分支结尾
}//Connect_flag=1的if分支的结尾
//Connect_flag=0同服务器断开了连接,我们要重启连接服务器
else{
u1_printf("需要连接服务器\r\n"); //串口输出信息
TIM_Cmd(TIM4,DISABLE); //关闭TIM4
TIM_Cmd(TIM3,DISABLE); //关闭TIM3
WiFi_RxCounter=0; //WiFi接收数据量变量清零
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
if(WiFi_Connect_IoTServer()==0){ //如果WiFi连接云服务器函数返回0,表示正确,进入if
u1_printf("建立TCP连接成功\r\n"); //串口输出信息
Connect_flag = 1; //Connect_flag置1,表示连接成功
WiFi_RxCounter=0; //WiFi接收数据量变量清零
memset(WiFi_RX_BUF,0,WiFi_RXBUFF_SIZE); //清空WiFi接收缓冲区
MQTT_Buff_ReInit(); //重新初始化发送缓冲区
}
}
delay_ms(3000);
}
}
(想学的看代码,不想学的照搬没用)