This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

ADC_IRQHandler specific calling

Hi, I am new to nordic n51822, i have implemented adc and timer independently. Now, what i want to do is read the adc values on a specific time when the timer overflows for 500ms. I am little confused that void ADC_IRQHandler(void) continually polls and reads the value and displays the value on UART. Can anyone guide me through the steps on how to read adc with specific time, like when enabling timing interrupt timer starts and reads value and every time when the value is read , the interrupt is stopped and values are processed then again the interrupt is activated and timer is started. What i want is to create a specific sample rate in which it reads adc,process values,print and repeat.

    #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */

   #define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */ 
  #define GPIO_TOGGLE_PIN 4 /*!< gpio pin to toggle after delay. */ 
 #ifndef NRF_APP_PRIORITY_HIGH #define NRF_APP_PRIORITY_HIGH 1
  #endif

/** @TIMER2
* 
*
*/

void start_timer(void)
{		
  NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;  // Set the timer in Counter Mode
  NRF_TIMER2->TASKS_CLEAR = 1;               // clear the task first to be usable for later
	NRF_TIMER2->PRESCALER = 8;                             //Set prescaler. Higher number gives slower timer. Prescaler = 0 gives 16MHz timer
	NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;		 //Set counter to 16 bit resolution
	NRF_TIMER2->CC[0] = 31250;                             //Set value for TIMER2 compare register 0
		
  // Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events
	NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos)	;
	//| (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
  NVIC_EnableIRQ(TIMER2_IRQn);
	NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos) & TIMER_SHORTS_COMPARE0_CLEAR_Msk;	
  NRF_TIMER2->TASKS_START = 1;               // Start TIMER2
}
		
/** TIMTER2 peripheral interrupt handler. This interrupt handler is called whenever there it a TIMER2 interrupt
 */
void TIMER2_IRQHandler(void)
{
	if(NRF_TIMER2->EVENTS_COMPARE[0])
    {
				NRF_TIMER2->EVENTS_COMPARE[0] = 0;           //Clear compare register 0 event	
	    	nrf_gpio_pin_toggle(GPIO_TOGGLE_PIN);
 
    }
}


/**
 * @brief UART events handler.
 */
void uart_events_handler(app_uart_evt_t * p_event)
{
    switch (p_event->evt_type)
    {
        case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication);
            break;

        case APP_UART_FIFO_ERROR:          APP_ERROR_HANDLER(p_event->data.error_code);
            break;

        case APP_UART_TX_EMPTY:            printf("RESULT= %1.1f\r\n", (float)adc_sample); // out ADC result
            break;

        default: break;
    }
}


/**
 * @brief ADC interrupt handler.
 */
void ADC_IRQHandler(void)
{
    nrf_adc_conversion_event_clean();

    adc_sample = nrf_adc_result_get();

    // trigger next ADC conversion
    nrf_adc_start();
}


/**
 * @brief UART initialization.
 */
void uart_config(void)
{
    uint32_t                     err_code;
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud38400
    };

    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_events_handler,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);

    APP_ERROR_CHECK(err_code);
}


/**
 * @brief ADC initialization.
 
 */
void adc_config(void)
{
    const nrf_adc_config_t nrf_adc_config = NRF_ADC_CONFIG_DEFAULT;

    // Initialize and configure ADC
    nrf_adc_configure( (nrf_adc_config_t *)&nrf_adc_config);
    nrf_adc_input_select(NRF_ADC_CONFIG_INPUT_7);
    nrf_adc_int_enable(ADC_INTENSET_END_Enabled << ADC_INTENSET_END_Pos);
		//ADC INTERRUPT ENABLE
    NVIC_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);
    NVIC_EnableIRQ(ADC_IRQn);
}

/*void adc_init(void)
{
 const nrf_adc_config_t nrf_adc_config = NRF_ADC_CONFIG_DEFAULT;

	// Enable interrupt on ADC sample ready event	
	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
	sd_nvic_EnableIRQ(ADC_IRQn);
	

}
*/

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    adc_config();
		//adc_init();
    uart_config();

    printf("\n\rADC HAL simple example\r\n");

    printf("Current sample value:\r\n");

    nrf_adc_start();

    while (true)
    {
        // enter into sleep mode
        __WFI();	//WAIT FOR INTERRUPT
			  //__SEV();
        //__WFE();
        //__WFE();
    }
}
Parents
  • Thanks for the detailed explanation Stefan. It has cleared many confusions. Currently, I am using internal 16MHz RC as a clock source, so can I use it with enabling PPI channel? I have tried the following

    static void ppi_init(void)
    

    { // Configure PPI channel 0 to start ADC task NRF_PPI->CH[0].EEP = (uint32_t)NRF_TIMER2->EVENTS_COMPARE[0]; NRF_PPI->CH[0].TEP = (uint32_t)&NRF_ADC->TASKS_START;

    // Enable PPI channel 0 NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos); }

    HERE IS THE TIMER2 CONFIGURATION**********

    void start_timer(void)
    

    { NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Counter Mode NRF_TIMER2->TASKS_CLEAR = 1; // clear the task first to be usable for later NRF_TIMER2->PRESCALER = 8; //Set prescaler. Higher number gives slower timer. Prescaler = 0 gives 16MHz timer NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution NRF_TIMER2->CC[0] = 31250; //Set value for TIMER2 compare register 0

    // Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) ; //| (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos); NVIC_EnableIRQ(TIMER2_IRQn); //NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos) & TIMER_SHORTS_COMPARE0_CLEAR_Msk; NRF_TIMER2->TASKS_START = 1; // Start TIMER2 }

    Have I enabled the PPI correctly ? As it doesn't seem to work not printing anything on UART

Reply
  • Thanks for the detailed explanation Stefan. It has cleared many confusions. Currently, I am using internal 16MHz RC as a clock source, so can I use it with enabling PPI channel? I have tried the following

    static void ppi_init(void)
    

    { // Configure PPI channel 0 to start ADC task NRF_PPI->CH[0].EEP = (uint32_t)NRF_TIMER2->EVENTS_COMPARE[0]; NRF_PPI->CH[0].TEP = (uint32_t)&NRF_ADC->TASKS_START;

    // Enable PPI channel 0 NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos); }

    HERE IS THE TIMER2 CONFIGURATION**********

    void start_timer(void)
    

    { NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; // Set the timer in Counter Mode NRF_TIMER2->TASKS_CLEAR = 1; // clear the task first to be usable for later NRF_TIMER2->PRESCALER = 8; //Set prescaler. Higher number gives slower timer. Prescaler = 0 gives 16MHz timer NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit; //Set counter to 16 bit resolution NRF_TIMER2->CC[0] = 31250; //Set value for TIMER2 compare register 0

    // Enable interrupt on Timer 2, both for CC[0] and CC[1] compare match events NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos) ; //| (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos); NVIC_EnableIRQ(TIMER2_IRQn); //NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos) & TIMER_SHORTS_COMPARE0_CLEAR_Msk; NRF_TIMER2->TASKS_START = 1; // Start TIMER2 }

    Have I enabled the PPI correctly ? As it doesn't seem to work not printing anything on UART

Children
No Data
Related