En primer lugar, el semáforo se puede dar en "ADC_IRQHandler ()" o "HAL_ADC_ConvCpltCallback ()" (ADC) agregando:
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
Al final de la función, parece que "HAL_ADC_ConvCpltCallback" también es un ISR cuando uso xSemaphoreGive( xBinarySemaphore);
. Con ello se bloquea el programa.
También es importante establecer la prioridad de IRQHandler numéricamente más alta que configMAX_SYSCALL_INTERRUPT_PRIORITY, en mi caso '80', agregando (5 por ejemplo). HAL_NVIC_SetPriority(ADC_IRQn, 5, 0);
, prioridad 5? 15 en mi caso. Puede consultar esto para obtener más información: enlace .
De todos modos, este código funciona y toma el inicio de ADC de enlace .
Código
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
SemaphoreHandle_t xBinarySemaphore=NULL;
ADC_HandleTypeDef g_AdcHandle;
uint32_t g_ADCValue=0;
void SystemClock_Config(void);
void ConfigureADC();
static void ledL( void*); // Task to change the brightness of the LED 12 of GPIOD when changing the value of potentiometer
static void vHandlerTask( void*); // Task to toggle GPIOD 13 every time a conversion is achieved and sleep for 300 ms
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef*);
void ADC_IRQHandler();
int main(void){
HAL_Init();
SystemClock_Config();
ConfigureADC();
HAL_NVIC_SetPriority(ADC_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
GPIO_InitTypeDef GPIO_InitStructure;
__GPIOD_CLK_ENABLE();
GPIO_InitStructure.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
vSemaphoreCreateBinary(xBinarySemaphore);
if( xBinarySemaphore != NULL ){
xTaskCreate(vHandlerTask, "Task 1", 1000, NULL, 1, NULL);
xTaskCreate(ledL, "Task 2", 1000, NULL, 1, NULL);
vTaskStartScheduler();
}
for(;;){}
}
//ISR
void ADC_IRQHandler(){
HAL_ADC_IRQHandler(&g_AdcHandle);
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
//CALLBACK CALLED WHEN CONVERTION COMPLETE
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle){
g_ADCValue = HAL_ADC_GetValue(AdcHandle);
}
static void vHandlerTask( void *pvParameters ){
HAL_ADC_Start_IT(&g_AdcHandle);
for( ;; ){
xSemaphoreTake( xBinarySemaphore, portMAX_DELAY );
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);
vTaskDelay(pdMS_TO_TICKS(200UL));
}
}
static void ledL( void *pvParameters ){
for (;;)
{
int onTime = g_ADCValue;
int offTime = 4096 - onTime;
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
for (int i = 0; i < onTime; i++)
asm("nop");
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
for (int i = 0; i < offTime; i++)
asm("nop");
}
}
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 288;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 6;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
SystemCoreClockUpdate();
if (HAL_GetREVID() == 0x1001)
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
}
void ConfigureADC()
{
GPIO_InitTypeDef gpioInit;
__GPIOC_CLK_ENABLE();
__ADC1_CLK_ENABLE();
gpioInit.Pin = GPIO_PIN_1;
gpioInit.Mode = GPIO_MODE_ANALOG;
gpioInit.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &gpioInit);
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
ADC_ChannelConfTypeDef adcChannel;
g_AdcHandle.Instance = ADC1;
g_AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
g_AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
g_AdcHandle.Init.ScanConvMode = DISABLE;
g_AdcHandle.Init.ContinuousConvMode = ENABLE;
g_AdcHandle.Init.DiscontinuousConvMode = DISABLE;
g_AdcHandle.Init.NbrOfDiscConversion = 0;
g_AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
g_AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
g_AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
g_AdcHandle.Init.NbrOfConversion = 1;
g_AdcHandle.Init.DMAContinuousRequests = ENABLE;
g_AdcHandle.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&g_AdcHandle);
adcChannel.Channel = ADC_CHANNEL_11;
adcChannel.Rank = 1;
adcChannel.SamplingTime = ADC_SAMPLETIME_480CYCLES;
adcChannel.Offset = 0;
if (HAL_ADC_ConfigChannel(&g_AdcHandle, &adcChannel) != HAL_OK)
{
asm("bkpt 255");
}
}