STM32 ADC DMA 中断模式多通道读取ADC转换值
2015-07-11 16:25
651 查看
因为做一个电机控制项目,其中需要用到用PWM触发ADC,读取ADC的转换值。
这里有两个关键问题:
第一,如何使PWM触发ADC转换?
第二,如何在ADC多通道扫描模式下,读取各个channel的adc转换值?
第三,如何使用DMA读取多通道ADC转换值?
第一个问题,首先需要将ADC设置成外部触发转换,第二需要选择触发是发生在Timer的上升沿还是下降沿。程序如下:
第二个问题,如果是使用ADC1的多个通道进行转换,那么使用DMA,使每个通道转换成功的数据存入响应的内存位置中,会是一个很好的选择,DMA选择外设到内存,外设地址不增加,内存地址增加。
第三个问题,DMA的拓扑图如下,记得使用对应的DMA请求,需要设置好对应的DMAy、streamx和channelz,否则没法触发DMA中断。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/4de1be072c93b98df6e75db54d3f2b39.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/9c032c6e6fff27cbaf43250ae2d6a363.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/9355ffb1645c80fa648812c1888a0cce.png)
这里使用的是ADCDMA请求,选择了DMA2 stream0 channel0。 对应的DMA配置程序如下
这里有两个关键问题:
第一,如何使PWM触发ADC转换?
第二,如何在ADC多通道扫描模式下,读取各个channel的adc转换值?
第三,如何使用DMA读取多通道ADC转换值?
第一个问题,首先需要将ADC设置成外部触发转换,第二需要选择触发是发生在Timer的上升沿还是下降沿。程序如下:
adc.ADC_Resolution = ADC_Resolution_12b; adc.ADC_ScanConvMode =ENABLE; //¶àͨµÀת»» adc.ADC_ContinuousConvMode = ENABLE; //Á¬Ðøת»» adc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T8_CC1; adc.ADC_DataAlign = ADC_DataAlign_Right; //ÓÒ¶ÔÆ뷽ʽ adc.ADC_NbrOfConversion = 2; ADC_Init(ADC1,&adc); ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_56Cycles); ADC_RegularChannelConfig(ADC1,ADC_Channel_2,2,ADC_SampleTime_56Cycles); ADC_Cmd(ADC1,ENABLE); //ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //ÉèÖô¥·¢ADCÖжϵÄÖжÏÔ´ ADC_DMACmd(ADC1, ENABLE); ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
第二个问题,如果是使用ADC1的多个通道进行转换,那么使用DMA,使每个通道转换成功的数据存入响应的内存位置中,会是一个很好的选择,DMA选择外设到内存,外设地址不增加,内存地址增加。
第三个问题,DMA的拓扑图如下,记得使用对应的DMA请求,需要设置好对应的DMAy、streamx和channelz,否则没法触发DMA中断。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/4de1be072c93b98df6e75db54d3f2b39.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/9c032c6e6fff27cbaf43250ae2d6a363.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/03/9355ffb1645c80fa648812c1888a0cce.png)
这里使用的是ADCDMA请求,选择了DMA2 stream0 channel0。 对应的DMA配置程序如下
//配置 DMA_DeInit(DMA2_Stream0); dma.DMA_Channel= DMA_Channel_0; // dma.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR); dma.DMA_Memory0BaseAddr = (uint32_t)ad_buffer; dma.DMA_DIR = DMA_DIR_PeripheralToMemory; dma.DMA_BufferSize = 2; dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//DMA_PeripheralDataSize_Byte; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//DMA_MemoryDataSize_Byte; dma.DMA_Mode = DMA_Mode_Circular; dma.DMA_Priority = DMA_Priority_High; dma.DMA_FIFOMode = DMA_FIFOMode_Disable; dma.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; dma.DMA_MemoryBurst = DMA_Mode_Normal; dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0,&dma); DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE); DMA_Cmd(DMA2_Stream0,ENABLE);
相关文章推荐
- 设计模式之状态模式
- ActionBar 设置图片、Home返回、Background图片
- 设计模式(java)1——单例模式
- mysql存储过程详解
- 前序遍历和中序遍历树构造二叉树
- 在drawable下的xml文件中layer-list的用法一:直接指定已有图片资源
- CSAPP LAB---MALLOC实验
- [Mark]分布式存储必读论文
- 四种支持向量机工具箱使用概念
- Ubuntu下的如何使用快捷键截图(自带工具)
- GDI+ 摘要: 保存图像文件
- C++控制台贪吃蛇代码
- [数学]计算点到线段的距离
- UI1_UITouch
- (未解决)android studio:com.android.support:appcompat-v7:22+ Could not found
- [置顶] 一种新的Activity转换动画实现方式
- LeetCode题解-Best Time to Buy and Sell Stock III
- 每天一个linux命令(1):ls命令
- 认识shell
- 输入十个字符(可能是数字也可能是字母)然后输出