demonstrate teensy 3.1 ADC internal channels: temperature sensor and VREF output
Fork of Teensy_MBED_BLINKY by
main.cpp
- Committer:
- manitou
- Date:
- 2015-10-02
- Revision:
- 2:5b51fe85e931
- Parent:
- 1:e452bc59d245
File content as of revision 2:5b51fe85e931:
// Teensy 3.1 internal ADC temperature VREF // analog resolution 16-bits #include "mbed.h" #include "USBSerial.h" #include "clk_freqs.h" #define DEFAULT 0 #define INTERNAL 2 #define INTERNAL1V2 2 #define INTERNAL1V1 2 #define EXTERNAL 0 // for teensy 3.1 temp sensor on ADC0 channel 26, vref output on ADC1 channel 18 GC3 #define ADC_TEMP 26 #define ADC_VREF 18 #define PRREG(x) pc.printf(#x" %0x\n",x) USBSerial pc; // Virtual serial port over USB #define MAX_FADC 6000000 #define ADC1 ((ADC_Type *)0x400BB000u) void adc_init(){ VREF->TRM = 0x60; // from teensy enable vref VREF->SC = 0xE1; // enable ADC0 and ADC1 SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; SIM->SCGC3 |= SIM_SCGC3_ADC1_MASK; // bus clk uint32_t PCLK = bus_frequency(); uint32_t clkdiv; for (clkdiv = 0; clkdiv < 4; clkdiv++) { if ((PCLK >> clkdiv) <= MAX_FADC) break; } if (clkdiv == 4) //Set max div clkdiv = 0x7; // ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc); ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration | ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select | ADC_CFG1_ADLSMP_MASK // Long Sample Time | ADC_CFG1_MODE(3) // (16)bits Resolution | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels | ADC_CFG2_ADHSC_MASK // High-Speed Configuration | ADC_CFG2_ADLSTS(0); // Long Sample Time Select ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference ADC0->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable | ADC_SC3_AVGS(0); // 4 Samples Averaged // ADC1 ADC1->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration | ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select | ADC_CFG1_ADLSMP_MASK // Long Sample Time | ADC_CFG1_MODE(3) // (16)bits Resolution | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock ADC1->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels | ADC_CFG2_ADHSC_MASK // High-Speed Configuration | ADC_CFG2_ADLSTS(0); // Long Sample Time Select ADC1->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference ADC1->SC3 = ADC_SC3_AVGE_MASK // Hardware Average Enable | ADC_SC3_AVGS(0); // 4 Samples Averaged } uint16_t adc0_read(int channel) { // start conversion ADC0->SC1[0] = ADC_SC1_ADCH(channel); // Wait Conversion Complete while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); return (uint16_t)ADC0->R[0]; } uint16_t adc1_read(int channel) { // start conversion ADC1->SC1[0] = ADC_SC1_ADCH(channel); // Wait Conversion Complete while ((ADC1->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK); return (uint16_t)ADC1->R[0]; } void adc0_ref(int ref){ ADC0->SC2 = ADC_SC2_REFSEL(ref); adc0_read(0); // discard a reading after ref change } int main() { double c, v; while(1) { uint16_t val; pc.printf("SystemCoreClock %d %s %s\n",SystemCoreClock,__TIME__,__DATE__); PRREG(SIM->CLKDIV1); PRREG(SIM->CLKDIV2); PRREG(SIM->SCGC2); //ref 12.2 PRREG(SIM->SCGC3); PRREG(SIM->SCGC4); PRREG(SIM->SCGC5); PRREG(SIM->SCGC6); PRREG(SIM->SCGC7); adc_init(); val = adc0_read(ADC_TEMP); c= -0.02432*val + 371; // may need to calibrate for your chip pc.printf("val %d %.1f C\n",val,c); val = adc1_read(ADC_VREF); v = 1.195*65536/val; // datasheet says internal vref is 1.195v pc.printf("val %d Vcc %.3f\n",val,v); wait(3.0); } }