蓝桥杯嵌入式开发经验分享(第九届国赛模拟——“频率控制器的功能设置与实现”)

作者:马一飞                                                         QQ:791729359       

在学习过程中有什么问题可以联系

 

一、题目

                                            频率控制器的功能设计与实现

硬件框图

                                            蓝桥杯嵌入式开发经验分享(第九届国赛模拟——“频率控制器的功能设置与实现”)

                                                                                         图1  频率控制器硬件框图

功能描述

1、LCD显示界面

                以下为参考界面, 实现过程中选手可修改, 但显示的内容应包含题目要求的数据项。

                                                                         蓝桥杯嵌入式开发经验分享(第九届国赛模拟——“频率控制器的功能设置与实现”)   

                (1) 测量界面

                       显示项目说明:

                       PULS1、PULS2

                       PULS1通道: 对应显示脉冲信号 PULS1的频率;

                       PULS2通道: 对应显示脉冲信号 PULS2的频率;

                       备注:频率测量范围应覆盖扩展板上 PULS1、PULS2信号的输出范围。

                       AO1、AO2

                       AO1:对应显示电位器 RP5的输出电压值, 保留小数点后2位有效数;

                       AO2:对应显示电位器 RP6的输出电压值, 保留小数点后2位有效数字。

                       界面编号

                        测量界面数字编号为1

                   (2) 配置界面

                                                                             蓝桥杯嵌入式开发经验分享(第九届国赛模拟——“频率控制器的功能设置与实现”)       

                            显示项说明:

                             - 分频系数

                                      通过 PA6、PA7通道输出方波信号,信号频率为 PA1、PA2通道输入信号的N、M 分频,分频系数取值范                                         围1-4;

                              - 界面编号

                                       配置界面数字编号为2

2、按键功能

      (1) B1按键, 设置功能, 按下按键后进入配置界面,再次按下,保存当前设置,切换回测量界面。

      (2) B2按键, 选择功能, 按下按键可切换选择待配置的参数,被选择的参数项需高亮显示。

      (3) B3按键, 加功能, 按下按键,当前选择的参数加1。

      (4) B4按键, 减功能, 按下按键,当前选择的参数减1。

        备注

                1) 按键 B3、B4仅在配置界面有效

                2) 加、减操作应做合理的数据边界保护

                3) 在参数配置过程中,PA6、PA7停止信号输出,保持低电平状态

3、参数存储功能

        分频系数应保存在 E2RPOM 中,设备上电后应能重载参数。

4、指示灯功能

(1) 指示灯 LD1, 参数设置指示灯,进入参数配置界面时,指示灯点亮,退出后指示灯熄灭。

(2) 指示灯 LD8, 当电压 VAO1 > VAO2时指示灯点亮,反之指示灯熄灭。

5、试题说明

(1) 资源扩展板跳线配置参考:

                                                 蓝桥杯嵌入式开发经验分享(第九届国赛模拟——“频率控制器的功能设置与实现”)

(2) 设备上电初始状态下,处于测量界面。

 

二、模块化代码分析

1、初始化部分以及一些变量的定义

变量的定义:

u32 TimingDelay = 0;
u8 string[20];
extern u16 LED_MODE; 
u8 Display_Flag = 0;
u8 KEY_Flag = 0;
u8 ADC_Flag = 0;
u8 LED_Flag = 0;
u8 Set_Pwm_Flag = 0;
extern u8 TIM2_CH2_CAPTURE_MODE ;
extern u32 TIM2_CH2_CAPTURE_H;
extern u32 TIM2_CH2_CAPTURE_HL;
extern u8 TIM2_CH3_CAPTURE_MODE;
extern u32 TIM2_CH3_CAPTURE_H;
extern u32 TIM2_CH3_CAPTURE_HL;
u8 TIM2_CH2_Fre;  
u8 TIM2_CH3_Fre;
u8 system_mode = 0;
u8 ch1_psc = 1;
u8 ch2_psc = 1;
u8 select_psc;
u16 output1_fre;
u16 output2_fre;
u16 output1_fre_last = 0;
u16 output2_fre_last = 0;
u8 ch1_enable;
u8 ch2_enable;
float AO1;
float AO2;



系统初始化:

STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
	
