首页 > 其他分享 >买菜车

买菜车

时间:2022-10-01 21:45:16浏览次数:39  
标签:void adc 买菜 Beep Flag Mode ADC

main.c

点击查看代码

 /*! ----------------------------------------------------------------------------
 * PDOA跟随小车控制板程序
 * @author 广州联网科技有限公司
 */
 
#include <string.h>
#include <stdio.h>
#include "main.h"
#include "delay.h"
#include "Commu.h"
#include "motion.h"
#include "stmflash.h"

#include <usart2.h>
#include <led.h>
#include <stm32f10x.h>

/**************************************/ 
/*               变量                 */
/**************************************/ 
uint8_t  LED2_En = 0;       //LED2使能标志
uint8_t  LED3_EN = 0;       //LED3使能标志
uint8_t  ADC_Beep_En = 0;   //蜂鸣器使能标志 ADC用
uint8_t  COUPLE_Beep_En = 0; //蜂鸣器使能标志 Couple用
uint32_t LED_FLAG=0;     		//系统指示灯记录标志位

uint8_t  Flash_App_Mode;    //系统工作模式

u8 led_flag=1;

typedef enum
{
	system_findcp_init = 0,   //初始配对标签列表(K列表)
	system_findcp_ing,        //监听标签
	system_findcp_fin,        //搜索完成
	system_couple_working     //正常工作
}system_flag_t;            //Couple模式下系统的工作状态指示

uint8_t  system_flag = system_couple_working;

uint8_t  Mode_Single_Flag = 0;  //Single模式工作标志位
uint8_t  Mode_Couple_Flag = 0;  //Couple模式工作标志位

char* Flash_Tag16_ID = "4096";  //标签短ID 固定4096
uint16_t Flash_Tag_Fastfreq = 1;  //标签运动发包频率留空 目前值无意义
uint16_t Flash_Tag_Slowfreq = 100;  //标签静止发包频率留空 目前值无意义
uint16_t Flash_Tag_Mode     = 0;  //标签工作模式留空 目前值无意义
uint8_t OLED_Flag = 0;          //OLED显示
uint32_t Beep_Flag = 0;

uint8_t comm_move = Motion_Stop;  //指示运动


#define ADC_Timeout 50000      //ADC测量电量周期时间
#define ADC_FULL_POWER 12.6    //ADC测量电量最大电压 ADC测量电压为电池电压
#define ADC_LOW_POWER  10.2    //ADC测量电量最小电压 ADC测量电压为电池电压

/**************************************/ 
/*               函数                 */
/**************************************/ 
static void Mode_Single_App(void);  //单一工作模式
static void Mode_Couple_App(void);  //配对工作模式
static void Move_Test(void);        //运动测试
static void Oled_InitShow(void);    //OLED屏幕显示
static void Adc_Event(void);        //ADC测量电压
static void Key_Event(void);        //按键扫描

/**************************************/ 
/*             代码开始               */
/**************************************/ 

/**
  * @brief  按键扫描
  * @param  None
  * @retval None
  */
void Key_Event()
{
	if(Read_KEY1 == 0)
	{
		if(time_flag_Key > 30000)
		{
			LED2_En = 1;
			system_flag = system_findcp_init;  
			time_flag_Key = 0;
		}
	}
	else
		time_flag_Key = 0;
}

/**
  * @brief  运动测试 
            会执行直行 左转 右转 用于判断线是否接对
  * @param  None
  * @retval None
  */
void Move_Test(void)
{
	Motor_Speed_Change(350);
	Motor_Forward();
	delay_ms(500);
	Motor_Front_TurnLeft();
	delay_ms(500);
	Motor_Front_TurnRight();
	delay_ms(500);
	Motor_Stop();
}

/**
  * @brief  ADC测量
            测量电池的ADC电压 如果使用USB供电 将显示USB
  * @param  None
  * @retval None
  */
