demonstrate teensy 3.1 ADC internal channels: temperature sensor and VREF output
Fork of Teensy_MBED_BLINKY by
main.cpp@2:5b51fe85e931, 2015-10-02 (annotated)
- Committer:
- manitou
- Date:
- Fri Oct 02 16:09:35 2015 +0000
- Revision:
- 2:5b51fe85e931
- Parent:
- 1:e452bc59d245
demonstrate teensy 3.1 ADC internal channels: temperature sensor and VREF output
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
manitou | 2:5b51fe85e931 | 1 | // Teensy 3.1 internal ADC temperature VREF |
manitou | 2:5b51fe85e931 | 2 | // analog resolution 16-bits |
yoonghm | 1:e452bc59d245 | 3 | #include "mbed.h" |
yoonghm | 1:e452bc59d245 | 4 | #include "USBSerial.h" |
manitou | 2:5b51fe85e931 | 5 | #include "clk_freqs.h" |
yoonghm | 1:e452bc59d245 | 6 | |
manitou | 2:5b51fe85e931 | 7 | #define DEFAULT 0 |
manitou | 2:5b51fe85e931 | 8 | #define INTERNAL 2 |
manitou | 2:5b51fe85e931 | 9 | #define INTERNAL1V2 2 |
manitou | 2:5b51fe85e931 | 10 | #define INTERNAL1V1 2 |
manitou | 2:5b51fe85e931 | 11 | #define EXTERNAL 0 |
manitou | 2:5b51fe85e931 | 12 | |
manitou | 2:5b51fe85e931 | 13 | // for teensy 3.1 temp sensor on ADC0 channel 26, vref output on ADC1 channel 18 GC3 |
manitou | 2:5b51fe85e931 | 14 | #define ADC_TEMP 26 |
manitou | 2:5b51fe85e931 | 15 | #define ADC_VREF 18 |
manitou | 2:5b51fe85e931 | 16 | |
manitou | 2:5b51fe85e931 | 17 | #define PRREG(x) pc.printf(#x" %0x\n",x) |
manitou | 2:5b51fe85e931 | 18 | |
yoonghm | 1:e452bc59d245 | 19 | USBSerial pc; // Virtual serial port over USB |
manitou | 2:5b51fe85e931 | 20 | |
manitou | 2:5b51fe85e931 | 21 | #define MAX_FADC 6000000 |
manitou | 2:5b51fe85e931 | 22 | #define ADC1 ((ADC_Type *)0x400BB000u) |
manitou | 2:5b51fe85e931 | 23 | |
manitou | 2:5b51fe85e931 | 24 | void adc_init(){ |
manitou | 2:5b51fe85e931 | 25 | VREF->TRM = 0x60; // from teensy enable vref |
manitou | 2:5b51fe85e931 | 26 | VREF->SC = 0xE1; |
manitou | 2:5b51fe85e931 | 27 | |
manitou | 2:5b51fe85e931 | 28 | // enable ADC0 and ADC1 |
manitou | 2:5b51fe85e931 | 29 | SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; |
manitou | 2:5b51fe85e931 | 30 | SIM->SCGC3 |= SIM_SCGC3_ADC1_MASK; |
manitou | 2:5b51fe85e931 | 31 | |
manitou | 2:5b51fe85e931 | 32 | // bus clk |
manitou | 2:5b51fe85e931 | 33 | uint32_t PCLK = bus_frequency(); |
manitou | 2:5b51fe85e931 | 34 | uint32_t clkdiv; |
manitou | 2:5b51fe85e931 | 35 | for (clkdiv = 0; clkdiv < 4; clkdiv++) { |
manitou | 2:5b51fe85e931 | 36 | if ((PCLK >> clkdiv) <= MAX_FADC) |
manitou | 2:5b51fe85e931 | 37 | break; |
manitou | 2:5b51fe85e931 | 38 | } |
manitou | 2:5b51fe85e931 | 39 | if (clkdiv == 4) //Set max div |
manitou | 2:5b51fe85e931 | 40 | clkdiv = 0x7; |
manitou | 2:5b51fe85e931 | 41 | |
manitou | 2:5b51fe85e931 | 42 | // ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc); |
manitou | 2:5b51fe85e931 | 43 | |
manitou | 2:5b51fe85e931 | 44 | ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration |
manitou | 2:5b51fe85e931 | 45 | | ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select |
manitou | 2:5b51fe85e931 | 46 | | ADC_CFG1_ADLSMP_MASK // Long Sample Time |
manitou | 2:5b51fe85e931 | 47 | | ADC_CFG1_MODE(3) // (16)bits Resolution |
manitou | 2:5b51fe85e931 | 48 | | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock |
manitou | 2:5b51fe85e931 | 49 | |
manitou | 2:5b51fe85e931 | 50 | ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels |
manitou | 2:5b51fe85e931 | 51 | | ADC_CFG2_ADHSC_MASK // High-Speed Configuration |
manitou | 2:5b51fe85e931 | 52 | | ADC_CFG2_ADLSTS(0); // Long Sample Time Select |
manitou | 2:5b51fe85e931 | 53 | |
manitou | 2:5b51fe85e931 | 54 | ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference |
manitou | 2:5b51fe85e931 | 55 | |
manitou | 2:5b51fe85e931 | 56 | ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable |
manitou | 2:5b51fe85e931 | 57 | | ADC_SC3_AVGS(0); // 4 Samples Averaged |
manitou | 2:5b51fe85e931 | 58 | // ADC1 |
manitou | 2:5b51fe85e931 | 59 | ADC1->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration |
manitou | 2:5b51fe85e931 | 60 | | ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select |
manitou | 2:5b51fe85e931 | 61 | | ADC_CFG1_ADLSMP_MASK // Long Sample Time |
manitou | 2:5b51fe85e931 | 62 | | ADC_CFG1_MODE(3) // (16)bits Resolution |
manitou | 2:5b51fe85e931 | 63 | | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock |
manitou | 2:5b51fe85e931 | 64 | |
manitou | 2:5b51fe85e931 | 65 | ADC1->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels |
manitou | 2:5b51fe85e931 | 66 | | ADC_CFG2_ADHSC_MASK // High-Speed Configuration |
manitou | 2:5b51fe85e931 | 67 | | ADC_CFG2_ADLSTS(0); // Long Sample Time Select |
manitou | 2:5b51fe85e931 | 68 | |
manitou | 2:5b51fe85e931 | 69 | ADC1->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference |
manitou | 2:5b51fe85e931 | 70 | |
manitou | 2:5b51fe85e931 | 71 | ADC1->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable |
manitou | 2:5b51fe85e931 | 72 | | ADC_SC3_AVGS(0); // 4 Samples Averaged |
manitou | 2:5b51fe85e931 | 73 | } |
manitou | 2:5b51fe85e931 | 74 | |
manitou | 2:5b51fe85e931 | 75 | |
manitou | 2:5b51fe85e931 | 76 | uint16_t adc0_read(int channel) { |
manitou | 2:5b51fe85e931 | 77 | // start conversion |
manitou | 2:5b51fe85e931 | 78 | ADC0->SC1[0] = ADC_SC1_ADCH(channel); |
manitou | 2:5b51fe85e931 | 79 | |
manitou | 2:5b51fe85e931 | 80 | // Wait Conversion Complete |
manitou | 2:5b51fe85e931 | 81 | while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); |
manitou | 2:5b51fe85e931 | 82 | |
manitou | 2:5b51fe85e931 | 83 | return (uint16_t)ADC0->R[0]; |
manitou | 2:5b51fe85e931 | 84 | } |
manitou | 2:5b51fe85e931 | 85 | |
manitou | 2:5b51fe85e931 | 86 | uint16_t adc1_read(int channel) { |
manitou | 2:5b51fe85e931 | 87 | // start conversion |
manitou | 2:5b51fe85e931 | 88 | ADC1->SC1[0] = ADC_SC1_ADCH(channel); |
manitou | 2:5b51fe85e931 | 89 | |
manitou | 2:5b51fe85e931 | 90 | // Wait Conversion Complete |
manitou | 2:5b51fe85e931 | 91 | while ((ADC1->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); |
manitou | 2:5b51fe85e931 | 92 | |
manitou | 2:5b51fe85e931 | 93 | return (uint16_t)ADC1->R[0]; |
manitou | 2:5b51fe85e931 | 94 | } |
manitou | 2:5b51fe85e931 | 95 | |
manitou | 2:5b51fe85e931 | 96 | void adc0_ref(int ref){ |
manitou | 2:5b51fe85e931 | 97 | ADC0->SC2 = ADC_SC2_REFSEL(ref); |
manitou | 2:5b51fe85e931 | 98 | adc0_read(0); // discard a reading after ref change |
manitou | 2:5b51fe85e931 | 99 | } |
manitou | 2:5b51fe85e931 | 100 | |
yoonghm | 0:8495741fab9c | 101 | int main() { |
manitou | 2:5b51fe85e931 | 102 | double c, v; |
yoonghm | 0:8495741fab9c | 103 | while(1) { |
manitou | 2:5b51fe85e931 | 104 | uint16_t val; |
manitou | 2:5b51fe85e931 | 105 | pc.printf("SystemCoreClock %d %s %s\n",SystemCoreClock,__TIME__,__DATE__); |
manitou | 2:5b51fe85e931 | 106 | PRREG(SIM->CLKDIV1); |
manitou | 2:5b51fe85e931 | 107 | PRREG(SIM->CLKDIV2); |
manitou | 2:5b51fe85e931 | 108 | |
manitou | 2:5b51fe85e931 | 109 | PRREG(SIM->SCGC2); //ref 12.2 |
manitou | 2:5b51fe85e931 | 110 | PRREG(SIM->SCGC3); |
manitou | 2:5b51fe85e931 | 111 | PRREG(SIM->SCGC4); |
manitou | 2:5b51fe85e931 | 112 | PRREG(SIM->SCGC5); |
manitou | 2:5b51fe85e931 | 113 | PRREG(SIM->SCGC6); |
manitou | 2:5b51fe85e931 | 114 | PRREG(SIM->SCGC7); |
manitou | 2:5b51fe85e931 | 115 | adc_init(); |
manitou | 2:5b51fe85e931 | 116 | val = adc0_read(ADC_TEMP); |
manitou | 2:5b51fe85e931 | 117 | c= -0.02432*val + 371; // may need to calibrate for your chip |
manitou | 2:5b51fe85e931 | 118 | pc.printf("val %d %.1f C\n",val,c); |
manitou | 2:5b51fe85e931 | 119 | |
manitou | 2:5b51fe85e931 | 120 | val = adc1_read(ADC_VREF); |
manitou | 2:5b51fe85e931 | 121 | v = 1.195*65536/val; // datasheet says internal vref is 1.195v |
manitou | 2:5b51fe85e931 | 122 | pc.printf("val %d Vcc %.3f\n",val,v); |
manitou | 2:5b51fe85e931 | 123 | wait(3.0); |
yoonghm | 0:8495741fab9c | 124 | } |
yoonghm | 0:8495741fab9c | 125 | } |