九齐NY8BE62D软件开发

开启100us中断

void Time_Init(void)
{
	DISI();
	//;Initial Timer0
	PCON1 = C_TMR0_Dis; // Disable Timer0
	TMR0 = 100;			// Load 0x00 to TMR0 (Initial Timer0 register)

	T0MD = C_PS0_TMR0 | C_PS0_Div2; 
	INTE = C_INT_TMR0;
	
	PCON1 = C_TMR0_En; // Enable Timer0
	ENI();			   // Enable all unmasked interrupts
}

开启10ms执行一次main函数

void isr(void) __interrupt(0)
{
	if (INTFbits.T1IF)
	{
		INTF = (char)~(C_INT_TMR1); // Clear T1IF flag bit
	}
	if (INTFbits.T0IF)
	{
		INTF = (char)~(C_INT_TMR0); // Clear T0IF flag bit
		TMR0 += 158;
		
		ti16_cnt0++;
		if (ti16_cnt0 > 99)
		{
			ti16_cnt0 = 0;
			time_10ms_flag = 1;
		}
	}
}

void main(void)
{
	GPIO_Init();
	CLRWDT();
	ADC_Init();
	PWM_Init();
	delay(1000);
	Time_Init();

	while (1)
	{
		CLRWDT(); // Clear WatchDog
		if (time_10ms_flag)
		{
			time_10ms_flag = 0;
			//这里面添加要执行的程序
		}
	}
}

ADC初始化

PACON寄存器添加要打开的引脚通道

void ADC_Init(void)
{
	//----- Initial ADC-----
	ADMD = C_ADC_En | C_ADC_CH_Dis | C_Quarter_VDD; // Enable ADC power, Disable global ADC input channel, Select PA0 pad as ADC input (SFR "ADMD")
													//----- ADC high reference voltage source select-----
													//	ADVREFH = C_Vrefh_VDD;					// ADC reference high voltage is supplied by internal VDD (Note: ADC clock freq. must be equal or less 2MHz @ VDD=5.0V)
	// ADVREFH = C_Vrefh_4V;					// ADC reference high voltage is supplied by internal 4V  (Note: ADC clock freq. must be equal or less 1MHz)
	ADVREFH = C_Vrefh_3V; // ADC reference high voltage is supplied by internal 3V  (Note: ADC clock freq. must be equal or less 500KHz)
	// ADVREFH = C_Vrefh_2V; // ADC reference high voltage is supplied by internal 2V  (Note: ADC clock freq. must be equal or less 250KHz)
	//----- ADC clock frequency select----------------------------
	ADR = C_Ckl_Div1; // ADC clock=Fcpu/1, Clear ADIF, disable ADC interrupt
					  //	ADR	 = C_Ckl_Div2;						// ADC clock=Fcpu/2, Clear ADIF, disable ADC interrupt
					  // ADR	  = C_Ckl_Div8;					// ADC clock=Fcpu/8, Clear ADIF, disable ADC interrupt
	// ADR	 = C_Ckl_Div16;					// ADC clock=Fcpu/16, Clear ADIF, disable ADC interrupt
	//----- ADC Sampling pulse width select-------------
	// ADCR  = C_Sample_1clk | C_12BIT;		// Sample pulse width=1 adc clock, ADC select 12-bit conversion ( Note: ADC clock freq. must be equal or less 500KHz)
	// ADCR  = C_Sample_2clk | C_12BIT;		// Sample pulse width=2 adc clock, ADC select 12-bit conversion ( Note: ADC clock freq. must be equal or less 1MHz)
	// ADCR  = C_Sample_4clk | C_12BIT;		// Sample pulse width=4 adc clock, ADC select 12-bit conversion ( Note: ADC clock freq. must be equal or less 1.25MHz)
	ADCR = C_Sample_8clk | C_12BIT; // Sample pulse width=8 adc clock, ADC select 12-bit conversion ( Note: ADC clock freq. must be equal or less 2MHz)
									//--------------------------------------------------
	// Set AIN0(PA0) to AIN7(PB2) as pure ADC input for reduce power consumption (SFR "PACON")
	PACON = C_PB0_AIN5 | C_PA1_AIN1; // C_PB2_AIN7 | C_PB1_AIN6 | C_PB0_AIN5 | C_PA4_AIN4 | C_PA3_AIN3 | C_PA2_AIN2 | C_PA1_AIN1 | C_PA0_AIN0;
	// Set AIN8(PB3) as pure ADC input for reduce power consumption (SFR "ADCR")
	ADCR |= C_Sample_8clk | C_12BIT | C_PB3_AIN8; // C_PB3_AIN8 |
	ADMDbits.GCHS = 1;							  // Enable global ADC channel	(SFR "ADMD")
	delay(50);									  // Delay 0.56ms(Instruction clock=4MHz/2T) waiting ADC stable
}

