⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main_ctl_test1.c

📁 MEGA32L 单片机的按键,LED,LCD等测试例程,ICCAVR编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
//======================================
//主控模块源程序
//FileName =main_ctl.c
//Date Time=20070608...20070824
//======================================
#include <eeprom.h>
#include <string.h>

#include "hc165.h"
#include "delay.h"
#include "main_ctl.h"
#include "int0_z.h"
#include "serial.h"
#include "ir_inter.h"
#include "mega32_adc.h"
#include "wdog.h"
#include "key_switch.h"
#include "output.h"

volatile struct	_st_work_mode		st_work_mode;		//工作模式结构变量
volatile struct	_st_eeprom_para_gdc	st_eeprom_para_gdc;	//eeprom中的设置参数
volatile struct _st_eeprom_para_speed_pwm st_eeprom_para_speed_pwm;	//eeprom中各种旋转速度的PWM控制数据值设置参数

//20070823(6-2)
volatile struct	_st_eeprom_para_pan_half_count st_eeprom_para_pan_half_count;	//PAN控制数据的一半值

volatile struct	_st_led_beep_op		st_led_beep_op;		//指示灯操作的结构
volatile struct	_st_warning_op		st_warning_op;		//告警的说明结构

volatile uchar	curr_adjust_x_y_z_number;		//up & down按键下调节x,y,z(x)的序号

//各种速度序号下的PWM控制参数的常数定义,具体的0/60/300/600cps的数据来源于EEPROM的设置
volatile uint	PWM_Output_Control_Data_By_Ctl_Num[4];

//各种工作模式下的PWM控制参数的加载变量,在初始化的时候设置初值,
//光电池参数设置模式(=10)采用300cps速度进行
volatile uint	PWM_Output_Control_Data_By_Work_Mode[CONST_WORK_MODE_DEFINE_COUNT_MAX];

//20070726 将非0扇扫集中到一起,调整到最前面,便于模式的判断使用!
//这里要求:前面模式的定义必须固定为:Auto Pan10/45/180, Man Pan10/45/180!
//!!!如果模式定义的顺序改变,这里也要做相应的调整!!!
//20070824(1-1) 采用PAN角度设置程序后,数据表将在 init_st_eeprom_para_pan_half_count() 中填充
volatile uchar	CONST_PAN_MOVE_HALF_STEPS_BY_PAN_MODE[6];

volatile uchar	detect_switch_is_horizontal_flag[2];	//前一个字节是计算值,首一个字节是计数器

//20070831(4-1)
volatile uint adc_xyz_windows_buff[17][3];		//ADC数据控制的窗口缓存
volatile uchar adc_xyz_windows_buff_len;		//ADC数据控制的窗口缓存中的有效个数,最大16个
volatile uchar adc_xyz_windows_buff_pos;		//ADC数据控制的窗口缓存中的存储指针

//20070905(6-0)
volatile uchar flag_xz_move_to_middle_pos;		//=0 已经偏离x,z中心附近位置,其非0数值是进行非大步驱动的依据
volatile uchar flag_y_move_to_middle_pos;		//=0 已经偏离y中心附近位置,其非0数值是进行非大步驱动的依据

//20070913(1-1)
volatile uchar flag_is_power_lower_flash;		//=1 标识是电池低压4~4.4V的Power灯闪烁

