NY8B062D 九齐单片机之ADC(采样值不准的解决办法)

其实ADC的程序 官方已经给出了 如下 ( 写这篇文章的目的是 就是本人在使用的时候 发现采样的数值 每次在接收采样值 必须要清零 要不然到处漂 ) 下面一段时间官方的程序 我就在上面加了个pwm的测试功能
另外 九齐官方并没有给出具体得出电压的公式 这个问题开始我是找了一会的说明书 真的没有 后面还是根据以前的经验算法得出来的数值 采样值 * 基准电压/4096 当然2k的单片机肯定不能在程序中计算,直接在外面计算好,得出的一个值在写入程序中进行判断就好了

=========================================================================*/
#include 
#include "ny8_constant.h"
unsigned int  R_AIN2_DATA=0;	
unsigned char R_AIN2_DATA_LB=0;	

unsigned int  R_AIN3_DATA=0;	
unsigned char R_AIN3_DATA_LB=0;	
		
unsigned int  R_Quarter_VDD_DATA=0 ;	
unsigned char R_Quarter_VDD_DATA_LB=0;	

unsigned int  D_PWM2_DUTY=0X00;

#define UPDATE_REG(x)	__asm__("MOVR _" #x ",F")
//unsigned int  
#define C_PWM_LB_DUTY_00H	0x00      //0x00
#define C_PWM_LB_DUTY_40H	0xA0      
#define C_PWM_LB_DUTY_01H	0x01
#define C_PWM_LB_DUTY_FFH	0x01


void F_AIN2_Convert(char);
void F_AIN3_Convert(char);

void F_Quarter_VDD_Convert(char);
void F_wait_eoc(void);
void delay(int);

void main(void)
{
  //----- Initial GPIO-----
   //1 IOSTA = C_PA0_Input;					// Set PortA as input port
   //1 IOSTA = C_PA1_Input;					// Set PortA as input port 
    IOSTA = C_PA2_Input ;					// Set PortA as input port
    IOSTA = C_PA3_Input ;					// Set PortA as input port 
    IOSTB = C_PB1_Output;
    

    PORTA = 0xFF;							// PortA Data Register = 0xFF
    
    PORTBbits.PB1 = 1;
    INTE  = 0x00;							// INTE = 0x00

 //----- Initial ADC-----	  
//1	ADMD  = C_ADC_En | C_ADC_CH_Dis | C_ADC_PA0 ;	// Enable ADC power, Disable global ADC input channel, Select PA0 pad as ADC input (SFR "ADMD")
 ADMD  = C_ADC_En | C_ADC_CH_Dis | C_ADC_PA2 | C_ADC_PA3 ;	// 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_4V;					// ADC reference high voltage is supplied by internal 4V  (Note: ADC clock freq. must be equal or less than 1MHz)
 	//ADVREFH = C_Vrefh_3V;					// ADC reference high voltage is supplied by internal 3V  (Note: ADC clock freq. must be equal or less than 500KHz)
 	//ADVREFH = C_Vrefh_2V;					// ADC reference high voltage is supplied by internal 2V  (Note: ADC clock freq. must be equal or less than 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 than 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 than 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 than 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 than 2MHz)	
 // Initial Timer 1/2 & PWM1/2 control register      
    TMRH  = C_TMR2_Data_b9 | C_TMR2_Data_b8 | C_PWM2_Duty_b9 | C_PWM2_Duty_b8;
    TMR2  = 0xFF;							// Move FFH to TMR2 LB register ( TMR2[9:0]=3FFH )
   // PWM2DUTY = C_PWM_LB_DUTY_FFH;			// Move FFH to PWM2DUTY LB register ( PWM2DUTY[9:0]=3FFH )

    T2CR2	 = C_PS2_Dis | C_TMR2_ClkSrc_Inst;	                            // Prescaler 1:1 , Timer2 clock source is instruction clock
    T2CR1	 = C_PWM2_En | C_PWM2_Active_Hi | C_TMR2_Reload | C_TMR2_En;	// Enable PWM2 , Active_High , Non-Stop mode ,reloaded from TMR2[9:0] , enable Timer2
    TMRH = TMRH & 0XF3;
//--------------------------------------------------	
//1	PACON = C_PA0_AIN0 | C_PA1_AIN1;		// Set AIN0(PA0) as pure ADC input for reduce power consumption (SFR "PACON")
    PACON = C_PA2_AIN2 | C_PA3_AIN3;		// Set AIN0(PA0) as pure ADC input for reduce power consumption (SFR "PACON") 
	ADMDbits.GCHS = 1;						// Enable global ADC channel	(SFR "ADMD")
	delay(50);								// Delay 0.56ms(Instruction clock=4MHz/2T) for waiting ADC stable 
    while(1)
    {
        CLRWDT();							// Clear WatchDog
		R_AIN2_DATA=R_AIN2_DATA_LB=R_Quarter_VDD_DATA=R_Quarter_VDD_DATA_LB=R_AIN3_DATA=R_AIN3_DATA_LB =0x00;            
        F_AIN2_Convert(8);					// execute AIN0 ADC converting 8 times
        R_AIN2_DATA <<= 4;					// R_AIN0_DATA shift left 4 bit
        R_AIN2_DATA_LB &= 0xF0;				// Only get Bit7~4
        R_AIN2_DATA += R_AIN2_DATA_LB;		// R_AIN0_DATA + R_AIN0_DATA_LB
        R_AIN2_DATA >>=3;					// R_AIN0_DATA divided 8
        
        F_AIN3_Convert(8);					// execute AIN0 ADC converting 8 times
        R_AIN3_DATA <<= 4;					// R_AIN0_DATA shift left 4 bit
        R_AIN3_DATA_LB &= 0xF0;				// Only get Bit7~4
        R_AIN3_DATA += R_AIN3_DATA_LB;		// R_AIN0_DATA + R_AIN0_DATA_LB
        R_AIN3_DATA >>=3;					// R_AIN0_DATA divided 8
            
        F_Quarter_VDD_Convert(8);			// execute 1/4VDD input channel ADC converting 8 times
        R_Quarter_VDD_DATA <<= 4;			// R_Quarter_VDD_DATA shift left 4 bit
        R_Quarter_VDD_DATA_LB &= 0xF0;		// Only get Bit7~4
        R_Quarter_VDD_DATA += R_Quarter_VDD_DATA_LB;  R_Quarter_VDD_DATA + R_Quarter_VDD_DATA_LB
        R_Quarter_VDD_DATA >>=3;			// R_Quarter_VDD_DATA dividing 8

       TMRH = 0X04;
       PWM2DUTY = R_AIN2_DATA / 4;;
     
    }
}