ADC采集函数

ADMD寄存器
九齐NY8BE62D软件开发_第1张图片九齐NY8BE62D软件开发_第2张图片
如果采集VDD的话电压要除于4
ch是采集通道
vref是参考电压:C_Vrefh_VDD,C_Vrefh_4V,C_Vrefh_3V,C_Vrefh_2V

unsigned int Get_ADC_Value(unsigned char ch, unsigned char vref) //,unsigned char vref)
{
	unsigned char i = 3;
	unsigned int value = 0, buf, max = 0, min = 0xFFFF;
	ADMD = C_ADC_En | C_ADC_CH_Dis | C_Quarter_VDD;
	ADMD = 0x90 | ch;
	ADVREFH = vref;
	delay(100);
	while (i)
	{
		i--;
		ADMDbits.START = 1; // Start a ADC conversion session
		while (ADMDbits.EOC == 0)
			; // Wait for ADC conversion complete
	}
	value = 0;
	for (i = 0; i < 6; i++)
	{
		ADMDbits.START = 1; // Start a ADC conversion session
		while (ADMDbits.EOC == 0)
			; // Wait for ADC conversion complete
		buf = ADD;
		buf <<= 4;
		buf |= 0x0F & ADR;
		if (max <= buf)
			max = buf;
		if (min >= buf)
			min = buf;
		value += buf;
	}
	value -= max;
	value -= min;
	value >>= 2;
	return value;
}

PWM初始化

引脚对应的pwm几就打开几
我只打开了pwm1和pwm5

