/*******************************************************************************************/
/* 程序名称: AD采样程序 */
/* 单 片 机: dsPIC33FJ128GP306A */
/* 晶 振: 40MHz */
/********************************************************************************************/
/* adcDrv1.c */
/********************************************************************************************/
#i nclude "p33fxxxx.h"
#i nclude "adcDrv1.h"
#i nclude "dsp.h"
fractional BufferA[NUMSAMP] __attribute__((space(dma)));
fractional BufferB[NUMSAMP] __attribute__((space(dma)));
/*=============================================================================
initAdc1() is used to configure A/D to convert channel 5 on Timer event.
It generates event to DMA on every sample/convert sequence. ADC clock is configured at 625Khz
=============================================================================*/
void initAdc1(void)
{
AD1CON1bits.FORM = 0; // 无符号整数
AD1CON1bits.SSRC = 7; // 采用AD内部时钟切换转换
AD1CON1bits.ASAM = 1; // 转换结束立即采样
AD1CON1bits.AD12B = 1; // 12-bit 模式
AD1CON2bits.CHPS = 0; // CH0
AD1CON3bits.ADRC=0; // 采用系统时钟
AD1CON3bits.ADCS = 63; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*64 = 1.6us (625Khz)
// ADC Conversion Time for 12-bit Tc=14*Tad = 22.4us
AD1CON1bits.ADDMABM = 1; // DMA buffers are built in conversion order mode
AD1CON2bits.SMPI = 0; // SMPI must be 0
//AD1CHS0: A/D Input Select Register
AD1CHS0bits.CH0SA=16; // MUXA +ve input selection (AN16) for CH0
AD1CHS0bits.CH0NA=0; // MUXA -ve input selection (Vref-) for CH0
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
AD1PCFGHbits.PCFG16 = 0; // AN16 as Analog Input
IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1; // Turn on the A/D converter
}
// DMA0 configuration
// Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
// AMODE: Register indirect with post increment
// MODE: Continuous, Ping-Pong Mode
// IRQ: ADC Interrupt
// ADC stores results stored alternatively between BufferA[] and BufferB[]
void initDma0(void)
{
DMA0CONbits.AMODE = 0; // Configure DMA for Register indirect with post increment
DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0;
DMA0CNT=(NUMSAMP-1);
DMA0REQ=0x0D;
DMA0STA = __builtin_dmaoffset(BufferA); //取得变量首地址
DMA0STB = __builtin_dmaoffset(BufferB);
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 0; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1;
}
/********************************************************************************************/
/* 结束 */
/********************************************************************************************/
/********************************************************************************************/
/* adcDrv1.h */
/********************************************************************************************/
#ifndef __ADCDRV1_H__
#define __ADCDRV1_H__
// Sampling Control
#define Fosc 40000000
#define Fcy (Fosc/2)
#define Fs 8000
#define SAMPPRD (Fcy/Fs)-1
#define NUMSAMP 256
// External s
extern void initAdc1(void);
extern void initDma0(void);
#endif
/**********************************************************************************************/
/* 结束 */
/**********************************************************************************************/
这是两个文件,直接加入工程即可,使用时把AD输入改为实际应用引脚.然后在主程序中查询DMA0标志,标志为1即为转换完成.然后读取BufferA即可。
如果多个通道切换,要先关闭DMA,然后切换.
文件中转换方式为12位,单通道,已经过验证.