SysTick_Config(SystemCoreClock/1000); //滴答定时器初始化
i2c_init();  //iic初始化
LED_Init();  //LED初始化
TIM2_CAPTURE_Init();  //TIM2捕获初始化
ch1_psc = _24c02_Read(0x11); //读取通道一分频系数
ch2_psc = _24c02_Read(0x22); //读取通道二分频系数
TIM3_OUTPUT_Init(0,0,50,50,1,ch1_enable,ch1_enable); //初始化TIM3作为比较输出
KEY_Init(); //按键初始化
ADC1_Init(); //ADC初始化

2、LED部分

if(LED_Flag)
{
	LED_Flag = 0;
	if(!system_mode)  //进入参数配置界面  LD1变化
	{
		LED_MODE |= (1<<8);
	}else
	{
		LED_MODE &=~(1<<8);
	}
	if(AO1 > AO2)  // LD8
	{
		LED_MODE &=~(1<<15);
	}else
	{
		LED_MODE |= (1<<15);
	}
	GPIOC->ODR = LED_MODE;
	GPIOD->ODR |= (1<<2);
	GPIOD->ODR &=~(1<<2);
}

3、ADC部分

    ADC部分就比较简单了,获取两路ADC值分别计算就行

if(ADC_Flag)
{
	ADC_Flag = 0;
	AO1 = Get_Adc(4) * 3.3 / 4096;
	AO2 = Get_Adc(5) * 3.3 / 4096;
}

4、捕获部分处理

if(TIM2_CH2_CAPTURE_MODE == 3) //通道2捕获
{
	TIM2_CH2_Fre = 1000000 / TIM2_CH2_CAPTURE_HL / 1000;  // 计算频率 kHZ
	TIM2_CH2_CAPTURE_MODE = 0; //清除捕获标志位
}
if(TIM2_CH3_CAPTURE_MODE == 3) //通道3捕获
{
	TIM2_CH3_Fre = 1000000 / TIM2_CH3_CAPTURE_HL / 1000;  // 计算频率 kHZ
	TIM2_CH3_CAPTURE_MODE = 0; //清除捕获标志位
}

5、显示部分

if(Display_Flag)
{
	Display_Flag = 0;
	if(!system_mode)
	{
		LCD_SetTextColor(White);
		LCD_DisplayStringLine(Line1, (u8*)"     Ce Shi Mode       ");
		sprintf((char*)string,"PULS1:%d kHZ     ",TIM2_CH2_Fre);
		LCD_DisplayStringLine(Line4, string);
		sprintf((char*)string,"PULS2:%d kHZ     ",TIM2_CH3_Fre);
		LCD_DisplayStringLine(Line5, string);
		sprintf((char*)string,"AO1:%.2fV         ",AO1);
		LCD_DisplayStringLine(Line6, string);
		sprintf((char*)string,"AO2:%.2fV         ",AO2);
		LCD_DisplayStringLine(Line7, string);
		sprintf((char*)string,"                   %d",system_mode+1);
		LCD_DisplayStringLine(Line9, string);
	}else
	{
		LCD_SetTextColor(White);
		LCD_DisplayStringLine(Line1, (u8*)"     Pei Zhi Mode       ");
		if(!select_psc)
		{
			LCD_SetTextColor(Yellow);
		}else
		{
			LCD_SetTextColor(White);
		}
		sprintf((char*)string,"PSC1:%d          ",ch1_psc);
		LCD_DisplayStringLine(Line4, string);
		if(select_psc)
		{
			LCD_SetTextColor(Yellow);
		}else
		{
			LCD_SetTextColor(White);
		}
		sprintf((char*)string,"PSC2:%d          ",ch2_psc);
		LCD_DisplayStringLine(Line5, string);
		sprintf((char*)string,"                   %d",system_mode+1);
		LCD_DisplayStringLine(Line9, string);
	}
}

6、按键部分

