Using ADC interrupts in RTOS environment. This program also demonstrates the usage of RTOS API function calls from interrupt.

Dependencies:   mbed mbed-rtos

main.cpp

Committer:
cspista
Date:
2022-04-10
Revision:
0:b6055a7af0c9

File content as of revision 0:b6055a7af0c9:

#include "mbed.h"
#include "rtos.h"
AnalogIn adc(A4);
DigitalOut led1(LED1);

typedef uint32_t message_t;
Queue <message_t, 4> queue;

void led1_thread(void const *args)
{
    while (true) {
        led1 = !led1;
        Thread::wait(1000);
    }
}

//--- ADC Interrupt handler -----------------
extern "C" void ADC1_IRQHandler()
{
    NVIC_ClearPendingIRQ(ADC_IRQn);             //Clear ADC Interrupt Request Flag
    uint16_t raw = ADC1->DR;
    queue.put((message_t*)raw);                 //Send result through a Queue
}

//--- Start conversion, wait for result -----
uint16_t adc_read(uint32_t ch)
{
    ADC1->SQR3 = ch;                              //set conversion channel
    ADC1->SMPR2 = 7;                              //Sample time =480
    ADC1->CR1 |= ADC_CR1_EOCIE;                   //enable interrupt
    ADC1->CR2 |= ADC_CR2_SWSTART;                 //Start conversion
    osEvent evt = queue.get();                    //Wait for a message
    return (uint16_t)evt.value.v;                 //Return obtained value
}

int main()
{
    int32_t v25 = 760;                            //Voltage at 25C (in millivolts)
    float m = 2.5;                                //Slope  mV per degree)
    uint16_t dummy = adc.read();                  //needed for ADC configuration
    ADC123_COMMON->CCR |= ADC_CCR_TSVREFE;        //Enable inner channels
    NVIC_SetVector(ADC_IRQn,(uint32_t)&ADC1_IRQHandler); //Attach ADC ISR
    NVIC_EnableIRQ(ADC_IRQn);                     //Enable ADC interrupts
    Thread thread1(led1_thread);
    printf("\r\n Lab09 ADC interrupt in RTOS environment\r\n");
    while(true) {
        uint32_t a1 = 0;
        uint32_t a2 = 0;
        for(int i=0; i<3300; i++) {
            a1 += adc_read(11);                    //Measure voltage at A4 (PTC_1)
            a2 += adc_read(18);                    //Internal temperature sensor
        }
        float v1 = a1/4096.0f;                     //Convert v1 to millivolts
        float temp1 = (v1-500)/10.0;               //MCP9700 temperature in Celsius
        float v2 = a2/4096.0f;                     //Convert v2 to millivolts
        float temp2 = 25.0f+(v2-v25)/m;            //Calculate temp in Celsius
        printf("A4 = %.0f mV  Temp = %.1f C  Inner Ts: %.0f mV  Temp = %.1f C\r\n",v1,temp1,v2,temp2);
        Thread::wait(2000);
    }

}