初级会员

- 积分
- 76
- 金钱
- 76
- 注册时间
- 2020-8-25
- 在线时间
- 18 小时
|
1金钱
大佬们 看看我的配置哪里出错了,为啥我写的寄存器控制DMA传输ADC值, 没数据。下面是代码。寄存器的配置和用CUBE配置出来的一样。
ADC部分:参考原子寄存器配置,根据需要做了改动。
//先初始化IO口
RCC->AHB1ENR|=1<<5; //使能ADC1/2时钟
RCC->AHB4ENR|=1<<0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN3,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE);//PA3,模拟输入,不带上下拉
RCC->AHB1RSTR|=1<<5; //ADC1/2复位
RCC->AHB1RSTR&=~(1<<5); //复位结束
RCC->D3CCIPR&=~(3<<16); //ADCSEL[1:0]清零
RCC->D3CCIPR|=2<<16; //ADCSEL[1:0]=2,per_ck作为ADC时钟源,默认选择hsi_ker_ck作为per_ck,频率:64Mhz
ADC12_COMMON->CCR|=1<<18; //PRESC[3:0]=1,输入时钟2分频,即adc_ker_ck=per_ck/2=64/2=32Mhz(不能超过36Mhz)
ADC1->CR = 0; //CR寄存器清零,DEEPPWD清零,从深度睡眠唤醒.
ADC1->CR|=1<<28; //ADVREGEN=1,使能ADC稳压器
delay_ms(50); //等待稳压器启动完成,约10us,这里延时大一点,没关系.
ADC1->CR|=1<<8; //BOOST=1,ADC工作在boost模式(ADC频率大于20M的时候,必须设置boost位)
ADC1->CFGR=0;
//ADC1->CFGR&=~(1<<13); //CONT=0,单次转换模式
ADC1->CFGR|=1<<13; //CONT=1,连续转换模式
ADC1->CFGR|=1<<12; //OVRMOD=1,复写模式(DR寄存器可被复写)
ADC1->CFGR&=~(3<<10); //EXTEN[1:0]=0,软件触发
ADC1->CFGR&=~(7<<2); //RES[2:0]位清零
ADC1->CFGR|=0<<2; //RES[2:0]=0,16位分辨率(0,16位;1,14位;2,12位;3,10位;4,8位.)
ADC1->CFGR|=3<<0; //选择 DMA 循环模式
ADC1->CFGR2&=~((u32)15<<28); //LSHIFT[3:0]=0,不左移,数据右对齐.
ADC1->CFGR2&=~((u32)0X3FF<<16);//OSR[9:0]=0,不使用过采样
ADC1->CR&=~((u32)1<<30); //ADCALDIF=0,校准单端转换通道
ADC1->CR|=1<<16; //ADCALLIN=1,线性校准
ADC1->CR|=(u32)1<<31; //开启校准
while(ADC1->CR&((u32)1<<31));//等待校准完成
ADC1->SQR1&=~(0XF<<0); //L[3:0]清零
ADC1->SQR1|=0<<0; //L[3:0]=0,1个转换在规则序列中 也就是只转换规则序列1
// ADC1->IER |= 1<<4;
//设置通道15的采样时间
ADC1->SMPR2&=~(7<<(3*5)); //通道19采样时间清空
ADC1->SMPR2|=0<<(3*5); //通道19 1.5个周期,提高采样时间可以提高精确度
ADC1->CR|=1<<0; //开启AD转换器
ADC1->PCSEL|=1<<15; //ADC转换通道预选择
//设置转换序列
ADC1->SQR1&=~(0X1F<<6*1); //规则序列1通道清零
ADC1->SQR1|=15<<6*1; //设置规则序列1的转换通道为ch
ADC1->CR|=1<<2; //启动规则转换通道
DMA 部分
MYDMA_Config(DMA1_Stream5,9,(u32)&ADC1->DR,(u32)&adcval,1);//这个函数使用原子的,但内部按照需求已经改好了,如下
DMA1_Stream5->NDTR=1; //DMA 存储器0地址
DMA1_Stream5->CR|=31<<0; //开启DMA传输
DMA_TypeDef *DMAx;
DMAMUX_Channel_TypeDef *DMAMUXx;
u8 streamx;
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
{
DMAx=DMA2;
RCC->AHB1ENR|=1<<1; //DMA2时钟使能
}else
{
DMAx=DMA1;
RCC->AHB1ENR|=1<<0; //DMA1时钟使能
}
while(DMA_Streamx->CR&0X01);//等待DMA可配置
streamx=(((u32)DMA_Streamx-(u32)DMAx)-0X10)/0X18; //得到stream通道号
if(streamx>=6)DMAx->HIFCR|=0X3D<<(6*(streamx-6)+16); //清空之前该stream上的所有中断标志
else if(streamx>=4)DMAx->HIFCR|=0X3D<<6*(streamx-4); //清空之前该stream上的所有中断标志
else if(streamx>=2)DMAx->LIFCR|=0X3D<<(6*(streamx-2)+16); //清空之前该stream上的所有中断标志
else DMAx->LIFCR|=0X3D<<6*streamx; //清空之前该stream上的所有中断标志
if((u32)DMA_Streamx>(u32)DMA2)streamx+=8; //如果是DMA2,通道编号+8
DMAMUXx=(DMAMUX_Channel_TypeDef *)(DMAMUX1_BASE+streamx*4); //得到对应的DMAMUX通道控制地址
DMAMUXx->CCR=chx&0XFF; //通道选择
DMA_Streamx->PAR=par; //DMA外设地址
DMA_Streamx->M0AR=mar; //DMA 存储器0地址
DMA_Streamx->NDTR=ndtr; //DMA 存储器0地址
DMA_Streamx->CR=0; //先全部复位CR寄存器值
// DMA_Streamx->CR|=1<<6; //存储器到外设模式
DMA_Streamx->CR &= ~(3<<6); //外设到存储器到模式 7:6 = 00
DMA_Streamx->CR|=1<<8; //循环模式(连续传输)
DMA_Streamx->CR|=0<<9; //外设非增量模式
DMA_Streamx->CR|=0<<10; //存储器增量模式
DMA_Streamx->CR|=1<<11; //外设数据长度:16位
DMA_Streamx->CR|=1<<13; //存储器数据长度:16位
DMA_Streamx->CR|=0<<16; //低等优先级
DMA_Streamx->CR|=0<<21; //外设突发单次传输
DMA_Streamx->CR|=0<<23; //存储器突发单次传输
实际效果是 :ADC数值有 但DMA没传输过来。

|
|