if(KEY_Flag)//每50ms扫描一次
{
	KEY_Flag = 0; //清除标志位
	KEY_Read(); //按键读取函数
}
void KEY_Read(void)
{
	static u16 key1_sum,key2_sum,key3_sum,key4_sum;
	// KEY1
	if(KEY1 == 0)
	{
		key1_sum++;
		if(key1_sum == 1)
		{
			system_mode ^= 1; //界面的切换
			LCD_ClearLine(Line0);  //清屏
			LCD_ClearLine(Line1);
			LCD_ClearLine(Line2);
			LCD_ClearLine(Line3);
			LCD_ClearLine(Line4);
			LCD_ClearLine(Line5);
		    LCD_ClearLine(Line6);
			LCD_ClearLine(Line7);
			LCD_ClearLine(Line8);
			LCD_ClearLine(Line9);
			if(!system_mode) // 如果是从设置界面切回主界面,则参数保存一次到eeprom
			{
				_24c02_Write(0x11,ch1_psc);
				Delay_Ms(5);
				_24c02_Write(0x22,ch2_psc);
				Delay_Ms(5);
			}
	    }
	}else
	{
		key1_sum = 0;
	}
		
	// KEY2
	if(KEY2 == 0)
	{
		key2_sum++;
		if(key2_sum == 1)
		{
			select_psc ^= 1; ////分频系数的选择
		}
	}else
	{
		key2_sum = 0;
	}
		
	// KEY3
	if(KEY3 == 0)
	{
		key3_sum++;
		if(key3_sum == 1)
		{
			if(!select_psc)  
			{
				ch1_psc++;
				if(ch1_psc >= 4) ch1_psc = 4;
			}else
			{
			    ch2_psc++;
				if(ch2_psc >= 4) ch2_psc = 4;
			}
		}
	}else
	{
		key3_sum = 0;
	}
		
	// KEY4
	if(KEY4 == 0)
	{
		key4_sum++;
		if(key4_sum == 1)
		{
			if(!select_psc)
			{
				ch1_psc--;
				if(ch1_psc <= 1) ch1_psc = 1;
			}else
			{
				ch2_psc--;
				if(ch2_psc <= 1) ch2_psc = 1;
			}
		}
	}else
	{
		key4_sum = 0;
	}
}

7、PWM输出部分

if(Set_Pwm_Flag) //每200ms检查一次看看需不需要设置pwm
{
	Set_Pwm_Flag = 0;
	if(TIM2_CH2_Fre) //如果通道2有设置频率,则使能响应的pwm
	{
		ch1_enable = 1;
	}else
	{
		ch1_enable = 0;
	}
	if(TIM2_CH3_Fre)//如果通道2有设置频率,则使能响应的pwm
	{			
        ch2_enable = 1;
	}else
	{
		ch2_enable = 0;
	}
	output1_fre = TIM2_CH2_Fre * 1000 / ch1_psc; //计算频率
	output2_fre = TIM2_CH3_Fre * 1000 / ch2_psc; //计算频率
	if((output1_fre != output1_fre_last) || (output2_fre != output2_fre_last))  //如果频率与历史值有变化,则重新设置,否则则跳过
	{
	        TIM3_OUTPUT_Init(output1_fre,output2_fre,50,50,0,ch1_enable,ch2_enable); //对响应的通道进行操作
		output1_fre_last = output1_fre; //保存作为历史值
		output2_fre_last = output2_fre;//保存作为历史值
	}
					
}

8、滴答定时器以及中断部分

        配置其实跟基础部分相差不大,实际上就是把很多个基础模块合并起来而已。具体的可以看我博客基础部分的讲解。

u8 TIM2_CH2_CAPTURE_MODE = 0;
u32 TIM2_CH2_CAPTURE_H = 0;
u32 TIM2_CH2_CAPTURE_HL = 0;
u8 TIM2_CH3_CAPTURE_MODE = 0;
u32 TIM2_CH3_CAPTURE_H = 0;
u32 TIM2_CH3_CAPTURE_HL = 0;
extern u16 CH1_Val;
extern u16 CH2_Val;
extern u16 CH1_Duty;
extern u16 CH2_Duty;
u8 TIM3_CH1_Flag;
u8 TIM3_CH2_Flag;
extern u8 KEY_Flag;
extern u8 Display_Flag;
extern u8 ADC_Flag;
extern u8 LED_Flag;
extern u8 Set_Pwm_Flag;
u8 capture_flag = 0;
void SysTick_Handler(void)
{
	static u16 capture_sum = 0;
	static u16 display_sum = 0;
	static u8 key_sum = 0;
	static u8 setpwm_sum = 0;
	static u16 adc_sum = 0;
	static u16 led_sum = 0;
	TimingDelay--;
	if(++led_sum == 300)
	{
		led_sum = 0;
		LED_Flag = 1;
	}
	if(++adc_sum == 300)
	{
		adc_sum = 0;
		ADC_Flag = 1;
	}
	if(++setpwm_sum == 200)
	{
		setpwm_sum = 0;
		Set_Pwm_Flag = 1;
	}
	if(++key_sum == 50) //50ms
	{
		key_sum = 0;
		KEY_Flag = 1;
	}
	if(++capture_sum == 500) // 500ms
	{
		capture_sum = 0;
		capture_flag ^= 1;
	}
	if(++display_sum == 100)
	{
		display_sum = 0;
		Display_Flag = 1;
	}
}

