demonstrate teensy 3.1 ADC internal channels: temperature sensor and VREF output

Dependencies:   USBDevice mbed

Fork of Teensy_MBED_BLINKY by HM Yoong

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //  Teensy 3.1 internal ADC  temperature VREF  
00002 //  analog resolution 16-bits
00003 #include "mbed.h"
00004 #include "USBSerial.h"
00005 #include "clk_freqs.h"
00006 
00007 #define DEFAULT         0
00008 #define INTERNAL        2
00009 #define INTERNAL1V2     2
00010 #define INTERNAL1V1     2
00011 #define EXTERNAL        0
00012 
00013 // for teensy 3.1 temp sensor on ADC0 channel 26,  vref output on ADC1 channel 18 GC3
00014 #define ADC_TEMP 26
00015 #define ADC_VREF 18
00016 
00017 #define PRREG(x) pc.printf(#x" %0x\n",x)
00018 
00019 USBSerial  pc;          // Virtual serial port over USB
00020 
00021 #define MAX_FADC        6000000 
00022 #define ADC1  ((ADC_Type *)0x400BB000u)
00023 
00024 void adc_init(){
00025     VREF->TRM = 0x60;  // from teensy enable vref
00026     VREF->SC = 0xE1;
00027     
00028     //  enable ADC0 and ADC1
00029     SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
00030     SIM->SCGC3 |= SIM_SCGC3_ADC1_MASK;
00031 
00032     // bus clk
00033     uint32_t PCLK = bus_frequency();
00034     uint32_t clkdiv;
00035     for (clkdiv = 0; clkdiv < 4; clkdiv++) {
00036         if ((PCLK >> clkdiv) <= MAX_FADC)
00037             break;
00038     }
00039     if (clkdiv == 4)                    //Set max div
00040         clkdiv = 0x7;
00041 
00042  //   ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc);
00043 
00044     ADC0->CFG1 = ADC_CFG1_ADLPC_MASK    // Low-Power Configuration
00045                | ADC_CFG1_ADIV(clkdiv & 0x3)       // Clock Divide Select
00046                | ADC_CFG1_ADLSMP_MASK   // Long Sample Time
00047                | ADC_CFG1_MODE(3)       // (16)bits Resolution
00048                | ADC_CFG1_ADICLK(clkdiv >> 2);    // Input Clock
00049 
00050     ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK   // ADxxb or ADxxa channels
00051                | ADC_CFG2_ADHSC_MASK    // High-Speed Configuration
00052                | ADC_CFG2_ADLSTS(0);    // Long Sample Time Select
00053 
00054     ADC0->SC2 = ADC_SC2_REFSEL(0);      // Default Voltage Reference
00055 
00056     ADC0->SC3 = ADC_SC3_AVGE_MASK       // Hardware Average Enable
00057               | ADC_SC3_AVGS(0);        // 4 Samples Averaged
00058 // ADC1
00059     ADC1->CFG1 = ADC_CFG1_ADLPC_MASK    // Low-Power Configuration
00060                | ADC_CFG1_ADIV(clkdiv & 0x3)       // Clock Divide Select
00061                | ADC_CFG1_ADLSMP_MASK   // Long Sample Time
00062                | ADC_CFG1_MODE(3)       // (16)bits Resolution
00063                | ADC_CFG1_ADICLK(clkdiv >> 2);    // Input Clock
00064 
00065     ADC1->CFG2 = ADC_CFG2_MUXSEL_MASK   // ADxxb or ADxxa channels
00066                | ADC_CFG2_ADHSC_MASK    // High-Speed Configuration
00067                | ADC_CFG2_ADLSTS(0);    // Long Sample Time Select
00068 
00069     ADC1->SC2 = ADC_SC2_REFSEL(0);      // Default Voltage Reference
00070 
00071     ADC1->SC3 = ADC_SC3_AVGE_MASK       // Hardware Average Enable
00072               | ADC_SC3_AVGS(0);        // 4 Samples Averaged
00073 }
00074 
00075 
00076 uint16_t adc0_read(int channel) {
00077     // start conversion
00078     ADC0->SC1[0] = ADC_SC1_ADCH(channel);
00079 
00080     // Wait Conversion Complete
00081     while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
00082 
00083     return (uint16_t)ADC0->R[0];
00084 }
00085 
00086 uint16_t adc1_read(int channel) {
00087     // start conversion
00088     ADC1->SC1[0] = ADC_SC1_ADCH(channel);
00089 
00090     // Wait Conversion Complete
00091     while ((ADC1->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
00092 
00093     return (uint16_t)ADC1->R[0];
00094 } 
00095 
00096 void adc0_ref(int ref){
00097     ADC0->SC2 = ADC_SC2_REFSEL(ref);
00098     adc0_read(0);   // discard a reading after ref change
00099 }
00100 
00101 int main() {
00102     double c, v;
00103     while(1) {
00104         uint16_t val;
00105         pc.printf("SystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
00106         PRREG(SIM->CLKDIV1);
00107         PRREG(SIM->CLKDIV2);
00108         
00109         PRREG(SIM->SCGC2);   //ref 12.2
00110         PRREG(SIM->SCGC3);
00111         PRREG(SIM->SCGC4);
00112         PRREG(SIM->SCGC5);
00113         PRREG(SIM->SCGC6);
00114         PRREG(SIM->SCGC7);
00115         adc_init();
00116         val = adc0_read(ADC_TEMP);
00117         c= -0.02432*val + 371;  // may need to calibrate for your chip
00118         pc.printf("val %d %.1f C\n",val,c);
00119 
00120         val = adc1_read(ADC_VREF);
00121         v = 1.195*65536/val;    // datasheet says internal vref is 1.195v
00122         pc.printf("val %d  Vcc %.3f\n",val,v);
00123         wait(3.0);
00124     }
00125 }