Using ADC interrupts in RTOS environment. This program also demonstrates the usage of RTOS API function calls from interrupt.
main.cpp@0:b6055a7af0c9, 2022-04-10 (annotated)
- Committer:
- cspista
- Date:
- Sun Apr 10 12:20:27 2022 +0000
- Revision:
- 0:b6055a7af0c9
Final version
Who changed what in which revision?
User | Revision | Line number | New 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 | } |