void TIM3_IRQHandler(void)
{
	u16 capture;
	if(TIM_GetITStatus(TIM3,TIM_IT_CC1) == 1)
	{
		TIM_ClearITPendingBit( TIM3, TIM_IT_CC1);
		capture = TIM_GetCapture1( TIM3);
		if(TIM3_CH1_Flag)
		{
			TIM_SetCompare1(TIM3,capture + CH1_Duty);
		}else
		{
			TIM_SetCompare1(TIM3,capture + CH1_Val - CH1_Duty);
		}
		TIM3_CH1_Flag ^= 1;
	}
		
	if(TIM_GetITStatus(TIM3,TIM_IT_CC2) == 1)
	{
		TIM_ClearITPendingBit( TIM3, TIM_IT_CC2);
		capture = TIM_GetCapture2( TIM3);
		if(TIM3_CH2_Flag)
		{
			TIM_SetCompare2(TIM3,capture + CH2_Duty);
		}else
		{
			TIM_SetCompare2(TIM3,capture + CH2_Val - CH2_Duty);
		}
		TIM3_CH2_Flag ^= 1;
	}
}
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_CC2) == 1)
	{
		TIM_ClearITPendingBit( TIM2, TIM_IT_CC2);
		if(capture_flag)
		{
			switch(TIM2_CH2_CAPTURE_MODE)
			{
				case 0: TIM2_CH2_CAPTURE_H = 0;
						TIM2_CH2_CAPTURE_HL = 0;
						TIM2_CH2_CAPTURE_MODE = 1;	
						TIM_OC2PolarityConfig( TIM2, TIM_ICPolarity_Falling);
						TIM_SetCounter(TIM2,0x0);
						break;
				case 1: TIM2_CH2_CAPTURE_H = TIM_GetCounter(TIM2);
						TIM_OC2PolarityConfig( TIM2, TIM_ICPolarity_Rising);
						TIM2_CH2_CAPTURE_MODE = 2;	
						break;
				case 2: TIM2_CH2_CAPTURE_HL = TIM_GetCounter(TIM2);
						TIM_OC2PolarityConfig( TIM2, TIM_ICPolarity_Rising);
						TIM2_CH2_CAPTURE_MODE = 3;	
						break;
			}
		}else
		{
			TIM2_CH2_CAPTURE_MODE = 0;
			TIM_OC2PolarityConfig( TIM2, TIM_ICPolarity_Rising);
		}
	}
		
	if(TIM_GetITStatus(TIM2,TIM_IT_CC3) == 1)
	{
		TIM_ClearITPendingBit( TIM2, TIM_IT_CC3);
		if(!capture_flag)
		{
			switch(TIM2_CH3_CAPTURE_MODE)
			{
				case 0: TIM2_CH3_CAPTURE_H = 0;
						TIM2_CH3_CAPTURE_HL = 0;
						TIM2_CH3_CAPTURE_MODE = 1;	
						TIM_OC3PolarityConfig( TIM2, TIM_ICPolarity_Falling);
						TIM_SetCounter(TIM2,0x0);
						break;
				case 1: TIM2_CH3_CAPTURE_H = TIM_GetCounter(TIM2);
						TIM_OC3PolarityConfig( TIM2, TIM_ICPolarity_Rising);
						TIM2_CH3_CAPTURE_MODE = 2;	
						break;
			    case 2: TIM2_CH3_CAPTURE_HL = TIM_GetCounter(TIM2);
						TIM_OC3PolarityConfig( TIM2, TIM_ICPolarity_Rising);
						TIM2_CH3_CAPTURE_MODE = 3;	
						break;
			}
		}else
		{
			TIM2_CH3_CAPTURE_MODE = 0;
			TIM_OC3PolarityConfig( TIM2, TIM_ICPolarity_Rising);
		}
	}
}

