acvarif 0 6 февраля, 2012 Опубликовано 6 февраля, 2012 · Жалоба Пытаюсь настроить ADC1 stm32f217 для работы по прерываниям (по окончании цикла преобразования). void ADC_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable ADC1, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* DMA2 Stream0 channel2 configuration **************************************/ DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 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_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_Cmd(DMA2_Stream0, ENABLE); /* Configure ADC1 Channel4 pin as analog input ******************************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* ADC Common Init **********************************************************/ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); /* ADC1 Init ****************************************************************/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // Режим сканирования ADC_InitStructure.ADC_ScanConvMode = DISABLE; // Непрерывное преобразование ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); /* Enable and set the ADC interrupt to the highest priority */ NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* ADC1 regular channel4 configuration *************************************/ ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_112Cycles); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Enable ADC3 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC3 */ ADC_Cmd(ADC1, ENABLE); } В прерываниях пока просто переключаю светодиод (для визуализации прерываний) void ADC_IRQHandler(void) { STM_EVAL_LEDToggle(LED2); /* Clear the interrupt flag. */ ADC_ClearFlag(ADC1, ADC_FLAG_EOC); } Не работает. Правда в инициализации задействовано DMA (в DMA данные попадают как положено - успешно выводятся на COM1). Но одно другого (DMA и прерывания по окончанию преобразования) вроде не должно касаться. Гляньте код кому не лень. Может чего напутано в инициализации прерываний или в самоой void ADC_IRQHandler. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Galizin 0 6 февраля, 2012 Опубликовано 6 февраля, 2012 · Жалоба Не работает. Правда в инициализации задействовано DMA (в DMA данные попадают как положено - успешно выводятся на COM1). Но одно другого (DMA и прерывания по окончанию преобразования) вроде не должно касаться. Гляньте код кому не лень. Может чего напутано в инициализации прерываний или в самоой void ADC_IRQHandler. EOCIE в регистре ADC_CR1 ? Или что то типа ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE) согласно Вашему стилю? Правда это все для 1 серии. Но для второй наверняка так же. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
acvarif 0 6 февраля, 2012 Опубликовано 6 февраля, 2012 · Жалоба Ошибочка блин. Не хватает. /* Enable ADC1 Interrupt */ ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); Прерывания заработали но появилась проблема с семафором FReeRTOS void ADC_IRQHandler(void) { STM_EVAL_LEDOn(LED2); portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; /* ADC1 received */ if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET) { /* Give the semaphore to wakeup ADC task */ xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken ); } /* Clear the interrupt flag. */ ADC_ClearFlag(ADC1, ADC_FLAG_EOC); /* Switch tasks if necessary. */ if( xHigherPriorityTaskWoken != pdFALSE ) { portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); } } Не срабатывает он здесь ..... for(;; ) { if (xSemaphoreTake( s_xSemaphore, portMAX_DELAY )==pdTRUE) { text[1] = ADC1ConvertedValue; text[0] = ADC1ConvertedValue >> 8; netbuf_ref(buf1, text, sizeof(text)); netconn_send(connn, buf1); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться