看到前面有人DMA+ADC通道错位,共享下我的,写了一上午,没有错位,希望对大家有帮助(PS,datasheet真的很差)
#define ADCBUF_SIZE 400
uint16 adcbuf[ADCBUF_SIZE];
volatile uint8 flag = 0;
void ADCGpioInit(void)
{
GPIOA_CRL->MODE4 = 0; //模拟输入
GPIOA_CRL->CNF4 = 0;
GPIOA_CRL->MODE5 = 0; //模拟输入
GPIOA_CRL->CNF5 = 0;
GPIOA_CRL->MODE6 = 0; //模拟输入
GPIOA_CRL->CNF6 = 0;
GPIOA_CRL->MODE7 = 0; //模拟输入
GPIOA_CRL->CNF7 = 0;
}
void DMAInit(void)
{
RCC_AHBENR->DMA1E = 1;
DMA_CCR1->EN = 0; //关闭DMA
DMA_CPAR1 = (uint32)adcbuf;
DMA_CMAR1 = (uint32)ADC1_DR;
DMA_CNDTR1->NDT = ADCBUF_SIZE;
DMA_CCR1->MEM2MEM = 0;
DMA_CCR1->PL = 1;
DMA_CCR1->MSIZE = 1; //16B
DMA_CCR1->PSIZE = 1; //外设也是16B
DMA_CCR1->MINC = 0;
DMA_CCR1->PINC = 1; //外设地址递增
DMA_CCR1->CIRC = 0; //不循环
DMA_CCR1->DIR = 1;
DMA_CCR1->TCIE = 1; //允许传输完成中断
}
void ADC_Init(void)
{
DMAInit(); //DMA初始化
RCC_APB2ENR->ADC1EN = 1;
ADC1_SQR1->L = 3; //4个转换
ADC1_SQR3->SQ1 = 4;
ADC1_SMPR2->SMP4 = 5; //转化时间
ADC1_SQR3->SQ2 = 5;
ADC1_SMPR2->SMP5 = 5;
ADC1_SQR3->SQ3 = 6;
ADC1_SMPR2->SMP6 = 5;
ADC1_SQR3->SQ4 = 7;
ADC1_SMPR2->SMP7 = 5;
ADC1_CR1->DUALMOD = 0; //独立模式
ADC1_CR1->SCAN = 1; //开启扫描
ADC1_CR2->EXTSEL = 7; //软件触发
ADC1_CR2->ALIGN = 0; //右对齐
ADC1_CR2->DMA = 1; //使用DMA
ADC1_CR2->CONT = 1; //连续转换
}
void Close_ADC(void)
{
DMA_CCR1->EN = 0;
ADC1_CR2->SWSTART = 0;
ADC1_CR2->ADON = 0;
}
void Open_ADC(void)
{
DMA_CNDTR1->NDT = ADCBUF_SIZE;
ADC1_CR2->ADON = 1;
ADC1_CR2->RSTCAL = 1;
while(ADC1_CR2->RSTCAL);
ADC1_CR2->CAL = 1;
while(ADC1_CR2->CAL);
ADC1_CR2->EXTTRIG = 1;
DMA_CCR1->EN = 1;
ADC1_CR2->SWSTART = 1;
}
uint16 channeldata[4];
uint16 GetADCData(void)
{
uint32 sum = 0;
uint16 i;
if(flag == 1)
{
sum = 0;
for(i=0;i<ADCBUF_SIZE;i=i+4)
sum += adcbuf[i];
channeldata[0] = sum*4/ADCBUF_SIZE;
sum = 0;
for(i=1;i<ADCBUF_SIZE;i=i+4)
sum += adcbuf[i];
channeldata[1] = sum*4/ADCBUF_SIZE;
sum = 0;
for(i=2;i<ADCBUF_SIZE;i=i+4)
sum += adcbuf[i];
channeldata[2] = sum*4/ADCBUF_SIZE;
sum = 0;
for(i=3;i<ADCBUF_SIZE;i=i+4)
sum += adcbuf[i];
channeldata[3] = sum*4/ADCBUF_SIZE;
Uart_Printf(3,"%4d ",channeldata[0]);
Uart_Printf(3,"%4d ",channeldata[1]);
Uart_Printf(3,"%4d ",channeldata[2]);
Uart_Printf(3,"%4d \n",channeldata[3]);
flag = 0;
return 1;
}
return 0;
}
void DMA_IRQ(void)
{
if(DMA_ISR->TCIF1 == 1)
{
flag = 1;
DMA_IFCR->CTCIF1 = 1;
}
}
uint8 num = 0;
void ADC_Test(void)
{
ADCGpioInit();
OpenADC();
while(1)
{
if(GetADCData())
{
CloseADC();
OSTimeDly(500);
ADCopen();
}
OSTimeDly(50);
}
} |