STM32F1xx 多路ADC 使用DMA转换结果顺序错乱问题
2017-01-04 10:22
288 查看
使用DMA获取多路ADC多路转换结果的过程中出现结果顺序错乱的问题。代码如下
经测试在校准的过程不会将SR:EOC位置位,而且也不会有DMA的TC中断产生。
关于转换中断在SCAN模式下有这样的规则
只有最后一个通道转换完毕后才会产生EOC中断。
void Adc_Init() { //先初始化IO口 RCC->APB2ENR |= 1<<4; //使能PORTC口时钟 GPIOC->CRL &= 0xFFFF000F;//PC1,PC2设置为模拟输入工作模式 RCC->APB2ENR |= 1<<9; //ADC1时钟使能 RCC->APB2RSTR |= 1<<9; //ADC1复位 RCC->APB2RSTR &= ~(1<<9);//复位结束 RCC->CFGR &= ~(3<<14); //分频因子清零 RCC->CFGR |= 2<<14; //分频因子设置,对应为6分频 //PCLK2/DIV6=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!否则将导致ADC准确度下降! ADC1->CR1 &= 0xF0FFFF; //工作模式清零, ADC1->CR1 |= 0<<16; //独立工作模式 ADC1->CR1 |= 1<<8; //扫描模式 ADC1->CR2 |= 1<<1; //连续转换模式 ADC1->CR2 |= 1<<8; //启用DMA模式 ADC1->CR2 &= ~(7<<17); //清除外部事件触发 ADC1->CR2 |= 7<<17; //使用软件控制转换 ADC1->CR2 |= 1<<20; //使用用外部触发(SWSTART)!!!必须使用一个事件来触发 ADC1->CR2 &= ~(1<<11); //右对齐 ADC1->SQR1 &= ~(0xF<<20); ADC1->SQR1 |= 2<<20; //3(channl 11,12,13)个转换在规则序列中 也就是只转换规则序列2 ADC1->SMPR1 &= ~(0x3F<<3); //采样时间清空 ADC1->SMPR1 |= 0x2D<<3; //55.5周期,提高采样时间可以提高精确度 约6us ADC1->SQR3 &= 0xFFFF8000;//规则序列1 通道ch ADC1->SQR3 |= 0x358B; //12<<5+11 ADC1->CR2 |= 1<<0; //开启AD转换器 ADC1->CR2 |= 1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准寄存器复位完成 ADC1->CR2 |= 1<<2; //启动校准 while(ADC1->CR2&1<<2); //等待校准结束 ADC1->SR &= ~(1<1); //clear SR:EOC bit ADC1->CR2 |= 1<<22; //启动规则转换通道 }
void DMA_Config(DMA_Channel_TypeDef*DMA_CHx, u32 cpar, u32 cmar, u16 cndtr) { RCC->AHBENR|=1<<0; //开启DMA1时钟 delay_ms(5); //等待DMA时钟稳定 DMA_CHx->CPAR=cpar; //DMA1 外设地址 DMA_CHx->CMAR=cmar; //DMA1,存储器地址 DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量 DMA_CHx->CCR=0x00000000; //复位 DMA_CHx->CCR|=0<<4; //传输方向:外设至存储器 DMA_CHx->CCR|=1<<5; //循环模式 DMA_CHx->CCR|=0<<6; //外设地址非增量模式 DMA_CHx->CCR|=1<<7; //存储器增量模式 DMA_CHx->CCR|=1<<8; //外设数据宽度为16位 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位 DMA_CHx->CCR|=2<<12; //中等优先级 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式 DMA_CHx->CCR|=1<<0; //开启DMA传输 }这是两段初始化的代码,一开始的调用是DMA->ADC,结果在两路转换的结果错了,后来改为ADC->DMA 结果正确。但是到了使用三路ADC时就又错了本应该1-->2-->3 的结果变成2-->3-->1。即使在ADC校准后将SR->EOC位清除也没用。所以将ADC启动语句放到了DMA初始化函数中如下所示;
void DMA_Config(DMA_Channel_TypeDef*DMA_CHx, u32 cpar, u32 cmar, u16 cndtr) { RCC->AHBENR|=1<<0; //开启DMA1时钟 delay_ms(5); //等待DMA时钟稳定 DMA_CHx->CPAR=cpar; //DMA1 外设地址 DMA_CHx->CMAR=cmar; //DMA1,存储器地址 DMA_CHx->CNDTR=cndtr; //DMA1,传输数据量 DMA_CHx->CCR=0x00000000; //复位 DMA_CHx->CCR|=0<<4; //传输方向:外设至存储器 DMA_CHx->CCR|=1<<5; //循环模式 DMA_CHx->CCR|=0<<6; //外设地址非增量模式 DMA_CHx->CCR|=1<<7; //存储器增量模式 DMA_CHx->CCR|=1<<8; //外设数据宽度为16位 DMA_CHx->CCR|=1<<10; //存储器数据宽度16位 DMA_CHx->CCR|=2<<12; //中等优先级 DMA_CHx->CCR|=0<<14; //非存储器到存储器模式 DMA_CHx->CCR|=1<<0; //开启DMA传输 ADC1->CR2 |= 1<<22; }在启动DMA后在启动ADC的连续转换功能。结果就对了。
经测试在校准的过程不会将SR:EOC位置位,而且也不会有DMA的TC中断产生。
关于转换中断在SCAN模式下有这样的规则
只有最后一个通道转换完毕后才会产生EOC中断。
相关文章推荐
- 百度地图/高德地图大批量坐标转换结果返回顺序问题
- 使用STM32F1xx_HAL库实现CAN通信的问题
- ReactNative踩坑日志——使用async/await语法解决网络请求的异步导致的指令执行顺序错乱问题
- STM32定时TIM2触发ADC采样,使用DMA保存结果
- Struts1.2中actionForm使用索引:ArrayList改用HashMap,避免错乱顺序
- 使用OPENXML函数将XML文档转换为行结果集
- C# 绘图中的图片闪烁问题解决方法的使用结果
- 使用ISA2006发布安全的Sharepoint站点疑难问题解答之连接地址转换
- WPF样式中使用BasedOn 注意顺序问题
- 解决使用nvelocity时候template文件里面包含中文输出结果时候出现乱码的问题
- 解决使用HIBERNATE对ORACLE数据库中数据进行排序分页错乱的问题
- 使用ODBC和OLEDB两种方式执行同一个存储过程,结果不同的问题!
- 解决SQL插入EXCEL字段顺序错乱问题
- 使用OPENXML函数将XML文档转换为行结果集
- 使用Pivot进行行列转换不能合并为一行的问题
- 使用SQL存储过程要特别注意的问题-注意顺序读取
- 使用Mencoder进行视频转换遇到的问题和相关解决方案
- 奇怪问题:使用Request.QueryString传递一个中文参数,结果少了一个字!
- 使用ISA2006发布安全的Sharepoint站点疑难问题解答之连接地址转换
- 使用json-lib的JSONObject.toBean( )时碰到的日期属性转换的问题