
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外部触发转换 {
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);
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 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); 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); }
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中断工作完全正常 不清楚是什么原因 |
STM32F405的ADC功耗参数不理解
CUBEIDE1.19.0
stm32支持canfd和dma结合使用吗
多DMA数据流问题
NUCLEO-F401RE板卡,连接USB,在KEIL下可以找到ST-LINK仿真器,也可以下载代码。在电脑上看不到NODE_F401RE的磁盘,有知道是什么原因?
程序进入HardFault_Handler求解
STM32CUBEIDE
This example describes how to configure the FMC controller to access the SDRAM memory in low power mode
STM32407 使用串口闲时中断+DMA方式接收最大接收字节是多少
USB_CDC_HOST 标准库里边USBH_DeAllocate_AllChannel()函数的疑问?
你检查下使用ADC2/ADC3时除了模块的差别外,其它是否都是一样的。
检查下是否有中断服务程序跟中断矢量表里定义的不一致的情况。
可以肯定TIM4的OC4事件时可以用来触发ADC1/2/3的。
我这边使用TIM4同时触发3个ADC模块,DMA循环搬运结果,程序运行可控。
尽量使用CubeMx进行配置,这样方便。