Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of rtos_basic by
Revision 8:4d2d1dbbeda5, committed 2016-03-31
- Comitter:
- icserny
- Date:
- Thu Mar 31 14:13:20 2016 +0000
- Parent:
- 7:84b7291a746d
- Commit message:
- First version
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Thu Jan 28 15:24:41 2016 +0000
+++ b/main.cpp Thu Mar 31 14:13:20 2016 +0000
@@ -1,38 +1,71 @@
-/** 09_rtos_basic
- * RTOS LED blinking example running 3 threads
- * (main and two additional threads)
+/** 12_rtos_ADCinterrupt
+ * Using ADC interrupts and RTOS messaging for non-blockin waitting
+ * Meanwhile a LED is blinked...
+ * With our adc_read function we can reach extra
+ * ADC channels as well, like the internal temperature sensor.
*
* Hardware requirement:
* - FRDM-KL25Z board
+ * - Some analog voltage applied to A0 input
*/
#include "mbed.h"
#include "rtos.h"
-
+AnalogIn adc(A0);
DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-
-void led2_thread(void const *args) {
- while (true) {
- led2 = !led2;
- Thread::wait(2000);
- }
-}
-void led3_thread(void const *args) {
- while (true) {
- led3 = !led3;
- Thread::wait(4000);
- }
-}
-
-int main() {
- Thread thread2(led2_thread);
- Thread thread3(led3_thread);
-
+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 ADC0_IRQHandler()
+{
+ NVIC_ClearPendingIRQ(ADC0_IRQn); //Clear ADC Interrupt Request Flag
+ uint16_t raw = ADC0->R[0];
+ queue.put((message_t*)raw); //Send result through a Queue
+}
+
+
+uint16_t adc_read(uint32_t ch) {
+ ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable
+ | ADC_SC3_AVGS(3); // 32 Samples Averaged
+ // start conversion
+ ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ch; //Set channel, enable interrupt
+ osEvent evt = queue.get(); //Wait for a message
+ return (uint16_t)evt.value.v;
+}
+
+int main() {
+/*
+ * The v25 value is the voltage reading at 25C, it comes from the ADC
+ * electricals table in the processor manual. V25 is in millivolts.
+ */
+ int32_t v25 = 716;
+
+/*
+ * The m value is slope of the temperature sensor values, again from
+ * the ADC electricals table in the processor manual.
+ * M in microvolts per degree.
+ */
+ int32_t m = 1620;
+ NVIC_SetVector(ADC0_IRQn, (uint32_t)&ADC0_IRQHandler); //Attach ADC interrupt service routine
+ NVIC_EnableIRQ(ADC0_IRQn); //Enable ADC interrupt requests
+ Thread thread1(led1_thread);
+
+ while (true) {
+ uint16_t a1 = adc_read(8); //Measure voltage at A0 (PTB0)
+ uint16_t a2 = adc_read(26); //Internal temperature sensor
+ float v1 = a1*3.3f/65536; //Convert v1 to Volts
+ float v2 = a2*3300.0f/65536; //Convert v2 to millivolts
+ float temp = 25.0f-(v2-v25)*1000.0f/m; //Calculate temp in Celsius
+ printf("A0 = %6.3f V Temp = %5.2f C\n",v1,temp);
+ Thread::wait(2000);
+ }
+}
