demonstrate teensy 3.1 ADC internal channels: temperature sensor and VREF output
Fork of Teensy_MBED_BLINKY by
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 }
Generated on Mon Jul 18 2022 21:24:37 by 1.7.2