//----- Sub-Routine ----- 
void F_AIN2_Convert(char count)
{
  	char i;
  	//1ADMD  = 0x90 | C_ADC_PA0;				// Select AIN0(PA0) pad as ADC input
  	ADMD  = 0x90 | C_ADC_PA2;				// Select AIN0(PA0) pad as ADC input
  	for(i=1;i<=count;i++)
  	{     			 
  	 ADMDbits.START = 1;					// Start a ADC conversion session
  	 F_wait_eoc();							// Wait for ADC conversion complete
  	 R_AIN2_DATA_LB += ( 0x0F & ADR); 
  	 R_AIN2_DATA    += ADD; 
  	}
}

void F_AIN3_Convert(char count)
{
  	char i;
  	//ADMD  = 0x90 | C_ADC_PA1;				// Select AIN0(PA0) pad as ADC input
  	ADMD  = 0x90 | C_ADC_PA3;				// Select AIN0(PA0) pad as ADC input
  	for(i=1;i<=count;i++)
  	{     			 
  	 ADMDbits.START = 1;					// Start a ADC conversion session
  	 F_wait_eoc();							// Wait for ADC conversion complete
  	 R_AIN3_DATA_LB += ( 0x0F & ADR); 
  	 R_AIN3_DATA    += ADD; 
  	}
}

void F_Quarter_VDD_Convert(char count)
{
  	char i;
  	ADMD  = 0x90 | C_Quarter_VDD;			// Select internal 1/4VDD as ADC input
  	for(i=1;i<=count;i++)
  	{     			 
  	 ADMDbits.START = 1;					// Start a ADC conversion session
  	 F_wait_eoc();							// Wait for ADC conversion complete	
  	 R_Quarter_VDD_DATA_LB += ( 0x0F & ADR); 
  	 R_Quarter_VDD_DATA    += ADD; 
  	}
}

void F_wait_eoc(void)
{
   while(ADMDbits.EOC==0)
   ;
}

void delay(int count)
{
	int i;
	for(i=1;i<=count;i++)
	;
}

你可能感兴趣的:(单片机系列之台湾九齐8位)