本帖最后由 iken 于 2013-12-5 16:50 编辑
我也遇到SDADC+DMA的问题,没有产生DMA中断,各使能条件都满足,不确定其它配置是否有问题。
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
RCC_ClocksTypeDef RCC_Clocks;
__IO float InputVoltageMv = 0;
uint32_t ChannelIndex;
/* SysTick end of count event each 1ms */
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
UART_Init();
/* Configure DMA2 to transfer data from SDADC data register to embedded SRAM */
DMA2_Config();
/* POT_SDADC channel5P (in Single Ended Zero Reference mode) configuration using
injected conversion with continuous mode enabled */
SDADC1_Config();
/* Configure TIM3 as trigger for SDADC conversion */
TIM13_Config();
TIM_Cmd(TIM13, ENABLE);
/* Infinite loop */
while (1)
{
if(aa==1)
{
aa=0;
InputVoltageMv = (((InjectedConvData + 32768) * SDADC_VREF) / (SDADC_GAIN * SDADC_RESOL));
/* write result to LCD */
sprintf(LCDstr, " RV3 = %2.2f mV ", InputVoltageMv);
printf("\n\r Pot (RV3) = %2.2f mV \n\r",InputVoltageMv);
LCD_DisplayStringLine(LCD_LINE_5, (uint8_t*)LCDstr);
DMA_ClearFlag(DMA2_FLAG_GL3);
}
}
}
static void DMA2_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA2 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
/* Config the DMA2 channel 3 */
DMA_DeInit(DMA2_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = SDADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)InjectedConvData;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
/* Enable DMA2 Channel3 Transfer half and Complete interrupt */
DMA_ITConfig(DMA2_Channel3, DMA_IT_TC | DMA_IT_HT, ENABLE);
/* Enable DMA2 Channel3 */
DMA_Cmd(DMA2_Channel3, ENABLE);
}
/**
* @brief Configure POT_SDADC channel 5P in Single Ended Zero Reference mode using
* injected conversion with continuous mode enabled.
* @param None
* @retval 0: SDADC Configured successfully
* 1: INITRDY flag is not set, check the SDVDDA and SDVREF
* 2: EOCAL flag is not set
*/
static uint32_t SDADC1_Config(void)
{
SDADC_AINStructTypeDef SDADC_AINStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
uint32_t SDADCTimeout = 0;
/* POT_SDADC APB2 interface clock enable */
RCC_APB2PeriphClockCmd(POT_SDADC_CLK, ENABLE);
/* PWR APB1 interface clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Enable POT_SDADC analog interface */
PWR_SDADCAnalogCmd(POT_SDADC_PWR, ENABLE);
/* Set the SDADC divider: The SDADC should run @6MHz */
/* If Sysclk is 72MHz, SDADC divider should be 12 */
RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div48);
/* POT_GPIO_CLK Peripheral clock enable */
RCC_AHBPeriphClockCmd(POT_GPIO_CLK, ENABLE);
/* POT_SDADC channel 5P (PB1) */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = POT_GPIO_PIN;
GPIO_Init(POT_GPIO_PORT, &GPIO_InitStructure);
/* Select External reference: The reference voltage selection is available
only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1
clock must be already enabled */
SDADC_VREFSelect(POT_SDADC_VREF);
/* Insert delay equal to ~5 ms */
Delay(5);
/* Enable POT_SDADC */
SDADC_Cmd(POT_SDADC, ENABLE);
/* Enter initialization mode */
SDADC_InitModeCmd(POT_SDADC, ENABLE);
SDADCTimeout = SDADC_INIT_TIMEOUT;
/* wait for INITRDY flag to be set */
while((SDADC_GetFlagStatus(POT_SDADC, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));
if(SDADCTimeout == 0)
{
/* INITRDY flag can not set */
return 1;
}
/* Analog Input configuration conf0: use single ended zero reference */
SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEZeroReference;
SDADC_AINStructure.SDADC_Gain = POT_SDADC_GAIN;
SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
SDADC_AINStructure.SDADC_Offset = 0;
SDADC_AINInit(POT_SDADC, SDADC_Conf_0, &SDADC_AINStructure);
/* Enable DMA transfer for injected conversions */
SDADC_DMAConfig(POT_SDADC, SDADC_DMATransfer_Injected,ENABLE);
/* select POT_SDADC channel 5 to use conf0 */
SDADC_ChannelConfig(POT_SDADC, POT_SDADC_CHANNEL, SDADC_Conf_0);
//SDADC_ChannelSelect(POT_SDADC, POT_SDADC_CHANNEL);
//SDADC_ContinuousModeCmd(POT_SDADC, ENABLE);
/* select channel 5 */
SDADC_InjectedChannelSelect(POT_SDADC, POT_SDADC_CHANNEL);
/* Enable continuous mode */
// SDADC_InjectedContinuousModeCmd(POT_SDADC, ENABLE);
/* Select an external trigger */
SDADC_ExternalTrigInjectedConvConfig(POT_SDADC, SDADC_ExternalTrigInjecConv_T13_CC1);
/* Select rising edge */
SDADC_ExternalTrigInjectedConvEdgeConfig(POT_SDADC, SDADC_ExternalTrigInjecConvEdge_Rising);
/* Exit initialization mode */
SDADC_InitModeCmd(POT_SDADC, DISABLE);
/* configure calibration to be performed on conf0 */
SDADC_CalibrationSequenceConfig(POT_SDADC, SDADC_CalibrationSequence_1);
/* start POT_SDADC Calibration */
SDADC_StartCalibration(POT_SDADC);
/* Set calibration timeout: 5.12 ms at 6 MHz in a single calibration sequence */
SDADCTimeout = SDADC_CAL_TIMEOUT;
/* wait for POT_SDADC Calibration process to end */
while((SDADC_GetFlagStatus(POT_SDADC, SDADC_FLAG_EOCAL) == RESET) && (--SDADCTimeout != 0));
if(SDADCTimeout == 0)
{
/* EOCAL flag can not set */
return 2;
}
/* Enable end of injected conversion interrupt */
// SDADC_ITConfig(POT_SDADC, SDADC_IT_JEOC, ENABLE);
/* Start a software start conversion */
// SDADC_SoftwareStartInjectedConv(POT_SDADC);
// SDADC_SoftwareStartConv(POT_SDADC);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
return 0;
}
/**
* @brief Configure timer TIM3: It is used as trigger for SDADC conversion
* @param None
* @retval None
*/
static void TIM13_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM3 Interrupt for capture compare event */
NVIC_InitStructure.NVIC_IRQChannel = TIM13_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable TIM13 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13, ENABLE);
/* TIM3 Configuration */
TIM_DeInit(TIM13);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 900000;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM13, &TIM_TimeBaseStructure);
/* PWM Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 4500 ;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM13, &TIM_OCInitStructure);
}
中断程序:
void DMA2_Channel3_IRQHandler(void)
{
printf("\n\r Pot (RV3) = gsdfasfasdf mV 11\n\r");
aa=1;
/* Clear DMA2 flag */
DMA_ClearFlag(DMA2_FLAG_GL3);
}
|