其实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++)
;
}