(五)STM32F103智能售货机main函数

一、操作系统

参考正点原子移植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);	
	}
	
}

(想学的看代码,不想学的照搬没用) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值