void	main(void)
{
#if	(DEBUG_ENABLE_SOFT_SIMULATION ==0)
uchar i;
//20070820(4-1)
uint adc_change_inner_delay;
#endif
uint word_tmp =0;

	_CLI();
	SP =CONST_UINT_RAM_END;
	//延时消除Power按键抖动
	delay_x1ms(50);
	
	init_system();
	_SEI();	

	//进行参数设置和删除的分支的判断,这里仅仅支持本地按键!	
	if( (word_tmp =judge_read_local_and_ir_keys()) ==CONST_HAS_READ_KEY)
	{	//存在按键
		if(st_curr_key.flag_now_is_local_key ==CONST_KEY_TYPE_IS_LOCAL)
		{	//本地按键
			word_tmp =st_curr_key.local_key_label;
		}
	}	
		
	//参数删除 Left + Power
	if(word_tmp ==CONST_KEY_LAB_LEFT_WITH_POWER)
	{	
		Dowith_Init_Para_Delete();	//以关机结束
	}
	//20070823(6-3)
	//Pan角度设置 Pan + Power
	else if(word_tmp ==CONST_KEY_LAB_X_AND_PAN_WITH_POWER)
	{
		Dowith_Set_Pan_Jiao_Du_Half_Val();	
	}
	//软件效验 "手动/自动按键 +电源按键"
	else if(word_tmp ==CONST_KEY_LAB_MAN_OR_AUTO_WITH_POWER)
	{
		while(1)
		{
			st_judge_key.curr_get_key_value =CONST_KEY_LAB_IDEL;			
			if( (word_tmp =judge_read_local_and_ir_keys()) ==CONST_HAS_READ_KEY)
			{
				if( (st_curr_key.flag_now_is_local_key ==CONST_KEY_TYPE_IS_LOCAL) &&
				    (st_curr_key.local_key_label ==CONST_KEY_LAB_MAN_OR_AUTO) )
				{	
					break;
				}	
			}
		};
		
		//20070912(4-1)
		if(st_work_mode.bak_flag_is_horizontal ==CONST_FLAG_IS_HORIZONTAL_MODE)
		{
			//X_PAN灯开始闪烁
			led_and_beep_operation(CONST_XU_HAO_OF_X_AND_PAN_LED,CONST_FLAG_FLASH_IS_LED_BEEP_FLASH_EVER,0);		
		}
		else
		{
			//X_PAN灯关闭
			led_and_beep_operation(CONST_XU_HAO_OF_X_AND_PAN_LED,CONST_FLAG_FLASH_IS_LED_BEEP_OFF,0);			
		}
		
		//等待按键弹起			
		while(judge_read_local_and_ir_keys() ==CONST_HAS_READ_KEY);
		st_judge_key.curr_get_key_value =CONST_KEY_LAB_IDEL;
				
		st_z_motor_control.work_mode_set=CONST_WORK_MODE_IS_SET_FACTORY_GDC_VAL;		
		st_work_mode.flag_is_tilt	=CONST_FLAG_IS_NORMAL;
		
		//初始化找平模式和限时时间计数器
		st_work_mode.flag_finding_level_mode	=CONST_FLAG_IS_INIT_SEARCHING_LEVEL;
		st_work_mode.auto_power_off_delay_count	=(CONST_LIMITED_FINDING_LEVEL_COUNTS<<3);	//40分钟时间	
		st_work_mode.flag_auto_power_off_delay_timeout =0;
		
		//20070823(8-1)
		if(st_work_mode.bak_flag_is_horizontal ==CONST_FLAG_IS_HORIZONTAL_MODE)
		{
			curr_adjust_x_y_z_number =CONST_FLAG_ADJUST_X_DIRECT;
		}
		else
		{	//垂直方向
			curr_adjust_x_y_z_number =CONST_FLAG_ADJUST_Z_DIRECT;
		}

		//激光灯闪烁;
		led_and_beep_operation(CONST_XU_HAO_OF_JI_GUANG_LED,CONST_FLAG_FLASH_IS_LED_BEEP_FLASH_EVER, 0);


		//需要启动Z的旋转(是否真的启动Z还是要看具体的工作模式),当前没有转动
		st_work_mode.need_start_z_moving	=1;
		st_work_mode.state_now_z_is_moving	=0;
	}
	//"speed + Tilt按键" 硬件调试
	else if(word_tmp ==CONST_KEY_LAB_Y_AND_TILT_WITH_Z_AND_SPEED)
	{	
		Dowith_Hardware_Debug();	//最后关机退出
	}
	//"speed +Power"	 设置旋转速度
	else if(word_tmp ==CONST_KEY_LAB_Z_AND_SPEED_WITH_POWER)
	{	
		st_z_motor_control.work_mode_set	=CONST_WORK_MODE_IS_SET_FACTORY_SPEEDS;
		Auto_Detect_To_Set_Circus_Speed();	//最后关机退出
	}
	else
	{	
_prog_label_normal:
		//20070805(2-1) 等待Power按键弹起
		while(CODE_GET_POWER_IN !=0);
		//延时消除按键抖动
		delay_x1ms(50);

		//20070820(2-1) 
		//以免初始化过程影响其他的设置过程!
		led_and_beep_all_on();
		delay_x250ms(3);
		led_and_beep_all_off();

		//初始找平模式
		st_z_motor_control.work_mode_set =CONST_WORK_MODE_IS_AUTO_CIRCU_SPEED_300;
		st_work_mode.flag_is_tilt	=CONST_FLAG_IS_NORMAL;
		
		//初始化找平模式和限时时间计数器
		st_work_mode.flag_finding_level_mode	=CONST_FLAG_IS_INIT_SEARCHING_LEVEL;
		st_work_mode.auto_power_off_delay_count	=CONST_LIMITED_FINDING_LEVEL_COUNTS;
		st_work_mode.flag_auto_power_off_delay_timeout =0;
		
		//20070823(8-2)
		if(st_work_mode.bak_flag_is_horizontal ==CONST_FLAG_IS_HORIZONTAL_MODE)
		{
			curr_adjust_x_y_z_number =CONST_FLAG_ADJUST_X_DIRECT;
		}
		else
		{	//垂直方向
			curr_adjust_x_y_z_number =CONST_FLAG_ADJUST_Z_DIRECT;
		}

		//需要启动Z的旋转(是否真的启动Z还是要看具体的工作模式),当前没有转动
		st_work_mode.need_start_z_moving	=1;
		st_work_mode.state_now_z_is_moving	=0;

		
		//初始化Z转动的绝对位置,以当前为起点144,最小1,最大288(一圈的INT0+INT1中断数值)
		st_z_motor_control.mp_curr_site	=CONST_MP_MIN_POS_ADDR +(CONST_MP_ALL_LENTH_NUMBER >>1);
		
		//清除中断标志
		GIFR	|= ( BIT(INTF0) |BIT(INTF1) );	
		//允许INT0,INT1中断		
		GICR	|= ( BIT(INT0) |BIT(INT1) );
	}		

	//整个流程的大循环开始!
	while(1)
	{
		//-------------------------------------------------------------
		//1) 按键的查询检测;	time=236us(没有按键时)
		//这里已经读取按键到 st_curr_key 结构中
		//和5个开关量到数据结构 st_work_mode 中		
		//实际调试时必须开放,否则没有按键!
		if( (word_tmp =judge_read_local_and_ir_keys()) ==CONST_HAS_READ_KEY )
		{
			//20070905(4-1)			
			//if( (st_z_motor_control.work_mode_set != CONST_WORK_MODE_IS_INIT) &&
			//    (st_z_motor_control.work_mode_set != CONST_WORK_MODE_IS_SET_FACTORY_GDC_VAL) 
			//)	//非初始化模式 && 非出厂参数设置模式下 的 电源按键 则关机! 
			if(st_curr_key.local_key_label  ==CONST_KEY_LAB_POWER)
			{
				excute_power_off();	//自动关机前进行点灯指示
			}
			//20070905(3-1)
			//20070913(1-0) 只有电池正常才允许暂停
			else if( (st_curr_key.ir_key_label  ==CONST_KEY_LAB_IR_POWER) &&				 
				(flag_is_power_lower_flash ==0) &&
				 (st_z_motor_control.work_mode_set != CONST_WORK_MODE_IS_SET_FACTORY_GDC_VAL) )
			{	//遥控器的暂停按键,软件效验没有暂停功能
				st_work_mode.need_start_z_moving =1;		//需要启动Z
				st_work_mode.state_now_z_is_moving =0;		//Z当前停止	
				led_and_beep_all_off();
				delay_x1ms(50);				
				do
				{
					//关闭激光,停止Z转动
					CODE_MOTOR_Z_MOVE_STOP;
					led_and_beep_operation(CONST_XU_HAO_OF_MANUAL_AND_AUTO_LED, CONST_FLAG_FLASH_IS_LED_BEEP_OFF, 0);
					//电源灯闪烁指示暂停状态
					led_and_beep_operation(CONST_XU_HAO_OF_POWER_LED, CONST_FLAG_FLASH_IS_LED_BEEP_ON_EVER, 0);
															
					if( (word_tmp =judge_read_local_and_ir_keys()) ==CONST_HAS_READ_KEY )
					{
						if(st_curr_key.local_key_label  ==CONST_KEY_LAB_POWER)
						{
							excute_power_off();	//自动关机前进行点灯指示
						}
						else if(st_curr_key.ir_key_label  ==CONST_KEY_LAB_IR_POWER)
						{	//遥控器的暂停按键,功能恢复
							//电源灯关闭,指示暂停状态结束
							led_and_beep_operation(CONST_XU_HAO_OF_POWER_LED, CONST_FLAG_FLASH_IS_LED_BEEP_OFF, 0);
							now_reset_limit_switch_exception();
							break;
						}
					}							
				}while(1);	
			}
		}


		//-------------------------------------------------------------
		//2) ADC数据的预处理,使用查询方式
		//输入:
		//	st_adc_op.inner_curr_adc_value[4]
		//	pos_of_all_adc_buff =0...(CONST_ADC_DATAS_LEN-1)
		//	all_adc_buffer_datas[4][CONST_ADC_DATAS_LEN]
		//输出:
		//	st_gdc_adc_sets_paras[4].curr_filter_dat
		//20070802(8-1) 人工模式关闭光电池,停止x,y,z的A/D转换;
		if((st_work_mode.flag_finding_level_mode &CONST_FLAG_IS_MAN_MODE_SEARCH_LEVEL) ==CONST_FLAG_IS_MAN_MODE_SEARCH_LEVEL)
		{	//增加延时,保持节奏
			delay_500us();
			pos_of_all_adc_buff =0;
			flag_filter_dat_can_use =0;			
		}
		else
		{
			//20070814 增加延时时间,并将延时时间集中,最后再采集控制
			if(pos_of_all_adc_buff <CONST_ADC_DATAS_LEN)
			{	
				//20070820(4-2)	延长计数器,利于找平,但是电机输出时间 CONST_MOTOR_XYZ_CTL_MOVE_BIG_STEP_TIMES 需要同步更改!
				//总时间大约 100*500us =50ms
				if(++adc_change_inner_delay >=120)
				{									
					//实际采样1次
//20070922(1-)
					//dowith_adc_change_xyz();						
//......................................
					for(i=0; i<3; i++)
					{
						all_adc_buffer_datas[i][pos_of_all_adc_buff] =st_adc_op.inner_curr_adc_value[i];
					}						
					pos_of_all_adc_buff ++;
					flag_filter_dat_can_use =0;
				}
				else
				{	//增加延时,降低功耗!
					delay_500us();
					flag_filter_dat_can_use =0;
				}				
			}
			else
			{
				adc_change_inner_delay =0;
				pos_of_all_adc_buff =0;
				get_adc_curr_xyz_filter_dat();
//20070922(1-)
st_gdc_adc_sets_paras[0].curr_filter_dat =st_gdc_adc_sets_paras[0].mid_pos;				
st_gdc_adc_sets_paras[1].curr_filter_dat =st_gdc_adc_sets_paras[1].mid_pos;				
st_gdc_adc_sets_paras[2].curr_filter_dat =st_gdc_adc_sets_paras[2].mid_pos;				
//..............................								
				
				flag_filter_dat_can_use =1;	//供后续函数使用
			}
		}


#if	(DEBUG_ENABLE_NEGLET_POWER_DETECT ==0)
		//-------------------------------------------------------------
		//3) 电压的检测,一次循环约0.2s,所以检测数据的周期约1分钟
		if( ++st_work_mode.detect_power_count_of_main >=250)
		{
			st_work_mode.detect_power_count_of_main =0;
			//检测一组电压数据
			for(word_tmp=0, i=0; i<4; i++)
			{
//20070922(1-)
//			 	st_adc_op.inner_curr_adc_value[CONST_ADC_CHANNEL_POWER] =do_adc_one_channel_change(CONST_ADC_CHANNEL_POWER);
			 	st_adc_op.inner_curr_adc_value[CONST_ADC_CHANNEL_POWER] =1000;
//..............................
				all_adc_buffer_datas[CONST_ADC_CHANNEL_POWER][i]	=st_adc_op.inner_curr_adc_value[CONST_ADC_CHANNEL_POWER];
				word_tmp +=all_adc_buffer_datas[CONST_ADC_CHANNEL_POWER][i];
			}
			//得到平均值			
			st_gdc_adc_sets_paras[CONST_ADC_CHANNEL_POWER].curr_filter_dat =word_tmp >>2;
			word_tmp >>= 2;
			
			//结果的判断
			if(word_tmp >=CONST_POWER_ADC_VALUE_OF_43V)
			{	//>=4.4V 电源指示灯关闭

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -