21ic问答首页 - 各位帅哥,问下stm32的DMA问题
各位帅哥,问下stm32的DMA问题
limoooo2024-12-28
使用STM32f103c8t6标准库,的TIM1 TRGO触发ADC注入组采样(2个通道),通过DMA传输进AD_Value[2]中在程序中可以使用ADC_GetInjectedConversionValue获得AD值,也可以直接读取JDRx来获得,就是无法通过DMA来读取
问问各位帅哥,这是为什么?
程序如下(gpio没有用到)
#include "stm32f10x.h" // Device header
#include <Delay.h>
#include <OLED.h>
uint16_t a=0;
int main(void)
{
uint16_t AD_Value[2] = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitTypeDef gpioa0_1;
gpioa0_1.GPIO_Mode = GPIO_Mode_AIN;
gpioa0_1.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
gpioa0_1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpioa0_1); //没有用到
TIM_TimeBaseInitTypeDef tim2init;//名字懒得改
tim2init.TIM_ClockDivision = TIM_CKD_DIV1;
tim2init.TIM_CounterMode = TIM_CounterMode_Up;
tim2init.TIM_Period = 10000-1; //周期
tim2init.TIM_Prescaler = 7200-1; //分频 1s
tim2init.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&tim2init);
TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef nvictim3init;//名字懒得改
nvictim3init.NVIC_IRQChannel = TIM1_UP_IRQn;
nvictim3init.NVIC_IRQChannelCmd = ENABLE;
nvictim3init.NVIC_IRQChannelPreemptionPriority = 2;
nvictim3init.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvictim3init);
ADC_InitTypeDef adc0_1;//名字懒得改
adc0_1.ADC_ContinuousConvMode = DISABLE;
adc0_1.ADC_DataAlign = ADC_DataAlign_Right;
adc0_1.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc0_1.ADC_Mode = ADC_Mode_Independent;
adc0_1.ADC_NbrOfChannel = 1;
adc0_1.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1,&adc0_1);
//开启内部参考
ADC_TempSensorVrefintCmd(ENABLE);
//不使用,但是需要有
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
//使用注入组
ADC_InjectedSequencerLengthConfig (ADC1,2); //通道数量
//通道配置
ADC_InjectedChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5);
ADC_InjectedChannelConfig(ADC1,ADC_Channel_17,2,ADC_SampleTime_239Cycles5);
//开启注入组TIM1UP触发
ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_T1_TRGO);
//DMA部分
DMA_InitTypeDef dmaadc0_1;
dmaadc0_1.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->JDR1;
dmaadc0_1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dmaadc0_1.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//注入组4通道自增
dmaadc0_1.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
dmaadc0_1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dmaadc0_1.DMA_MemoryInc = DMA_MemoryInc_Enable;
dmaadc0_1.DMA_DIR = DMA_DIR_PeripheralSRC;
dmaadc0_1.DMA_BufferSize = 2;
dmaadc0_1.DMA_Mode = DMA_Mode_Circular;
dmaadc0_1.DMA_M2M = DMA_M2M_Disable;
dmaadc0_1.DMA_Priority = DMA_Priority_Medium;
DMA_Init(DMA1_Channel1,&dmaadc0_1);
TIM_ClearFlag(TIM1, TIM_IT_Update);
TIM_Cmd(TIM1,ENABLE);
DMA_Cmd(DMA1_Channel1,ENABLE);
//使能外部触发
ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == SET);
OLED_Init();
OLED_Clear();
uint16_t GET_VBUS,GET_TEMP;
while(1)
{
//AD_Value[0] = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
//AD_Value[1] = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
GET_VBUS = (uint16_t)(4945449/AD_Value[1]);
GET_TEMP = (float)((1.43f-(((GET_VBUS*0.001f)/4095.0f)*AD_Value[0]))/0.0043f)+25.0f;
OLED_ShowNum(1,1,GET_TEMP,4);
OLED_ShowNum(2,1,GET_VBUS,4);
OLED_ShowNum(3,1,a,4);
}
}
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
a++;
}
}
问问各位帅哥,这是为什么?
程序如下(gpio没有用到)
#include "stm32f10x.h" // Device header
#include <Delay.h>
#include <OLED.h>
uint16_t a=0;
int main(void)
{
uint16_t AD_Value[2] = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitTypeDef gpioa0_1;
gpioa0_1.GPIO_Mode = GPIO_Mode_AIN;
gpioa0_1.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
gpioa0_1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpioa0_1); //没有用到
TIM_TimeBaseInitTypeDef tim2init;//名字懒得改
tim2init.TIM_ClockDivision = TIM_CKD_DIV1;
tim2init.TIM_CounterMode = TIM_CounterMode_Up;
tim2init.TIM_Period = 10000-1; //周期
tim2init.TIM_Prescaler = 7200-1; //分频 1s
tim2init.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&tim2init);
TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef nvictim3init;//名字懒得改
nvictim3init.NVIC_IRQChannel = TIM1_UP_IRQn;
nvictim3init.NVIC_IRQChannelCmd = ENABLE;
nvictim3init.NVIC_IRQChannelPreemptionPriority = 2;
nvictim3init.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvictim3init);
ADC_InitTypeDef adc0_1;//名字懒得改
adc0_1.ADC_ContinuousConvMode = DISABLE;
adc0_1.ADC_DataAlign = ADC_DataAlign_Right;
adc0_1.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc0_1.ADC_Mode = ADC_Mode_Independent;
adc0_1.ADC_NbrOfChannel = 1;
adc0_1.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1,&adc0_1);
//开启内部参考
ADC_TempSensorVrefintCmd(ENABLE);
//不使用,但是需要有
ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_239Cycles5);
//使用注入组
ADC_InjectedSequencerLengthConfig (ADC1,2); //通道数量
//通道配置
ADC_InjectedChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5);
ADC_InjectedChannelConfig(ADC1,ADC_Channel_17,2,ADC_SampleTime_239Cycles5);
//开启注入组TIM1UP触发
ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_T1_TRGO);
//DMA部分
DMA_InitTypeDef dmaadc0_1;
dmaadc0_1.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->JDR1;
dmaadc0_1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dmaadc0_1.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//注入组4通道自增
dmaadc0_1.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
dmaadc0_1.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dmaadc0_1.DMA_MemoryInc = DMA_MemoryInc_Enable;
dmaadc0_1.DMA_DIR = DMA_DIR_PeripheralSRC;
dmaadc0_1.DMA_BufferSize = 2;
dmaadc0_1.DMA_Mode = DMA_Mode_Circular;
dmaadc0_1.DMA_M2M = DMA_M2M_Disable;
dmaadc0_1.DMA_Priority = DMA_Priority_Medium;
DMA_Init(DMA1_Channel1,&dmaadc0_1);
TIM_ClearFlag(TIM1, TIM_IT_Update);
TIM_Cmd(TIM1,ENABLE);
DMA_Cmd(DMA1_Channel1,ENABLE);
//使能外部触发
ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1) == SET);
OLED_Init();
OLED_Clear();
uint16_t GET_VBUS,GET_TEMP;
while(1)
{
//AD_Value[0] = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
//AD_Value[1] = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
GET_VBUS = (uint16_t)(4945449/AD_Value[1]);
GET_TEMP = (float)((1.43f-(((GET_VBUS*0.001f)/4095.0f)*AD_Value[0]))/0.0043f)+25.0f;
OLED_ShowNum(1,1,GET_TEMP,4);
OLED_ShowNum(2,1,GET_VBUS,4);
OLED_ShowNum(3,1,a,4);
}
}
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
a++;
}
}
赞0
评论
2024-12-29
赞0
1.png (54.97 KB )
下载附件
2024-12-29 17:23 上传
2.png (60.47 KB )
下载附件
2024-12-29 17:23 上传
评论
2024-12-29
赞0
但是 开启连续ADC的规则组也会运行
主要是TIM1的TRGO没办法触发ADC规则组
没有办法只使用注入组+DMA吗?
评论
2024-12-28
您需要登录后才可以回复 登录 | 注册