Usage of ADC interrupt and the inner temperature sensor

Dependencies:   mbed-rtos mbed

Fork of rtos_basic by mbed official

Committer:
icserny
Date:
Thu Mar 31 14:13:20 2016 +0000
Revision:
8:4d2d1dbbeda5
Parent:
7:84b7291a746d
First version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
icserny 8:4d2d1dbbeda5 1 /** 12_rtos_ADCinterrupt
icserny 8:4d2d1dbbeda5 2 * Using ADC interrupts and RTOS messaging for non-blockin waitting
icserny 8:4d2d1dbbeda5 3 * Meanwhile a LED is blinked...
icserny 8:4d2d1dbbeda5 4 * With our adc_read function we can reach extra
icserny 8:4d2d1dbbeda5 5 * ADC channels as well, like the internal temperature sensor.
icserny 7:84b7291a746d 6 *
icserny 7:84b7291a746d 7 * Hardware requirement:
icserny 7:84b7291a746d 8 * - FRDM-KL25Z board
icserny 8:4d2d1dbbeda5 9 * - Some analog voltage applied to A0 input
icserny 7:84b7291a746d 10 */
icserny 7:84b7291a746d 11
emilmont 1:491820ee784d 12 #include "mbed.h"
emilmont 1:491820ee784d 13 #include "rtos.h"
icserny 8:4d2d1dbbeda5 14 AnalogIn adc(A0);
emilmont 1:491820ee784d 15 DigitalOut led1(LED1);
icserny 7:84b7291a746d 16
icserny 8:4d2d1dbbeda5 17 typedef uint32_t message_t;
icserny 8:4d2d1dbbeda5 18 Queue <message_t, 4> queue;
icserny 8:4d2d1dbbeda5 19
icserny 8:4d2d1dbbeda5 20 void led1_thread(void const *args) {
emilmont 1:491820ee784d 21 while (true) {
emilmont 1:491820ee784d 22 led1 = !led1;
icserny 7:84b7291a746d 23 Thread::wait(1000);
emilmont 1:491820ee784d 24 }
emilmont 1:491820ee784d 25 }
icserny 8:4d2d1dbbeda5 26
icserny 8:4d2d1dbbeda5 27 //--- ADC Interrupt handler -----------------
icserny 8:4d2d1dbbeda5 28 extern "C" void ADC0_IRQHandler()
icserny 8:4d2d1dbbeda5 29 {
icserny 8:4d2d1dbbeda5 30 NVIC_ClearPendingIRQ(ADC0_IRQn); //Clear ADC Interrupt Request Flag
icserny 8:4d2d1dbbeda5 31 uint16_t raw = ADC0->R[0];
icserny 8:4d2d1dbbeda5 32 queue.put((message_t*)raw); //Send result through a Queue
icserny 8:4d2d1dbbeda5 33 }
icserny 8:4d2d1dbbeda5 34
icserny 8:4d2d1dbbeda5 35
icserny 8:4d2d1dbbeda5 36 uint16_t adc_read(uint32_t ch) {
icserny 8:4d2d1dbbeda5 37 ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
icserny 8:4d2d1dbbeda5 38 | ADC_SC3_AVGS(3); // 32 Samples Averaged
icserny 8:4d2d1dbbeda5 39 // start conversion
icserny 8:4d2d1dbbeda5 40 ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ch; //Set channel, enable interrupt
icserny 8:4d2d1dbbeda5 41 osEvent evt = queue.get(); //Wait for a message
icserny 8:4d2d1dbbeda5 42 return (uint16_t)evt.value.v;
icserny 8:4d2d1dbbeda5 43 }
icserny 8:4d2d1dbbeda5 44
icserny 8:4d2d1dbbeda5 45 int main() {
icserny 8:4d2d1dbbeda5 46 /*
icserny 8:4d2d1dbbeda5 47 * The v25 value is the voltage reading at 25C, it comes from the ADC
icserny 8:4d2d1dbbeda5 48 * electricals table in the processor manual. V25 is in millivolts.
icserny 8:4d2d1dbbeda5 49 */
icserny 8:4d2d1dbbeda5 50 int32_t v25 = 716;
icserny 8:4d2d1dbbeda5 51
icserny 8:4d2d1dbbeda5 52 /*
icserny 8:4d2d1dbbeda5 53 * The m value is slope of the temperature sensor values, again from
icserny 8:4d2d1dbbeda5 54 * the ADC electricals table in the processor manual.
icserny 8:4d2d1dbbeda5 55 * M in microvolts per degree.
icserny 8:4d2d1dbbeda5 56 */
icserny 8:4d2d1dbbeda5 57 int32_t m = 1620;
icserny 8:4d2d1dbbeda5 58 NVIC_SetVector(ADC0_IRQn, (uint32_t)&ADC0_IRQHandler); //Attach ADC interrupt service routine
icserny 8:4d2d1dbbeda5 59 NVIC_EnableIRQ(ADC0_IRQn); //Enable ADC interrupt requests
icserny 8:4d2d1dbbeda5 60 Thread thread1(led1_thread);
icserny 8:4d2d1dbbeda5 61
icserny 8:4d2d1dbbeda5 62 while (true) {
icserny 8:4d2d1dbbeda5 63 uint16_t a1 = adc_read(8); //Measure voltage at A0 (PTB0)
icserny 8:4d2d1dbbeda5 64 uint16_t a2 = adc_read(26); //Internal temperature sensor
icserny 8:4d2d1dbbeda5 65 float v1 = a1*3.3f/65536; //Convert v1 to Volts
icserny 8:4d2d1dbbeda5 66 float v2 = a2*3300.0f/65536; //Convert v2 to millivolts
icserny 8:4d2d1dbbeda5 67 float temp = 25.0f-(v2-v25)*1000.0f/m; //Calculate temp in Celsius
icserny 8:4d2d1dbbeda5 68 printf("A0 = %6.3f V Temp = %5.2f C\n",v1,temp);
icserny 8:4d2d1dbbeda5 69 Thread::wait(2000);
icserny 8:4d2d1dbbeda5 70 }
icserny 8:4d2d1dbbeda5 71 }