void PWM_Init(void)
{
   // Initial Timer 1 & PWM1/2 control register
   TMRH = 0; // C_TMR1_Data_b9 | C_TMR1_Data_b8 | C_PWM2_Duty_b9 | C_PWM2_Duty_b8 ;
   // TM4RH = 0; // C_TMR4_Data_b9 | C_TMR4_Data_b8 | C_PWM3_Duty_b9 | C_PWM3_Duty_b8;
   TM5RH = 0; // C_TMR5_Data_b9 | C_TMR5_Data_b8 | C_PWM5_Duty_b8;

   TMR1 = 0xFF; // Move FFH to TMR1 LB register ( TMR1[9:0]=3FFH )
   // TMR4 = 0xFF;  // Move FFH to TMR4 LB register ( TMR1[9:0]=3FFH )
   TMR5 = 0xFF;  // Move FFH to TMR5 LB register ( TMR1[9:0]=3FFH )
   PWM1DUTY = 0; // Move 01H to PWM1DUTY LB register ( PWM1DUTY[9:0]=001H )
   			  //    PWM2DUTY = 0;			// Move FFH to PWM2DUTY LB register ( PWM2DUTY[9:0]=3FFH )
   			  //    PWM3DUTY = 0;			// Move FFH to PWM3DUTY LB register ( PWM3DUTY[9:0]=300H )
   // PWM4DUTY = 0; // Move FFH to PWM4DUTY LB register ( PWM4DUTY[9:0]=0FFH )
   PWM5DUTY = 0; // Move FFH to PWM5DUTY LB register ( PWM3DUTY[9:0]=100H )

   T1CR2 = C_PS1_Dis | C_TMR1_ClkSrc_Inst;							  // Prescaler 1:1 , Timer1 clock source is instruction clock
   T1CR1 = C_PWM1_En | C_PWM1_Active_Hi | C_TMR1_Reload | C_TMR1_En; // Enable PWM1 , Active_High , Non-Stop mode ,reloaded from TMR1[9:0] , enable Timer1
   //    P2CR1    = C_PWM2_En | C_PWM2_Active_Hi;
   //    P3CR1	 = C_PWM3_En | C_PWM3_Active_Hi;	// Enable PWM3 , Active_High , Non-Stop mode ,reloaded from TMR3[9:0] , enable Timer3
   // T4CR2 = C_PS4_Dis | C_TMR4_ClkSrc_Inst;							  // Prescaler 1:1 , Timer4 clock source is instruction clock
   // T4CR1 = C_PWM4_En | C_PWM4_Active_Hi | C_TMR4_Reload | C_TMR4_En; // Enable PWM4 , Active_High , Non-Stop mode ,reloaded from TMR4[9:0] , enable Timer4
   T5CR2 = C_PS5_Dis | C_TMR5_ClkSrc_Inst;							  // Prescaler 1:1 , Timer5 clock source is instruction clock
   T5CR1 = C_PWM5_En | C_PWM5_Active_Hi | C_TMR5_Reload | C_TMR5_En; // Enable PWM5 , Active_High , Non-Stop mode ,reloaded from TMR5[9:0] , enable Timer5
}

结构体写bit节省空间

8个标志位只占了1个字节

typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
// union
//{
typedef struct
{
	unsigned bit0 : 1;
	unsigned bit1 : 1;
	unsigned bit2 : 1;
	unsigned bit3 : 1;
	unsigned bit4 : 1;
	unsigned bit5 : 1;
	unsigned bit6 : 1;
	unsigned bit7 : 1;
} byte;
byte flag_byte = {0}, flag_byte1 = {0};

#define time_10ms_flag flag_byte.bit0
#define power_flag flag_byte.bit1		 // 开关机
#define direction_flag flag_byte.bit2	 // 电机正反转  0正1反
#define volFull_flag flag_byte.bit3		 // 充满
#define heat_mode_count flag_byte.bit4	 // 0关闭  1高档
#define vbat_low_off_flag flag_byte.bit5 // 低电量
#define breath_flag flag_byte.bit6		 // 呼吸灯
#define key_sign flag_byte.bit7

软推pwm实现呼吸灯

把该函数放中断执行就可以了
一旦打开breath_flag呼吸灯开始执行

//***************************呼吸灯程序******************************
void breath_led_func()
{
	static u16 pwm_count = 0;
	static u16 pwm_set = 0;
	static u8 pwm_dir = 1;
	static u8 pwm_set_count = 0;
	if (breath_flag)
	{
		pwm_count++;
		if (pwm_count < pwm_set)
			LED_GREEN = 1;
		else
			LED_GREEN = 0;
		if (pwm_count == 20) // 20*50us=1ms,pwm波频率为 1KHz
		{
			pwm_count = 0;
			pwm_set_count++;
		}
		if (pwm_set_count == 50) // 50ms调整一次占空比,占空比调整频率为20Hz
		{
			pwm_set_count = 0;
			if (pwm_dir == 1)
				pwm_set++;
			else
				pwm_set--;
			if (pwm_set == 20) // 20*500*2ms=2s为一个呼吸周期
				pwm_dir = 0;
			if (pwm_set == 0)
				pwm_dir = 1;
		}
	}
	else
	{
		pwm_count = 0;
	}
}

ADC计算电压方法

电压V = (ad值/(2^adc位数))*参考电压

你可能感兴趣的:(单片机,嵌入式硬件)