void Adc_Event(void)
{
	double adc_value = 0;
	char adc[10] = {'0'};
	adc_value = Get_Adc_Average(0,5);
	adc_value = adc_value * 3.3 / 4096 * 4 ;
	
	if(adc_value > ADC_FULL_POWER)
		adc_value = ADC_FULL_POWER;
	
	if(adc_value < 1) //usb供电 此时由5V供电 电机无法转动
	{
		sprintf(adc,"%s","USB");
	}
	else  //电池供电 显示电压百分比
	{
		adc_value = (adc_value - ADC_LOW_POWER) / (ADC_FULL_POWER - ADC_LOW_POWER) * 100;
	  sprintf(adc,"%d",(uint16_t)adc_value);
	  strcat(adc,"%");
		if(adc_value < 30) //电量小于30		
			ADC_Beep_En = 1;		
		else
			ADC_Beep_En = 0;
	}	
	OLED_Clear();
	Oled_InitShow();
	OLED_ShowString(50,38,adc,12,1);
	OLED_Refresh();
	time_flag_Adc = 0;
}

/**
  * @brief  OLED屏幕信息显示
  * @param  None
  * @retval None
  */
void Oled_InitShow(void)
{
	char temp[20] = {'0'};
	char show_num;
	char point = '.';
	char Mode[30] = "Mode:";
	char Battery[9] = "Battery:";
	strcpy(temp,APP_NAME);
	sprintf(&show_num,"%d",VERSION/10);
	strcat(temp,&show_num);
	strcat(temp,&point);
	sprintf(&show_num,"%d",VERSION%10);
	strcat(temp,&show_num);
	OLED_ShowString(0,0,temp,12,1);
	OLED_ShowString(0,12,APP_AUTHOR,12,1);
	if(Flash_App_Mode == MODE_SINGLE)
		strcat(Mode,"Single");
	if(Flash_App_Mode == MODE_COUPLE)
		strcat(Mode,"Couple");
	OLED_ShowString(0,24,Mode,12,1);
    OLED_ShowString(0,38,Battery,12,1);
	OLED_Refresh();
}

/**
  * @brief  Single模式下工作流程
            等待基站上报获取到新标签信息,添加该标签并跟随该标签
            会跟随该基站第一个响应到的标签
            要求基站的K列表中不存在要跟随的标签
  * @param  None
  * @retval None
  */
void Mode_Single_App()
{
	
	//Step0 等待获取基站上报要跟随的标签ID
	if(Mode_Single_Flag == 0)
	{
		if(Usart_event_flag & (1 << JType_NewTag)) //接收到新标签ID
		{
			Usart_event_flag &= (0 << JType_NewTag);
			Mode_Single_Flag = 1;
		}
	}
	
	//Step1 指示基站添加该标签的信息
	if(Mode_Single_Flag == 1)
	{
		Command_Result comm;	

		comm = Commu_Addtag(JNewtag.TagID,Flash_Tag16_ID,Flash_Tag_Fastfreq,Flash_Tag_Slowfreq,Flash_Tag_Mode);
		if(comm == Command_Good)
		{
			Mode_Single_Flag = 2;
//		  time3_usart1 = 0;
		}
	}
	
	//Step2 监听是否接收到正确的标签信息
	if(Mode_Single_Flag == 2)
	{
			if(Usart_event_flag & (1 << JType_TagAdded)) //接收到正确返回信息
		  {
		  	Usart_event_flag &= (0 << JType_TagAdded);
				LED2_En = 0;         //代表匹配成功
				Beep_On;
				delay_ms(200);
				Beep_Off;
				Mode_Single_Flag = 3;
		  }

	}
	
	//Step3 监听TWR信息 并根据其值进行解算和控制电机
	if(Mode_Single_Flag == 3)
	{ 

		if(Usart_event_flag & (1 << JType_TWR)) //接收到新标签ID
		{		
			Usart_event_flag &= (0 << JType_TWR);			
			
			//电机控制
			LED3_TOGGLE;
//			printf("raw:%d %d %d %d\r\n",JTwrtag.X,JTwrtag.Y,JTwrtag.Dis,JTwrtag.P);				
			comm_move = Motion_Control(JTwrtag.X,JTwrtag.Y,JTwrtag.Dis,JTwrtag.P);

			time_flag = 0;
	 }

	 if(comm_move != Motion_Stop)
	   comm_move = Motion_IR_Control(comm_move);

	 if(time_flag > 5000)  //如果500ms没有收到信息 认为标签已经断电
	 {
		 Motion_Init();
		 comm_move = Motion_Stop;
	 }
		 
	 
	 Motion_Act(comm_move);
	 
	}
}

