我用c8051f064做个简单的数据采集程序,,采用DMA方式将AD转换的数据存于片内XRAM中,程序如下,其中部分引用例程,但程序好象还是有问题,怎么调试都没有数据采进来.请高手帮忙指点下,谢谢!
#include // SFR 声明
sfr16 RCAP3 = 0xCA; // 定时器3重装值
sfr16 TMR3 = 0xCC; // 定时器3计数器
sfr16 ADC0 = 0xBE; // ADC0数据
sfr16 ADC1 = 0xBE; // ADC1数据
sfr16 DMA0DS = 0xDB; // DMA0 XRAM Address Pointer
sfr16 DMA0CT = 0xF9; // DMA0 Repeat Counter Limit
sfr16 DMA0DA = 0xD9; // DMA0 Address Beginning
sfr16 DMA0CS = 0xFB; // DMA0 Repeat Counter
#define SYSCLK 22118400 // 系统时钟频率
// DMA INSTRUCTIONS
#define DMA0_END_OF_OP 0x00 // End-of-Operation
#define DMA0_END_OF_OP_C 0x80 // End-of-Operation + Continue
#define DMA0_GET_ADC0 0x10 // Retrieve ADC0 Data
#define DMA0_GET_ADC1 0x20 // Retrieve ADC1 Data
#define DMA0_GET_ADC01 0x30 // Retrieve ADC0 and ADC1 Data
#define DMA0_GET_DIFF 0x40 // Retrieve Differential Data
#define DMA0_GET_DIFF1 0x60 // Retrieve Differential and ADC1 Data
#define NUM_SAMPLES 2000 // 采样次数
#define XRAM_START_ADD 0x0000 // DMA0 XRAM Start address of ADC data log
#define SAMP_RATE 100000 // 采样频率
sbit LED = P1^6; // 做指示用,数据采集完亮.
void SYSCLK_Init (void); //系统时钟初始化
void PORT_Init (void); //端口初始化
void ADC0_Init (void); //ADC0初始化
void ADC1_Init (void); //ADC1初始化
void DMA0_Init (void); //DMA初始化
void EMIF_Init (void);
void Timer3_Init (int counts); //定时器3初始化
// MAIN Routine
void main (void)
{
LED = 0;
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
SYSCLK_Init (); // initialize SYSCLK
PORT_Init ();
EMIF_Init (); // Storing ADC samples in SRAM on the
// target board.
Timer3_Init (SYSCLK/SAMP_RATE); // Init Timer3 for 100ksps sample rate
ADC0_Init (); // configure ADC0 and ADC1 for differential
// measurement.
DMA0_Init (); // Configure DMA to move NUM_SAMP samples.
SFRPAGE = DMA0_PAGE;
while (!(DMA0CN & 0x40)); // Wait for DMA to obtain and move ADC samples
// by polling DMA0INT bit.
LED=1;
while(1); // Done.
}
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = CONFIG_PAGE; // Switch to configuration page
XBR2 = 0x40;
P1MDOUT |= 0x40; // enable Port1 outputs as push-pull
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
// SYSCLK_Init
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
char old_SFRPAGE = SFRPAGE;
int i;
SFRPAGE = CONFIG_PAGE; // Switch to Configuration Page
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal on TB
for (i=0; i <5000; i++) ; // XTLVLD blanking interval (>1ms)
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
RSTSRC = 0x04; // enable missing clock detector reset
CLKSEL = 0x01; // change to external crystal
OSCICN = 0x00; // disable internal oscillator
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
// ADC0_Init
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
char old_SFRPAGE = SFRPAGE;
int i;
SFRPAGE = ADC0_PAGE; // Switch to ADC0 Page
ADC0CN = 0xC4; // ADC Disabled, Timer3 start-of-conversion
// track 16 SAR clocks before data conversion
// upon Timer3 OV. DMA will enable ADC as needed
REF0CN = 0x03; // turn on bias generator and internal reference.
for(i=0;i<10000;i++); // Wait for Vref to settle (large cap used on target board)
AMX0SL = 0x00; // Single-ended mode
ADC0CF = (SYSCLK/25000000) << 4; // Select SAR clock frequency =~ 25MHz
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
// DMA0_Init
void DMA0_Init (void)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = DMA0_PAGE; // Switch to DMA0 Page
DMA0CN = 0x00; // Disable DMA interface
DMA0DA = XRAM_START_ADD; // Starting Point for XRAM addressing
DMA0CT = NUM_SAMPLES; // Get NUM_SAMPLES samples
DMA0IPT = 0x00; // Start writing at location 0
// Push instructions onto stack in order they will be executed
DMA0IDT = DMA0_GET_ADC0; // DMA to move ADC0 data.
DMA0IDT = DMA0_END_OF_OP;
DMA0BND = 0x00; // Begin instruction executions at address 0
DMA0CN = 0xA0; // Mode 1 Operations, Begin Executing DMA Ops
// (which will start ADC0)
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
// Timer3_Init
// Configure Timer3 to auto-reload and generate ADC sample rate
// specified by using SYSCLK as its time base.
//
void Timer3_Init (int counts)
{
char old_SFRPAGE = SFRPAGE;
SFRPAGE = TMR3_PAGE; // Switch to Timer 3 page
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
TMR3CF = 0x08; // use SYSCLK as timebase
RCAP3 = -counts; // Init reload values
TMR3 = 0xffff; // set to reload immediately
TR3 = 1; // start Timer3
SFRPAGE = old_SFRPAGE; // restore SFRPAGE
}
void EMIF_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = EMI0_PAGE;
EMI0CF = 0x10;
SFRPAGE = SFRPAGE_SAVE;
}