原子哥,最近我在调SDADC与DMA通道的时候发现SDADC能和DMA建立数据传递联系。我的SDADC是由timer3进行触发的。我在DMA接受数组中可以明显地看到ADC的数据在发往DMA。但是奇怪的是主函数为什么不跑啊。照理来说DMA数据通道与CPU是独立分开。我在主函数中用了系统delay延时的LED。正常现象是LED灯会定时翻转,但是主函数就是不能跑。我在开启普通的12位ADC时,用这种方法能跑。但是用SDADC酒不能。希望各位大牛能够指点一二,小弟在此感激不尽。
我的芯片是STM32F373
我的程序是
[mw_shl_code=c,true]#define SDADC1_DR_Address ((uint32_t)0x40016060)
#define ECG_BUFF_SIZE (uint32_t)960
uint32_t TimingDelay = 0;
int16_t ECG_Buff[ECG_BUFF_SIZE];
static void SDADC_Config(void)
{
SDADC_AINStructTypeDef SDADC_AINStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOE Peripheral clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
/* ECG_SDADC channel pin configuration: PE12 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* ECG_SDADC APB2 interface clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDADC1, ENABLE);
/* PWR APB1 interface clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
/* Enable ECG_SDADC analog interface */
PWR_SDADCAnalogCmd(PWR_SDADCAnalog_1, ENABLE);
/* Set the SDADC divider: The SDADC should run @6MHz */
/* If Sysclk is 72MHz, SDADC divider should be 12 */
RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div12);
/* 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(SDADC_VREF_Ext);
/* Insert delay equal to ~10 ms (4 ms required) */
DDelay(5);
/* Enable ECGSDADC */
SDADC_Cmd(SDADC1, ENABLE);
/* Enter initialization mode */
SDADC_InitModeCmd(SDADC1, ENABLE);
/* wait for INITRDY flag to be set */
while(SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_INITRDY) == RESET);
SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEZeroReference;
SDADC_AINStructure.SDADC_Gain = SDADC_Gain_1;
SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
SDADC_AINStructure.SDADC_Offset = 0;
SDADC_AINInit(SDADC1, SDADC_Conf_0, &SDADC_AINStructure);
/* Enable DMA transfer for injected conversions */
SDADC_DMAConfig(SDADC1, SDADC_DMATransfer_Injected, ENABLE);
/* select ECG_SDADC channel to use conf0 */
SDADC_ChannelConfig(SDADC1, SDADC_Channel_3, SDADC_Conf_0);
/* select SDADC Channel */
SDADC_InjectedChannelSelect(SDADC1, SDADC_Channel_3);
/* Select an external trigger */
SDADC_ExternalTrigInjectedConvConfig(SDADC1, SDADC_ExternalTrigInjecConv_T3_CC1);
/* Select rising edge */
SDADC_ExternalTrigInjectedConvEdgeConfig(SDADC1, SDADC_ExternalTrigInjecConvEdge_Rising);
/* Exit initialization mode */
SDADC_InitModeCmd(SDADC1, DISABLE);
/* configure calibration to be performed on conf0 */
SDADC_CalibrationSequenceConfig(SDADC1, SDADC_CalibrationSequence_1);
/* start ECG_SDADC Calibration */
SDADC_StartCalibration(SDADC1);
/* wait for ECG_SDADC Calibration process to end */
while(SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_EOCAL) == RESET);
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);
}
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)&ECG_Buff[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ECG_BUFF_SIZE;
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_Low;
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);
}
static void TIM3_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Enable TIM3 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Prescaler = 12;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/480/13;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Channel1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = SystemCoreClock/480/26;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
/* TIM3 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
int main()
{
RCC_ClocksTypeDef RCC_Clocks;
NVIC_InitTypeDef NVIC_InitStructure;
/* SysTick end of count event each 1ms */
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);
GPIO_Config();
LCD_Init();
LCD_Clear(Red);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
LCD_DisplayStringLine(0, "AD TEST: ");
//ADC_Config();
DAC_Config();
//TIM_Config();//must set befor initing LCD, for the interrupt fuction will affect initing LCD .
//TIM_INIT(); //must be after TIM_Config()
DMA2_Config();
/* Confifgure SDADC to convert ECG voltage applied on PE7 */
SDADC_Config();
/* Configure TIM3 as trigger for SDADC conversion */
TIM3_Config();
GPIO_SetBits(GPIOC, GPIO_Pin_12|GPIO_Pin_11|GPIO_Pin_10);
while(1)
{ DDelay(200);
/* Test DMA1 TC flag */
while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET );
GPIOC->ODR ^= GPIO_Pin_11;
/* Clear DMA TC flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
//RegularConvData[0]=ADC_GetConversionValue(ADC1);
DAC_SetChannel2Data(DAC1, DAC_Align_12b_R, ECG_Buff[0]);
LCD_ShowNum(100,50,ECG_Buff[0]);
//out the DA value which is the AD value
}
}
[/mw_shl_code]
|