Usage of ADC interrupt and the inner temperature sensor
Fork of rtos_basic by
main.cpp
00001 /** 12_rtos_ADCinterrupt 00002 * Using ADC interrupts and RTOS messaging for non-blockin waitting 00003 * Meanwhile a LED is blinked... 00004 * With our adc_read function we can reach extra 00005 * ADC channels as well, like the internal temperature sensor. 00006 * 00007 * Hardware requirement: 00008 * - FRDM-KL25Z board 00009 * - Some analog voltage applied to A0 input 00010 */ 00011 00012 #include "mbed.h" 00013 #include "rtos.h" 00014 AnalogIn adc(A0); 00015 DigitalOut led1(LED1); 00016 00017 typedef uint32_t message_t; 00018 Queue <message_t, 4> queue; 00019 00020 void led1_thread(void const *args) { 00021 while (true) { 00022 led1 = !led1; 00023 Thread::wait(1000); 00024 } 00025 } 00026 00027 //--- ADC Interrupt handler ----------------- 00028 extern "C" void ADC0_IRQHandler() 00029 { 00030 NVIC_ClearPendingIRQ(ADC0_IRQn); //Clear ADC Interrupt Request Flag 00031 uint16_t raw = ADC0->R[0]; 00032 queue.put((message_t*)raw); //Send result through a Queue 00033 } 00034 00035 00036 uint16_t adc_read(uint32_t ch) { 00037 ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable 00038 | ADC_SC3_AVGS(3); // 32 Samples Averaged 00039 // start conversion 00040 ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ch; //Set channel, enable interrupt 00041 osEvent evt = queue.get(); //Wait for a message 00042 return (uint16_t)evt.value.v; 00043 } 00044 00045 int main() { 00046 /* 00047 * The v25 value is the voltage reading at 25C, it comes from the ADC 00048 * electricals table in the processor manual. V25 is in millivolts. 00049 */ 00050 int32_t v25 = 716; 00051 00052 /* 00053 * The m value is slope of the temperature sensor values, again from 00054 * the ADC electricals table in the processor manual. 00055 * M in microvolts per degree. 00056 */ 00057 int32_t m = 1620; 00058 NVIC_SetVector(ADC0_IRQn, (uint32_t)&ADC0_IRQHandler); //Attach ADC interrupt service routine 00059 NVIC_EnableIRQ(ADC0_IRQn); //Enable ADC interrupt requests 00060 Thread thread1(led1_thread); 00061 00062 while (true) { 00063 uint16_t a1 = adc_read(8); //Measure voltage at A0 (PTB0) 00064 uint16_t a2 = adc_read(26); //Internal temperature sensor 00065 float v1 = a1*3.3f/65536; //Convert v1 to Volts 00066 float v2 = a2*3300.0f/65536; //Convert v2 to millivolts 00067 float temp = 25.0f-(v2-v25)*1000.0f/m; //Calculate temp in Celsius 00068 printf("A0 = %6.3f V Temp = %5.2f C\n",v1,temp); 00069 Thread::wait(2000); 00070 } 00071 }
Generated on Thu Jul 14 2022 10:31:11 by 1.7.2