本帖最后由 nnqtdf 于 2022-11-19 15:38 编辑
#define ADC1_DR_Address ((uint32_t)0x40012400+0x4c) /* ADC1数据寄存器地址(ADC基地址+偏移) */
__IO uint16_t ADC_ConvertedValue[ADC_CH_SIZE];
extern SemaphoreHandle_t adc1_dma_Semaphore; //二值信号量句柄
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] DMA Init
*
* @param None
*
* @retval None
*/
void ADC_DMA_Config(void)
{
/** DMA Configure */
DMA_Config_T dmaConfig;
/** Enable DMA clock */
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
DMA_Disable(DMA1_Channel1);//关DMA通道
DMA_Reset(DMA1_Channel1);//恢复缺省值
/** size of buffer*/
dmaConfig.bufferSize = ADC_CH_SIZE;
/** set memory Data Size*/
dmaConfig.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;
/** Set peripheral Data Size*/
dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;
/** Enable Memory Address increase*/
dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;
/** Disable Peripheral Address increase*/
dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
/** Reset Circular Mode*/
dmaConfig.loopMode = DMA_MODE_NORMAL;
/** set priority*/
dmaConfig.priority = DMA_PRIORITY_HIGH;
/** read from peripheral*/
dmaConfig.dir = DMA_DIR_PERIPHERAL_SRC;
/** Set memory Address*/
dmaConfig.memoryBaseAddr = (uint32_t)ADC_ConvertedValue;
/** Set Peripheral Address*/
dmaConfig.peripheralBaseAddr = ADC1_DR_Address;
dmaConfig.M2M = DMA_M2MEN_DISABLE;
DMA_Config(DMA1_Channel1, &dmaConfig);
NVIC_EnableIRQRequest(DMA1_Channel1_IRQn, 4, 0);
DMA_ClearStatusFlag(DMA1_FLAG_TC1);
DMA_EnableInterrupt(DMA1_Channel1, DMA_INT_TC);
DMA_Enable(DMA1_Channel1);
}
/*
这里默认APB2的CLK PCLK2为60MHz。那么当设置ADC分辨率为12bits,ADCCLK = PCLK2 / 2 = 30MHz时。结合前述“转换时间”章节中讲到的计算方式,可以得知单次
ADC转换时间 = 采样周期 + 转换周期
= 3 x ADCCLK + 12 x ADCCLK
= 15 ADC CLK
= 15 / 30MHz
= 0.5 us
每次ADC转换间隔为20 x ADCCLK。
*/
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] ADC Init
*
* @param None
*
* @retval None
*/
void ADC_ADC_Config(void)
{
GPIO_Config_T gpioConfig;
ADC_Config_T ADC_configStruct;
/** RCM Enable*/
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOC);
RCM_ConfigADCCLK(RCM_PCLK2_DIV_6);
/** GPIO Configuration */
GPIO_ConfigStructInit(&gpioConfig);
gpioConfig.pin = GPIO_PIN_1;
gpioConfig.mode = GPIO_MODE_ANALOG;
GPIO_Config(GPIOA, &gpioConfig);
gpioConfig.pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
gpioConfig.mode = GPIO_MODE_ANALOG;
GPIO_Config(GPIOC, &gpioConfig);
ADC_Reset(ADC1);
ADC_EnableTempSensorVrefint(ADC1);//开启内部温度传感器
/* ADC1 Configuration */
ADC_configStruct.mode = ADC_MODE_INDEPENDENT;
ADC_configStruct.scanConvMode = ENABLE;
ADC_configStruct.continuosConvMode = DISABLE;
ADC_configStruct.externalTrigConv = ADC_EXT_TRIG_CONV_None;
ADC_configStruct.dataAlign = ADC_DATA_ALIGN_RIGHT;
ADC_configStruct.nbrOfChannel = ADC_CH_SIZE;
ADC_Config(ADC1, &ADC_configStruct);
ADC_EnableAutoInjectedConv(ADC1);
/* ADC1 regular channel14 configuration */
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_10, 1, ADC_SAMPLETIME_239CYCLES5);//
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_11, 2, ADC_SAMPLETIME_239CYCLES5);//
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_12, 3, ADC_SAMPLETIME_239CYCLES5);//
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_13, 4, ADC_SAMPLETIME_239CYCLES5);//
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_1, 5, ADC_SAMPLETIME_239CYCLES5);//
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_16, 6, ADC_SAMPLETIME_239CYCLES5);//
ADC_EnableDMA(ADC1);
/* Enable ADC1 */
ADC_Enable(ADC1);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_ReadResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_ReadCalibrationStartFlag(ADC1));
ADC_EnableSoftwareStartConv(ADC1); /* 启动ADC1转换 */
}
void DMA1_Channel1_IRQHandler(void)// 使用DMA中断采集数据,不会容易丢失数据
{
BaseType_t xHigherPriorityTaskWoken;
printf("DMA1_Channel1_IRQHandler!\r\n");
if(DMA_ReadIntFlag(DMA1_INT_FLAG_TC1)!=RESET)
{
DMA_ClearIntFlag(DMA1_INT_FLAG_TC1);
DMA_Disable(DMA1_Channel1);
if(adc1_dma_Semaphore!=NULL)//二值信号量有效,在这里向ADC计算任务释放二值信号量
{
xSemaphoreGiveFromISR(adc1_dma_Semaphore,&xHigherPriorityTaskWoken); //释放二值信号量
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换
}
}
}
/*启动ADC转换*/
void ADC_Start(void)
{
DMA_Enable(DMA1_Channel1);
/* Start ADC1 Software Conversion */
ADC_EnableSoftwareStartConv(ADC1);
}
/*ADc初始化*/
void ADC_init(void)
{
ADC_DMA_Config();
ADC_ADC_Config();
}
这段代码,进不去dma中断,请问是哪里问题?
|