2.9 外围设备DMA请求
当A/D转换结束的时候,转换结果被存储在ADDR寄存器中VALID位被置‘1’。如果ADCR.PTEN被置‘1’,A/D控制器将产生PDMA请求(P_nDRQ)来传输数据,PDMA通过回应P_nDRQ请求来读走A/D转换的数据,以此达到CPU无干预情况下的连续A/D转换。
3 A/D转换编程方法 3.1 单次A/D转换下的程序流程
1. 设置被选为A/D转换功能的GPIOA口为输入模式
2. 根据需要设置寄存器CLKSEL1中的ADC_S位和CLKDIV中的ADC_N,然后设置寄存器APBCLK中的ADC_EN位来使能ADC时钟源
3. 根据操作模式设定寄存器ADCR中的ADEN,DIFF,ADMD位
4. 设置ADCHER寄存器CHEN位来选择A/D转换通道
5. 设置ADCR寄存器中ADIE位和NVIC_ISER寄存器来使能中断
6. 设置ADCR寄存器中ADST开始A/D转换
3.2 示例程序#include <stdio.h>
#include "NUC1xx.h"
/*----------------------------------------------------------------------------
Define variable
----------------------------------------------------------------------------*/
static uint32_t ADCTemp=0;
/*----------------------------------------------------------------------------
Function subroutine
----------------------------------------------------------------------------*/
void Delay(uint32_t delayCnt)
{
while(delayCnt--)
{
__NOP();
__NOP();
}
}
/*----------------------------------------------------------------------------
Interrupt subroutine
----------------------------------------------------------------------------*/
void ADC_IRQHandler(void) // Timer0 interrupt subroutine
{
ADC->ADSR.ADF=1;
ADCTemp=ADC->ADDR[1].RSLT;
}
/*----------------------------------------------------------------------------
MAIN function
----------------------------------------------------------------------------*/
int32_t main (void)
{
NVIC_DisableIRQ(ADC_IRQn); //Disable ADC interrupt
outpw(&ADC->ADCR ,0 ); //Disable ADC
/* Step 1. GPIO initial */
GPIOA->PMD.PMD1=0; //Set input mode
GPIOA->SCH|=0x00020000; //Disable digital input path
SYS->GPAMFP.ADC1=1; //Set ADC function
/* Step 2. Enable and Select ADC clock source, and then enable ADC module */
SYSCLK->CLKSEL1.ADC_S = 2; //Select 22Mhz for ADC
SYSCLK->CLKDIV.ADC_N = 1; //ADC clock source = 22Mhz/2 =11Mhz;
SYSCLK->APBCLK.ADC_EN = 1; //Enable clock source
/* Step 3. Select Operation mode */
ADC->ADCR.ADEN = 1; //Enable ADC module
ADC->ADCR.DIFF = 0; //single end input
ADC->ADCR.ADMD = 0; //single mode
/* Step 4. Select ADC channel */
ADC->ADCHER.CHEN = 0x02;
/* Step 5. Enable ADC interrupt */
ADC->ADSR.ADF =1; //clear the A/D interrupt flags for safe
ADC->ADCR.ADIE = 1;
NVIC_EnableIRQ(ADC_IRQn);
/* Step 6. Conversion start */
ADC->ADCR.ADST=1;
while(1)
{
if (ADC->ADSR.BUSY==0) ADC->ADCR.ADST=1;
ADCTemp=ADC->ADSR.CHANNEL;
}
}
|