/**
  * @brief  Couple模式下工作流程
            分为搜索状态和跟随状态
            如果长按Key1按键3秒以上 进入搜索标签状态 等待新标签信号监听然后配对
            只支持一对一配对
  * @param  None
  * @retval None
  */
void Mode_Couple_App()
{
	/*
	  配对工作模式
	  该模式下 控制板会记录基站要配对的标签ID
	  工作方式:获取标签后让基站保存配置到Flash 下次不用再次添加
	*/
  uint8_t i;
	Command_Result comm;
	switch(system_flag)
	{
		case system_findcp_init:  //读取此时K列表并删除所有标签
		{
			if(Mode_Couple_Flag == 0)
			{
				comm_move = Motion_Stop;
        Motion_Act(comm_move);  //防止车辆在动  
				Mode_Couple_Flag = 1;
			}
			
			//获取K列表
			if(Mode_Couple_Flag == 1)
			{
				comm = Commu_GetKList();
				if(comm == Command_Good)
					Mode_Couple_Flag = 2;
			}
			
			//是否获取成功
			if(Mode_Couple_Flag == 2)
			{
				if(Usart_event_flag & (1 << JType_KList))
				{
					Usart_event_flag &= (0 << JType_KList);   //获取好KList信息
					comm = Command_Error;
					if(KList_num != 0)
            Mode_Couple_Flag = 3;
					else
						Mode_Couple_Flag = 14;
				}
			}
			
			//删除K列表里面所有标签
			if(Mode_Couple_Flag > 2 && Mode_Couple_Flag < 3 + KList_num)
			{
				for(i=Mode_Couple_Flag;i<KList_num + 3;i++)  //删除K列表的标签
			  {
				  if(Mode_Couple_Flag == i)
				  {				  
						if(comm == Command_Error)
						{
							delay_ms(50);  //少量延时配合基站板
							comm = Commu_Deltag(KList[i-3].Addr64);
						}
						else
						{
							if(Usart_event_flag & (1 << JType_TagDeleted))
							{
								Usart_event_flag &= (0 << JType_TagDeleted);
								if(Mode_Couple_Flag == KList_num + 3 - 1)
								  Mode_Couple_Flag = 14;
							  else
								  Mode_Couple_Flag++;
								comm = Command_Error;
							}
							
						}					    
				  }
			  }
			}
			
			//删除成功 保存当前配置
			if(Mode_Couple_Flag == 14)
			{
				delay_ms(100);
				comm = Commu_Save();
				if(comm == Command_Good)
				{
					system_flag = system_findcp_ing;
					Mode_Couple_Flag = 20;
					COUPLE_Beep_En = 1;  //使能蜂鸣器				
				}
			}
			
			break;
		}
		
		case system_findcp_ing:  //等待搜索标签
		{
			if(Mode_Couple_Flag == 20)
			{
				if(Usart_event_flag & (1 << JType_NewTag)) //接收到新标签ID
		    {
			    Usart_event_flag &= (0 << JType_NewTag);
			    Mode_Couple_Flag = 21;
		    }
			}
			
			if(Mode_Couple_Flag == 21)
			{
				comm = Commu_Addtag(JNewtag.TagID,Flash_Tag16_ID,Flash_Tag_Fastfreq,Flash_Tag_Slowfreq,Flash_Tag_Mode);
		    if(comm == Command_Good)
		    {
			     Mode_Couple_Flag = 22;
		    }
			}
			
			if(Mode_Couple_Flag == 22)
			{
				 if(Usart_event_flag & (1 << JType_TagAdded)) //接收到正确返回信息
		     {
		  	   Usart_event_flag &= (0 << JType_TagAdded);
           Mode_Couple_Flag = 23;
           delay_ms(100);					 
		     }
			}			
			
			if(Mode_Couple_Flag == 23)
			{
				comm = Commu_Save();
				if(comm == Command_Good)
				{
					system_flag = system_couple_working;  //匹配成功 退出搜索模式
					Mode_Couple_Flag = 0;
					LED2_En = 0;         //代表匹配成功
					LED2_ON;
					COUPLE_Beep_En = 0;
				}
			}

		}
		
		case system_couple_working:
		{
			if(Usart_event_flag & (1 << JType_TWR)) //接收到新标签ID
		  {

//			  char show[10] = {'0'};
			  Usart_event_flag &= (0 << JType_TWR);			
			
			//电机控制
		    LED3_TOGGLE;
//			printf("raw:%d %d %d %d\r\n",JTwrtag.X,JTwrtag.Y,JTwrtag.Dis,JTwrtag.P);				
			  comm_move = Motion_Control(JTwrtag.X,JTwrtag.Y,JTwrtag.Dis,JTwrtag.P);
			  time_flag = 0;
	   }
	 
		 if(comm_move != Motion_Stop)
	     comm_move = Motion_IR_Control(comm_move);
		
	   if(time_flag > 5000)
	   {
		   Motion_Init();
		   comm_move = Motion_Stop;
	  }
					 
		 Motion_Act(comm_move);		
		 break;
	  }
	}	

}