三、通用初始化部分

#include "io.h"
u16 LED_MODE = 0xffff;
u16 CH1_Val;
u16 CH2_Val;
u16 CH1_Duty;
u16 CH2_Duty;
extern u8 system_mode;
extern u8 ch1_psc;
extern u8 ch2_psc;
extern u8 select_psc;
////////////////////   LED   /////////////////////////////
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOD, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = 0xff00;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOC, &GPIO_InitStructure);
	
	GPIOC->ODR = LED_MODE;
	GPIOD->ODR |= (1<<2);
	GPIOD->ODR &=~(1<<2);
}

//////////////////////   24c02  ////////////////////////
void _24c02_Write(u8 address,u8 data)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(address);
	I2CWaitAck();
	I2CSendByte(data);
	I2CWaitAck();
	I2CStop();
}
u8 _24c02_Read(u8 address)
{
	u8 temp;
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	I2CSendByte(address);
	I2CWaitAck();

	I2CStart();
	I2CSendByte(0xa1);
	I2CWaitAck();
	temp = I2CReceiveByte();
	I2CWaitAck();
	I2CStop();
	return temp;
}

///////////////////////   capture   //////////////////////
void TIM2_CAPTURE_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 ,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	TIM_TimeBaseInitStructure.TIM_Period = 0xffff;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x0;
	TIM_TimeBaseInitStructure.TIM_CounterMode = 0x0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICFilter = 0x0;
	TIM_ICInit(TIM2, &TIM_ICInitStructure);
	
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
	TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStructure.TIM_ICFilter = 0x0;
	TIM_ICInit(TIM2, &TIM_ICInitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
	TIM_ITConfig( TIM2,TIM_IT_CC2 | TIM_IT_CC3, ENABLE);
}

//////////////////   PWM_OUTPUT   //////////////////////
void TIM3_OUTPUT_Init(u16 ch1_val,u16 ch2_val,u8 ch1_duty,u8 ch2_duty,u8 status,u8 enable1,u8 enable2)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	if(status)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 ,ENABLE);
		
	
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init( GPIOA, &GPIO_InitStructure);
			
		NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
			
		TIM_TimeBaseInitStructure.TIM_Period = 0xffff;
		TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
		TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x0;
		TIM_TimeBaseInitStructure.TIM_CounterMode = 0x0;
		TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	}
		
	CH1_Val = 1000000 / ch1_val;
	CH2_Val = 1000000 / ch2_val;
	CH1_Duty = CH1_Val * ch1_duty / 100;
	CH2_Duty = CH2_Val * ch2_duty / 100;
		
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	if(enable1)
	{
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	}else
	{
	    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
	}
	TIM_OCInitStructure.TIM_Pulse = CH1_Val;
	TIM_OC1Init( TIM3,&TIM_OCInitStructure);
		
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	if(enable2)
	{
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	}else
	{
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
	}
	TIM_OCInitStructure.TIM_Pulse = CH2_Val;
	TIM_OC2Init( TIM3,&TIM_OCInitStructure);
		
	TIM_SetCounter(TIM3, 0x0);
	TIM_SetCompare1(TIM3,0x0);
	TIM_SetCompare2(TIM3,0x0);
	if(status)
	{
		TIM_Cmd( TIM3, ENABLE);
		TIM_ITConfig( TIM3,TIM_IT_CC1 | TIM_IT_CC2,ENABLE);
	}
}
///////////////// ADC   /////////////////////
void ADC1_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStructure);

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1,&ADC_InitStructure);

	ADC_Cmd( ADC1,ENABLE);

	ADC_StartCalibration( ADC1);
	while(ADC_GetCalibrationStatus(ADC1));
	ADC_ResetCalibration( ADC1);
	while(ADC_GetResetCalibrationStatus(ADC1));
}

u16 Get_Adc(u8 channel)
{
	u16 temp;
	ADC_RegularChannelConfig(ADC1, channel, 1,ADC_SampleTime_239Cycles5);
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == 0);
	temp = ADC_GetConversionValue(ADC1);
	ADC_SoftwareStartConvCmd(ADC1, DISABLE);
	return temp;
}
//////////////////  KEY   //////////////////////
void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init( GPIOB, &GPIO_InitStructure);
}