你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F405RGT6 ADC2+TIM4触发+DMA(DMA2_Stream2_CH1)+DMA中断会死机(取消中断后完全正常)

[复制链接]
onlap 提问时间:2025-7-18 16:40 / 未解决

ADC1+TIM4触发+DMA(DMA2_Stream0_CH0)+DMA中断完全正常 更改为 ADC2+TIM4触发+DMA(DMA2_Stream2_CH1)+DMA中断会死机(取消中断后完全正常) 更改为 ADC3+TIM4触发+DMA(DMA2_Stream1_CH2)+DMA中断会死机(取消中断后完全正常)

void ADC2_EXIT_TIM4_CC4_Trig_DMAConfiguration(unsigned short F_Prescaler,unsigned int F_ARR )//ADC_TIM4_CC4外部触发转换 {

GPIO_InitTypeDef  GPIO_InitStructure;

ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_InitTypeDef ADC_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟 //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOC时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能

// Configure PA5 PA4 PC2(ADC Channel 5-0-1-13) as analog input ------------------------- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//GPIO模式为ADC模拟输入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;//选择PA5 PA4 为输入通道 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//端口速度50MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//不带上下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);

 // ADC2 configuration -----------------------------------------------------
// ADCs DeInit 

RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE); //ADC2复位 RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE); //复位结束 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); //使能ADC2时钟

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;;//连续转换模式 使用(连续模式) ADC_InitStructure.ADC_ScanConvMode = DISABLE;;//扫面模式 使用(扫描) ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Falling;//禁止触发检测,使用软件触发 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4;//外部触发源 外部引脚 (已经禁止触发检测了) ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐 ADC_InitStructure.ADC_NbrOfConversion = 1;//指定规则组转换的通道 5个通道 ADC_Init(ADC2, &ADC_InitStructure);//ADC初始化

ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);

ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样阶段之间的延迟5个时钟 ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA使能模式 ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频。ADCCLK=PCLK2/4=84/4=21Mhz,ADC时钟最好不要超过36Mhz ADC_CommonInit(&ADC_CommonInitStructure);//初始化

ADC_DMARequestAfterLastTransferCmd(ADC2,ENABLE); //单通道使用 //ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); ADC_DMACmd(ADC2,ENABLE);//使能ADC的DMA数据传送功能

ADC_Cmd(ADC2, ENABLE);//使能ADC2 // DMA2_Stream2_CH0ADC configuration ---------------------------------------------- DMA2_Stream2_CH1_ADC2_Config((uint32_t *)OSC_ADC_ConvertedValue,232,DMA_Mode_Circular);// DMA2_Stream2_CH1_ADC2_Config ADC DMA NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断优先级分组方式,整个程序只配置一次,可以放置在程序最开始

NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;//DMA2_Stream2中断占用通道 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//配置中断抢占优先级值,分组2的值为0-3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//配置中断响应优先级的值 分组2的值为0-3 NVIC_Init(&NVIC_InitStructure);

DMA_Cmd(DMA2_Stream2, ENABLE);//打开DMA2 Stream0(或者使能) / Enable DMA Channelx complete transfer interrupt / // DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TC); //清除中断标志 // DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);

// Start ADC2 Software Conversion
ADC_SoftwareStartConv(ADC2); //使能指定的ADC2的软件转换启动功能

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//配置定时器计时参数 TIM_OCInitTypeDef TIM_OCInitStructure;//设置结构体

//开启TIM4时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

//选择TIM4的时钟模式为内部模式,时钟源为内部时钟(42*2=84MHZ) TIM_InternalClockConfig(TIM4);

//初始化上述结构体 TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
//配置预分频系数为8400 TIM_TimeBaseInitStructure.TIM_Prescaler = F_Prescaler;
//配置自动重装值为10000 TIM_TimeBaseInitStructure.TIM_Period = F_ARR;
//配置计数模式为向上计数 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //配置定时器时钟频率与数字滤波器所使用的采样时钟之间的分频比 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //配置重复计数器的值为0 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
//初始化时基单元 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);

TIM_OCStructInit(&TIM_OCInitStructure);//给结构体设置默认初始值 ////配置TIM4 通道1占空比 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式 PWM1模式 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性,默认输出高电平 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能输出比较 TIM_OCInitStructure.TIM_Pulse = 10; //设置CCR数值 输出比较直0-FFFF(占空比-CCR/ARR) TIM_OC4Init(TIM4, &TIM_OCInitStructure);//初始化TIM4输出通道OC4

//选择更新事件作为触发输出 TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_OC4Ref);

//开启TIM4,此时计数器开始工作 TIM_Cmd(TIM4, ENABLE);
}

void DMA2_Stream2_IRQHandler(void) //DMA2_Stream2_IRQn { if(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF1)) //清除传输完成中断 { DMA_ClearITPendingBit(DMA2_Stream2, DMA_IT_TCIF1); // 清除传输完成标志 DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF1); OSC_ADC_FLAG=1; TIM_Cmd(TIM4, DISABLE); }

if( DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_HTIF1)) //清除半传输完成中断

{ DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_HTIF1);

}

// Clear the Streamx direct mode error flag 

if( DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_DMEIF1)) //清除传输错误中断

{ DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_DMEIF1);

}

if( DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_FEIF1)) //清除Streamx FIFO error flag

{ DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_FEIF1);

}

}

以上换成ADC1+TIM4+DMA+DMA中断工作完全正常 不清楚是什么原因

收藏 评论1 发布时间:2025-7-18 16:40

举报

1个回答
xmshao 回答时间:昨天 14:29

你检查下使用ADC2/ADC3时除了模块的差别外,其它是否都是一样的。

检查下是否有中断服务程序跟中断矢量表里定义的不一致的情况。

可以肯定TIM4的OC4事件时可以用来触发ADC1/2/3的。

我这边使用TIM4同时触发3个ADC模块,DMA循环搬运结果,程序运行可控。

尽量使用CubeMx进行配置,这样方便。

image.png

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版