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

📄 adc.c

📁 Kalman Filter PIC30F3011 testboard V3 源码
💻 C
字号:
/***********************************************************************
 *                                                                     *
 * This file contains the implementation of adc.h for the dsPIC30F3011 *
 * device and the 5DOF test board v3.                                  *
 *                                                                     *
 ***********************************************************************
 *                                                                     * 
 *    Author:         Tom Pycke                                        *
 *    Filename:       adc.c                                            *
 *    Date:           13/10/2007                                       *
 *    File Version:   1.00                                             *
 *    Other Files Required: adc.h                                      *
 *                                                                     *
 ***********************************************************************
 *                                                                     *
 * Other Comments:                                                     *
 * The 5DOF test board v3 is using the following ADC input pins:       *
 * AN2 till AN7 using AN0 and AN1 as voltage referene.                 *
 * I included the code for 2 low-pass filters:                         *
 *  - Average of last 2 samples                                        *
 *  - Median over 3 samples                                            *
 *  - Runge-Kutta 4th order                                            *
 ***********************************************************************/
 
#include "common.h"

// we're implementing ../adc.h
#include "../adc.h"
 
// to define the timer 3 counter value
#define SAMPLINGRATE    1800
#define SAMPCOUNT       (FCY/SAMPLINGRATE)+1

 
unsigned int adc_buf[16];
volatile unsigned int* ADC16Ptr = &ADCBUF0; //Pointer to ADC register buffer, 

unsigned int adc_filter_buffer[4][6] = { {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0} };

unsigned int current_buf = 1;

 
void adc_init()
{
	adc_stop();	
	
	// CONTROL BITS (See p17-34 in "dsPIC30F Family Reference Manual")
    // Sequence Select
    ADCON2bits.SMPI = 5;    // Interrupt on 6th sample
    ADCON2bits.CHPS = 0;    // Sample channel CH0
    ADCON1bits.SIMSAM = 0;  // n/a for single channel sample
    ADCON2bits.BUFM = 0;    // Single 16-word result buffer
    ADCON2bits.ALTS = 0;    // Always use MUX A input select
    
    // MUX A Input Select
    ADCHSbits.CH0SA = 0;    // Overridden by CSCNA
    ADCHSbits.CH0NA = 0;    // Select VREF- for CH0- input
    ADCON2bits.CSCNA = 1;   // Scan channel 0 inputs
    ADCSSL = 0b011111100;   // Scan AN2..AN7
    ADCHSbits.CH123SA = 0;  // n/a
    ADCHSbits.CH123NA = 0;  // n/a
    
    // MUX B Input Select
    ADCHSbits.CH123SA = 0;  // n/a
    ADCHSbits.CH123NA = 0;  // n/a
    
    
    // SPECIFIC BITS
    ADCON1bits.FORM = 0b10;  // Use fractional (DOUT = dddd dddd dd00 0000) for future compatibility with 12-bit ADC
    ADCON1bits.SSRC = 2;     // Use TIMER3 trigger to start convertion
    ADCON1bits.ASAM = 1;     // Sampling begins immediately after last conversion completes. SAMP bit is auto set
    ADCON2bits.VCFG = 0b011; // Use VREF+ and VREF- as reference
    ADCON3bits.ADCS = 0b011111;    // Timing for 8MHz
    ADPCFG = 0xFF00;         // AN0..AN7 are analog
    TRISB = 0b11111111;      // Port B is input
    
    // INITIALIZE TIMER3 (used to trigger ADC)
    TMR3 = 0x0000;
    PR3 = SAMPCOUNT;
    IFS0bits.ADIF = 0;       //Clear the A/D interrupt flag bit
    IEC0bits.ADIE = 1;       //Set the A/D interrupt enable bit 
}


void adc_start()
{
    //Turn on the A/D converter
    //This is typically done after configuring other registers
    ADCON1bits.ADON = 1;

    //Start Timer 3
    T3CONbits.TON = 1;	
}


void adc_stop()
{
	// Turn off the A/D converter
    ADCON1bits.ADON = 0;

    // Stop TIMER 3
    T3CONbits.TON = 0;
}

/*
 * ADC interrupt, called when 6 conversions are done
 *
 * Implements 4th order Runge-Kutta filter
 */
void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
	unsigned int i;
	
	for (i=0; i < 6; i++)
  		adc_filter_buffer[current_buf][i] = ADC16Ptr[i];

    for (i=0; i < 6; i++)
     	adc_buf[i] = (adc_filter_buffer[current_buf][i]/6 + 
     	              adc_filter_buffer[(current_buf+1)%4][i]/6 +
     	              adc_filter_buffer[(current_buf+2)%4][i]/3 +
     	              adc_filter_buffer[(current_buf+3)%4][i]/3);
	current_buf = (current_buf+1) % 4;
	
	IFS0bits.ADIF = 0;
}



/*   NO FILTERING  */
/*void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
    unsigned int channel = 0;
    unsigned int buffer = 0;
    for (buffer=0; buffer < 6; buffer++)
     	adc_buf[buffer] = ADC16Ptr[buffer];

	IFS0bits.ADIF = 0;
}
*/


/* Average over 2 samples */
/*unsigned int adc_buf1[6];
unsigned int adc_buf2[6];
unsigned int adc_buf3[6];
unsigned int adc_buf4[6];*/
/*void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
     unsigned int channel = 0;
     unsigned int buffer = 0;

	if (current_buf == 1)
	{
	    for (buffer=0; buffer < 6; buffer++)
    	 	adc_buf1[buffer] = ADC16Ptr[buffer];
		current_buf = 2;
	}
	else
	{
	    for (buffer=0; buffer < 6; buffer++)
    	 	adc_buf2[buffer] = ADC16Ptr[buffer];
		current_buf = 1;
	}	
    for (buffer=0; buffer < 6; buffer++)
     	adc_buf[buffer] = (adc_buf1[buffer]/2 + adc_buf2[buffer]/2);

	IFS0bits.ADIF = 0;
}
*/


/* Median over 3 samples */
/*unsigned int middle(unsigned int x, unsigned int y, unsigned int z)
{
	if (x > y)
	{
		if (z > x)
			return x;
		else if (z > y)
			return z;
		else
			return y;	
	} 
	else // x < y 
	{
		if (z < x)
			return x;
		else if (z < y) // & x < z
			return z;
		else
			return y;		
	}
}
void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
     unsigned int channel = 0;
     unsigned int buffer = 0;

	if (current_buf == 1)
	{
	    for (buffer=0; buffer < 6; buffer++)
    	 	adc_buf1[buffer] = ADC16Ptr[buffer];
		current_buf = 2;
	}
	else if (current_buf == 2)
	{
	    for (buffer=0; buffer < 6; buffer++)
    	 	adc_buf2[buffer] = ADC16Ptr[buffer];
		current_buf = 3;
	}	
	else if (current_buf == 3)
	{
	    for (buffer=0; buffer < 6; buffer++)
    	 	adc_buf3[buffer] = ADC16Ptr[buffer];
		current_buf = 1;
	}	

    for (buffer=0; buffer < 6; buffer++)
     	adc_buf[buffer] = middle(adc_buf1[buffer], adc_buf2[buffer], adc_buf3[buffer]);

	IFS0bits.ADIF = 0;
}*/

⌨️ 快捷键说明

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