/******************************************************************************
												         主函数
*******************************************************************************/
int main(void)
{
    peripherals_init();//初始化外设
	
//  printf("初始化完成!");
//	u2_printf("初始化完成!");
	FLASH_read();  //读取Flash中保存的参数
	Adc_Event();   //先测量一次电压
//	Move_Test();
		
	LED2_ON;
	LED3_ON;

	while(1)
	{				
		Key_Event();
		Usart_Fin_Handler();

		if(time_flag_Adc > ADC_Timeout)  //每ADC_Timeout的时间测量一次电压
			Adc_Event();
		
//		Usart_Test();	
if(led_flag==1)	
{	
		switch(Flash_App_Mode)
		{
			case MODE_SINGLE:
			{
				Mode_Single_App();
				break;
			}
			case MODE_COUPLE:
			{
				Mode_Couple_App();
				break;
			}
			default:break;
		}
}
else
{
Motor_Stop();//报警后,电机停止运动
}
		
		if(LED_FLAG > 100000)
		{			
            LED1_TOGGLE;	
			if(LED2_En)
				LED2_TOGGLE;
			if(LED3_EN)
				LED3_TOGGLE;			
			LED_FLAG = 0;
/*报警闪灯*/			
			if(led_flag==0)
			{
				LED0=!LED0;
				//u2_printf("123\r\n");
			}
/*End*/
		}
		else
            LED_FLAG++;		
/*蜂鸣器使用*/	
//		if(ADC_Beep_En || COUPLE_Beep_En)
//		{
//			if(Beep_Flag > 80000)
//			{
//				Beep_Toggle;
//				Beep_Flag = 0;
//			}
//			else
//				Beep_Flag++;
//		}
//		else
//			    Beep_Off;
/*End*/
		if(COUPLE_Beep_En)
		{
			if(Beep_Flag > 80000)
			{
				Beep_Toggle;
				Beep_Flag = 0;
			}
			else
				Beep_Flag++;
		}
		else
			    Beep_Off;		
	}
		
}



标签:void,adc,买菜,Beep,Flag,Mode,ADC
From: https://www.cnblogs.com/hcnnnnnn/p/16747826.html

相关文章