在使用双ADC进行同步采样的时候只有ADC1有数据,ADC2不能正常工作
DMA部分
[mw_shl_code=c,true]void DMA_init(void)
{
RCC->AHB1ENR|=1<<22;//DMA2时钟使能
while(DMA2_Stream0->CR&(1<<0));//确保EN=0
DMA2_Stream0->

AR=(u32)&ADC->CDR;//外设地址
DMA2_Stream0->M0AR=(u32)table; //储存器地址
DMA2_Stream0->NDTR=100; //传输数量
DMA2_Stream0->CR=0;
DMA2_Stream0->CR&=~(0X07<<25);//选择通道0
DMA2_Stream0->CR&=~(0x03<<23);//储存器单次传输
DMA2_Stream0->CR&=~(0x03<<21);//外设单次传输
DMA2_Stream0->CR&=~(0x03<<16);
DMA2_Stream0->CR|=0x02<<16;//优先级,高
DMA2_Stream0->CR&=~(1<<15);//外设地址不增量
DMA2_Stream0->CR&=~(0x03<<13);
DMA2_Stream0->CR|=0x02<<13;//储存器32位
DMA2_Stream0->CR&=~(0x03<<11);
DMA2_Stream0->CR|=0x02<<11;//外设32位
DMA2_Stream0->CR|=1<<10;//储存器地址递增
DMA2_Stream0->CR&=~(1<<9);//外设地址不递增
DMA2_Stream0->CR&=~(1<<8);//禁止循环,单次
DMA2_Stream0->CR&=~(0x03<<6);//外设到储存器
DMA2_Stream0->CR|=1<<4;//传输完成中断
MY_NVIC_Init(0,0,DMA2_Stream0_IRQn,2);
}
void DMA_enable(u16 num)
{
DMA2_Stream0->CR&=~(1<<0);//关闭DMA
while(DMA2_Stream0->CR&(1<<0));//确保EN=0,确保已经关闭
DMA2_Stream0->NDTR=num;
DMA2_Stream0->CR|=1<<0;//打开DMA
}
void DMA2_Stream0_IRQHandler(void)
{
DMA_flag=1;
DMA2->LIFCR|=1<<5;//清除传输完成中断
ADC1->CR2&=~(1<<1);//关闭ADC连续转换
ADC2->CR2&=~(1<<1);
}[/mw_shl_code]
ADC部分
[mw_shl_code=c,true]void ADC_init(void)
{
RCC->APB2ENR|=1<<8; //使能ADC1时钟
RCC->APB2ENR|=1<<9; //使能ADC2时钟
RCC->AHB1ENR|=1<<0; //使能PORTA时钟
GPIO_set(GPIOA,PIN0|PIN1,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE); //PA0,模拟输入,下拉
RCC->APB2RSTR|=1<<8; //ADC1复位
RCC->APB2RSTR&=~(1<<8); //复位结束
RCC->APB2RSTR|=1<<9; //ADC2复位
RCC->APB2RSTR&=~(1<<9); //复位结束
ADC->CCR&=~(0X03<<16);
ADC->CCR|=0X01<<16; //ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz
ADC->CCR&=~(0x03<<14);
ADC->CCR|=0x01<<14; //DMA模式1
ADC->CCR|=1<<13; //只有有数据转换就产生DMA请求
ADC->CCR&=~(0x1F<<0);
ADC->CCR|=0x06<<0; //双ADC同步模式
ADC1->CR1&=~(0X03<<24);//12位模式
// ADC1->CR1&=~(1<<8); //非扫描模式
ADC1->CR1|=(1<<8); //扫描模式
ADC1->CR2&=~(0X03<<28); //软件触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->CR2|=1<<9; //使能DMA请求
ADC1->CR2|=1<<8; //开DMA
ADC1->CR2|=1<<1; //连续转换模式
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=0<<20; //1个转换在规则序列中 也就是只转换规则序列1
ADC1->SQR3&=~(0x1F<<0);//规则序列1 通道0
ADC1->SQR3|=0;
//设置通道0的采样时间
ADC1->SMPR2&=~(7<<(3*0));//通道0采样时间清空
ADC1->SMPR2|=7<<(3*0); //通道0 480个周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器
ADC2->CR1&=~(0X03<<24);//12位模式
// ADC2->CR1&=~(1<<8); //非扫描模式
ADC2->CR1|=(1<<8); //扫描模式
ADC2->CR2&=~(0X03<<28); //软件触发
ADC2->CR2&=~(1<<11); //右对齐
ADC2->CR2|=1<<9; //使能DMA请求
ADC2->CR2|=1<<8; //开DMA
ADC2->CR2|=1<<1; //连续转换模式
ADC2->SQR1&=~(0XF<<20);
ADC2->SQR1|=0<<20; //1个转换在规则序列中 也就是只转换规则序列1
ADC2->SQR3&=~(0x1F<<0);//规则序列1 通道0
ADC2->SQR3|=0;
//设置通道0的采样时间
ADC2->SMPR2&=~(7<<(3*0));//通道0采样时间清空
ADC2->SMPR2|=7<<(3*0); //通道0 480个周期,提高采样时间可以提高精确度
ADC2->CR2|=1<<0; //开启AD转换器
}
u16 ADC_get(u8 ch)
{
ADC1->CR2|=1<<30; //启动规则转换通道
while(!(ADC1->SR&1<<1));//等待转换结束
return ADC1->DR; //返回adc值
}
void ADC_DMA_en(u8 ch)
{
ADC2->CR2|=1<<1;
ADC1->CR2|=1<<1;
//连续转换
DMA_enable(100);
// ADC->CCR|=0x06<<0; //双ADC同步模式
ADC1->CR2|=1<<30; //启动规则转换通道
}
[/mw_shl_code]
有没有例程分享一下,谢谢。
一周热门 更多>