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

Dependencies:   mbed mbed-rtos

Committer:
cspista
Date:
Sun Apr 10 12:20:27 2022 +0000
Revision:
0:b6055a7af0c9
Final version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cspista 0:b6055a7af0c9 1 #include "mbed.h"
cspista 0:b6055a7af0c9 2 #include "rtos.h"
cspista 0:b6055a7af0c9 3 AnalogIn adc(A4);
cspista 0:b6055a7af0c9 4 DigitalOut led1(LED1);
cspista 0:b6055a7af0c9 5
cspista 0:b6055a7af0c9 6 typedef uint32_t message_t;
cspista 0:b6055a7af0c9 7 Queue <message_t, 4> queue;
cspista 0:b6055a7af0c9 8
cspista 0:b6055a7af0c9 9 void led1_thread(void const *args)
cspista 0:b6055a7af0c9 10 {
cspista 0:b6055a7af0c9 11 while (true) {
cspista 0:b6055a7af0c9 12 led1 = !led1;
cspista 0:b6055a7af0c9 13 Thread::wait(1000);
cspista 0:b6055a7af0c9 14 }
cspista 0:b6055a7af0c9 15 }
cspista 0:b6055a7af0c9 16
cspista 0:b6055a7af0c9 17 //--- ADC Interrupt handler -----------------
cspista 0:b6055a7af0c9 18 extern "C" void ADC1_IRQHandler()
cspista 0:b6055a7af0c9 19 {
cspista 0:b6055a7af0c9 20 NVIC_ClearPendingIRQ(ADC_IRQn); //Clear ADC Interrupt Request Flag
cspista 0:b6055a7af0c9 21 uint16_t raw = ADC1->DR;
cspista 0:b6055a7af0c9 22 queue.put((message_t*)raw); //Send result through a Queue
cspista 0:b6055a7af0c9 23 }
cspista 0:b6055a7af0c9 24
cspista 0:b6055a7af0c9 25 //--- Start conversion, wait for result -----
cspista 0:b6055a7af0c9 26 uint16_t adc_read(uint32_t ch)
cspista 0:b6055a7af0c9 27 {
cspista 0:b6055a7af0c9 28 ADC1->SQR3 = ch; //set conversion channel
cspista 0:b6055a7af0c9 29 ADC1->SMPR2 = 7; //Sample time =480
cspista 0:b6055a7af0c9 30 ADC1->CR1 |= ADC_CR1_EOCIE; //enable interrupt
cspista 0:b6055a7af0c9 31 ADC1->CR2 |= ADC_CR2_SWSTART; //Start conversion
cspista 0:b6055a7af0c9 32 osEvent evt = queue.get(); //Wait for a message
cspista 0:b6055a7af0c9 33 return (uint16_t)evt.value.v; //Return obtained value
cspista 0:b6055a7af0c9 34 }
cspista 0:b6055a7af0c9 35
cspista 0:b6055a7af0c9 36 int main()
cspista 0:b6055a7af0c9 37 {
cspista 0:b6055a7af0c9 38 int32_t v25 = 760; //Voltage at 25C (in millivolts)
cspista 0:b6055a7af0c9 39 float m = 2.5; //Slope mV per degree)
cspista 0:b6055a7af0c9 40 uint16_t dummy = adc.read(); //needed for ADC configuration
cspista 0:b6055a7af0c9 41 ADC123_COMMON->CCR |= ADC_CCR_TSVREFE; //Enable inner channels
cspista 0:b6055a7af0c9 42 NVIC_SetVector(ADC_IRQn,(uint32_t)&ADC1_IRQHandler); //Attach ADC ISR
cspista 0:b6055a7af0c9 43 NVIC_EnableIRQ(ADC_IRQn); //Enable ADC interrupts
cspista 0:b6055a7af0c9 44 Thread thread1(led1_thread);
cspista 0:b6055a7af0c9 45 printf("\r\n Lab09 ADC interrupt in RTOS environment\r\n");
cspista 0:b6055a7af0c9 46 while(true) {
cspista 0:b6055a7af0c9 47 uint32_t a1 = 0;
cspista 0:b6055a7af0c9 48 uint32_t a2 = 0;
cspista 0:b6055a7af0c9 49 for(int i=0; i<3300; i++) {
cspista 0:b6055a7af0c9 50 a1 += adc_read(11); //Measure voltage at A4 (PTC_1)
cspista 0:b6055a7af0c9 51 a2 += adc_read(18); //Internal temperature sensor
cspista 0:b6055a7af0c9 52 }
cspista 0:b6055a7af0c9 53 float v1 = a1/4096.0f; //Convert v1 to millivolts
cspista 0:b6055a7af0c9 54 float temp1 = (v1-500)/10.0; //MCP9700 temperature in Celsius
cspista 0:b6055a7af0c9 55 float v2 = a2/4096.0f; //Convert v2 to millivolts
cspista 0:b6055a7af0c9 56 float temp2 = 25.0f+(v2-v25)/m; //Calculate temp in Celsius
cspista 0:b6055a7af0c9 57 printf("A4 = %.0f mV Temp = %.1f C Inner Ts: %.0f mV Temp = %.1f C\r\n",v1,temp1,v2,temp2);
cspista 0:b6055a7af0c9 58 Thread::wait(2000);
cspista 0:b6055a7af0c9 59 }
cspista 0:b6055a7af0c9 60
cspista 0:b6055a7af0c9 61 }