在使用双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]
有没有例程分享一下,谢谢。
函 数 名: ADC1,ADC2,初始化同步规则转换
调 用: ADC_RegSimul_Init(void)
参 数: 无
返 回 值: 无
说 明: ADC1 模拟输入通道0,ADC2 模拟输入通道1
********************************************************************************************/
void ADC_RegSimul_Init(void)
{
RCC->APB2ENR |= 0x00000610; //PCLK2/6 = 12MHZ(ADC转换器的时钟)
RCC->APB2ENR |= 1<<2; //使能PORTA口时钟
GPIOA->CRL &= 0XFFFFFF00; //PA0,PA1 anolog输入
RCC->APB2ENR |= 1<<9; //ADC1时钟使能
RCC->APB2ENR |= 1<<10; //ADC2时钟使能
RCC->APB2RSTR |= 1<<9; //ADC1复位
RCC->APB2RSTR &= ~(1<<9); //ADC2复位结束
RCC->APB2RSTR |= 1<<10; //ADC2复位
RCC->APB2RSTR &= ~(1<<10); //ADC2复位结束
//ADC1寄存器的配置方法
ADC1->CR1 = 0x00060000; //同步规则模式
ADC1->CR2 = 0x000E0002;
ADC1->SQR1 = 0x00000000;
ADC1->SMPR2 = 0x00000007; //转换时间(239.5周期)
ADC1->SQR3 = 0x00000000; //ADC1的0通道 PA0
ADC1->CR2 |= 0x00000001; //使能ADC1
ADC1->CR2 |= 0x00000008; //使能ADC1复位
while(ADC1->CR2&1<<3); //等待复位校准结束
ADC1->CR2|=1<<2; //开启AD校准,该位由软件设置以开始校准,
//并在校准结束时由硬件清除
while(ADC1->CR2&1<<2); //等待校准结束
//ADC2寄存器配置的方法
ADC2->CR1 = 0x00060000; //同步规则模式
ADC2->CR2 = 0x000E0002; //禁止扫描模式,使能连续转换,
ADC2->SQR1 = 0x00000000;
ADC2->SMPR2 = 0x00000038; //转换时间(239.5周期)
ADC2->SQR3 = 0x00000001; //ADC2的第1通道 PA1
ADC2->CR2 |= 0x00100000; //使能ADC2外部触发转换
ADC2->CR2 |= 0x00000001; //使能ADC2
ADC2->CR2 |= 1<<3; //使能复位校准,该位由软件设置并由硬件清除,
//在校准寄存器被初始化后该位将被清除。
while(ADC2->CR2 & 1<<3); //等待ADC2复位校准结束
ADC2->CR2 |= 1<<2; //开启AD校准,该位由软件设置以开始校准
//并在校准结束时由硬件清除
while(ADC2->CR2 & 1<<2); //等待ADC2校准结束
ADC1->CR2 |= 0x00000100; //使能ADC1 DMA传输
}
一周热门 更多>