STM32 ADC DMA时EOC转换完成中断异常

问题:用ADC1连续采集几个通道上的电压值,配置为规则组,没有开启ADC1的DMA的时候EOC中断是正常的。但是开启ADC1的DMA传输之后EOC中断的频率明显变慢了。

开始以为是STM32F1的DMA和CM3内核共享系统数据总线,然后DMA的开启导致CM3响应ADC中断的速度变慢。

但是,后来发现原因是开启DMA会读取ADC的DR寄存器,而ADC的DR寄存器的读操作会清除EOC(转换完成)标志位,所以ADC的中断服务函数中判断不到EOC标志位。(清除了EOC标志位,但ADC的中断服务函数还是可以正常进入的。只是判断不到EOC标志了)
然后去翻了一下数据手册中ADC的状态寄存器EOC标志位的说明:
在这里插入图片描述“读取ADC_DR时清除”。
所以,可以不用DMA,EOC中断就能正常判断了。或者仅使能EOC中断,只要进了ADC的中断服务函数中就认为是EOC中断。(但是要注意在STM32F1中ADC1和ADC2共用一个中断向量)
再或者没有必要的话就不用EOC中断了,不用使能EOC中断。直接读取DMA转换来的数据即可。

感谢一下这篇帖子的作者(https://blog.csdn.net/diyer_zhou/article/details/108698771
第一句话就把我遇到的问题给解决了。

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
的实现代码应该怎么写? 对于stm32h750的adc dma传输的实现代码,可以如下进行编写: 首先需要进行adc模块的初始化,在初始化中需要设置好adc的通道、采样间等参数,然后使用HAL库中的HAL_ADC_Start_DMA()函数启动采集,并将采集到的数据传输到指定的内存地址中。 具体的代码实现如下: ```c /* ADC初始化 */ static void MX_ADC_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } } /* DMA初始化 */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ /* DMA2_Stream0_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } /* 启动ADC采集 */ void ADC_Start(void) { HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_value, 1); } /* DMA传输完成回调函数 */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* 在此处添加处理采集数据的代码 */ } ``` 在上述代码中,MX_ADC_Init()函数是ADC模块的初始化函数,用于设置ADC的参数;MX_DMA_Init()函数是DMA控制器的初始化函数;ADC_Start()函数则是用于启动DMA传输数据的函数,其中adc_value为存储采集到的数据的内存地址;HAL_ADC_ConvCpltCallback()是DMA传输完成回调函数,用于处理采集到的数据。 以上代码仅供参考,具体实现应根据实际需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值