lect14_notes

lect14_notes - Foundations of Embedded Systems A Term Fall...

Info iconThis preview shows pages 1–12. Sign up to view the full content.

View Full Document Right Arrow Icon
Background image of page 1

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 2
Background image of page 3

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 4
Background image of page 5

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 6
Background image of page 7

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 8
Background image of page 9

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 10
Background image of page 11

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
Background image of page 12
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Foundations of Embedded Systems A Term Fall 2008 Lecture #14: More ADC Examples Reading for Today: TI example code, ADXL330 data sheet Reading for Next Class: SPI Articles, User's Manual Ch 15 Lab #2 (on web): Report due 9/30/2008 HW #4 (on web): Due MONDAY 9/29/2008 Exam #2 -— Tuesday 9/30/2008 Last Class: Basic: settings for the ADC12 registers for a simple single channel, single conversion measurement >> Use code examples >> Add new required elements as needed starting from working code Let's stand back and take stock... >> & of the interfacing to and programming of peripherals is just 10! ——> In general purpose computing this is automagically handled by OS... but the embedded. systems programmer has to implement it all A Key Part is using code examples to help figure out those peripheral control registers! >> Last class we set up the ADC12 for to take a single measurement from our example current measurement circuit -> This involved specific settings for ADC12CTLO, ADC12CTL1 and ADC 1 iZMCTLO registers Some key elements of the solution were Vref+ was set to 2.5V (and Vmg = GND) —- REF2_5 , REF_ON , SREF_1 >> Starting with the code from that example how should we configure the ADC12 registers to take a single measurement from the Internal Temperature Sensor >> See Notes from Yesterday (Lecture 13) Curve“ *1— M915 wrst Exam/\(Q l~e .SeIASI‘nS / warrenk: '1' S“: 7' HM: rmeasté-Mmen4 0“ {{oqE —~ 26": lA 2-730 CorreSPDnC‘S +0 curren* a? {0.1% m/“QB 0): Ise'n w ' Jo SM?) : ~Fume when Lao-a Make {4‘4 conversiov- QMeG-Suv‘ns CUV‘V‘CA'\' 39,3 meaSur‘uvxs vo\‘\’¢34 Jroeo CKC V055 0K- Currevd SQnSTnS V‘€$H$+0V‘ IA- Lor '9 r SFOAAS 4° Q-gv) 0A- Correspmxcxs 40 0V :) Use Vr¢p+: 2.§v : In+evnd We; _> ADCD‘ 0U'+PU+ CoJe 'ns mappecl 4o vewr44C‘J ‘V‘i5 Oxoooo = 0A «ml OonFFsl-Io‘tf: I A. A sinjlfl bf} 05 “Vt/0% = 0. 2w mA/bH | M l (3?th | CA 9' OOO‘A // // Some code to implement the current sensor example from last class. Input voltage range 0 t02.5V corresponds to 0 to 1A. unsigned int in_va1ue, busy; // // // // Initialize control register ADC12CTLO = 0110 0110 0111 0000 SHTlx and SHTOx = 66h (both 128 clks), MCS = O = no burst mode REF2_5V = 2 (2.5V), REFON = 1 = use internal reference voltage and ADClZON = 1 = turn ADC on ADClZCTLO = SHTO_6 + SHT1_6 + REF2_5 + REFON + ADClZON; // // // // // // // // // Initialize control register ADClZCTLl = 0000 0010 0000 0000 CSTART ADDX = 0000 = start conversion with ADC12MEMO, SHSx = 00 = use SW conversion initiation trigger, ADClZSC bits SHP = 1 = SAMPCON signal sourced from sampling timer, ISSH = 0 = sample input signal not inverted, ADClZDIVx = 000= divide ADClZCLK by 1, ADClZSSEL=00= ADC clock ADClZOSC (~5 MHz), CONSEQX = 00 single channel, single conversion, ADClZBUSY = 0 = no ADC operation active ADC12CTL1 = SHP; 0001 0000 // Set conversion memory control register ADClZMCTLO = // EOS = 0, SREF =001 ——>Voltage refs = GND to (Vref+) // INCHx = 0000 = analog input from A0 ADClZMCTLO = SREF_1 + INCH_0; PGSEL |= BITO; // Set Port 6 Pin 0 in FUNCTION mode for ADC //Enable and start (single) conversion (not using ADC interrupts) ADC12CTLO |= ADClZSC + ENC; busy = 1; while (busy I: 0) // Wait until conversion complete busy = ADC12CTL1 & ADClZBUSY; //Check BUSY bit (polling!) in_va1ue = ADC12MEMO & OxOFFF; // keep only low 12 bits > > How would we use the results from the ADC in our program? (2256 iUL‘LOAB LOW} oloes 1 \b}+ {epresevx+? “4 : 0.2HumA/10;+ 4090 Curran-1' Wading LA mil‘lMPSW—dj b‘e m V3-per_ bf+ = 0.2LH45 A b4 . - .2 _ l \ Lh—UA,\U‘€ 3* M P V j \\‘/ Ex: Another ADC example -- The MSP430's Internal Temperature Sensor // // signed long Determine_Temp() { // // // // // // // // // =9 // // // -$ //Enable and start (single) conversion // // // // // // This function returns the internal chip temperature, based on the internal temperature diode which has an FSR 1.5V < signed long temperature, tempC, approx_tempC; unsigned int in_temp, busy; Initialize control register ADC12CTLO SHTlx and SHTOX = 66h (both 128 clks), MCS 0110 0110 0011 0000 = 0 = no burst mode REF2_5V = 0 (1.5V), REFON = 1 = use internal reference voltage and ADClZON = l = turn ADC on ADC12CTLO = SHTO_6 + SHT1_6 + REFON + ADC120N; Initialize control register ADClZCTLl 0000 0010 0000 0000 CSTART ADDx = 0000 start conversion with ADClZMEMO, SHSX = 00 = use SW conversion initiation trigger, ADClZSC bits SHP = l = SAMPCON signal sourced from sampling timer, ISSH = 0 = sample input signal not inverted, ADClZDIVX = OOO= divide ADClZCLK by l, ADClZSSEL=OO= ADC Clock ADClZOSC (~5 MHz), CONSEQX = 00 single channel, single conversion, ADClZBUSY = 0 = no ADC operation active ADClZCTLl = SHP; Set conversion memory control register ADClZMCTLO = 0001 1010 E05 = O, SREF =001 ——>Voltage refs = GND to 1.5V (Vref+) INCHx = 1010 = analog input from ch10 = internal temp sensor ADCIZMCTLO = SREF 1 + INCH 107 176551.. because W3 ins IuTeszu ck¢4n¢( égr ADC12CTLO |= ADClZSC + ENC; busy = 1; while (busy != 0) IO // Wait until conversion complete busy = ADC12CTL1 & ADClZBUSY; //Check BUSY bit (polling!) in_temp = ADClZMEMO & OXOFFF; // keep only low 12 bits temperature = (long)in_temp; // convert to type long These steps convert the ADC reading to degrees Celsius <37 Sensor spec 3.55 mV/C deg and 986 mV = O Celsius There are 1.5V/4096 counts 0.366 mV per count. So, tempC ((float)in_temp*0.366 — 986.0)/3.55; Often want to avoid floating point math especially division Verify that these integer operations provide a fairly good approximation (integer portion) of the floating point math! approx_tempC = temperature*21l; approx_tempC >>= 11; // right shift 11 is a divide by 2048 approx_tempc -= 278; }//End Determine_Temp Function ADC12 Operation 7 m5? 1: ntfiv na,’ 20.2.8 Using the Integrated Temperature Sensor I am 19 sehs‘”, To use the on-chi temperature sensor, the user selects the analog input WKINCHX = 101@ Any other configuration is done as if an external v channel was se ced, including reference selection, conversion-memory HQ H- to selection, etc. The typical temperature sensor transfer function is shown in Figure 20—10. When using the temperature sensor, the sample period must be greater than 30 us. The temperature sensor offset error can be large, and may need to be calibrated for most applications. See device-specific datasheet for parameters. Selecting the temperature sensor automatically turns on the on-chip reference generator as a voltage source for the temperature sensor. However, it does not enable the VREF+ output or affect the reference selections for the conversion. The reference choices for converting the temperature sensor are the same as with any other channel. Figure 20— 10. Typical Temperature Sensor Transfer Function Volts (5 'L300 .. gasolutmn - 1.200 Ll 0‘1 ‘9 ‘L1OO Sgflé‘ “60 r:- 1.000 0 CLQOO 0.700 Celsius ~50 0 50 100 ‘emp C =- 6/‘TEMP —O.‘lf§(oV»/o.oogl§§ 2046 ADC72 Ex: Now, what if you wanted to monitor both the current through the sensing resistor and the internal temperature of the chip at the same time? How should we set up the ADC registers to do that? =9 ‘wé'd (Jam/\d 4‘0 A0 SLflcJQ COWVQASIOW Om 2L r/Qnaevx n@{ 3 £902, need Burgh mode on omg +0 9"} UP 0: MCTL «6375+‘9’ for eoka sown =37 Qkofi v’fipevewce l/@l 4&‘3’3 3) 2*gv 9Com“ Lorre/A metflf :> Tk‘ts m €6LI/LS C on VQVS‘IOW ma, p 4 In»; #define MA_PER_BIT 0.244 // =l.0A/4096 #define MV_PER_BIT 0.610 // =2.5V/4096 unsigned int in_current,in_temp; float milliamps,tempC; // Initialize control register ADC12CTLO = 0110 0110 0011 0000 // SHTlx and SHTOx = 66h (both 128 clks), MSC = 1 = burst mode on // REF2_5V =I' (Vref+ =.2.5V), REFON = 1 = use internal reference // voltage and ADC120N = 1 = turn ADC on ADC12CTLO = SHTO_6 + SHT1_6 + MSC + REF2_5V+ REFON + ADClZON; // Initialize control register ADClZCTLl = 0000 0010 0000 0010 // CSTART ADDX = 0000 = start conversion with ADC12MEMO, // SHSX = 00 = use SW conversion initiation trigger, ADClZSC bits // SHP = 1 = SAMPCON signal sourced from sampling timer, // ISSH = 0 = sample input signal not inverted, // ADCIZDIVX = 000= divide ADClZCLK by l, // ADCIZSSEL=00= ADC clock ADCIZOSC (~5 MHZ), // CONSEQl = o // CONSEQO = 1 = sequence of channels converted once, // ADC12BUSY = 0 = no ADC operation active ADC12CTL1 SHP+CONSEQO; // Set conversion memory control registers for the 2 channels // ADC12MCTLO: EOS = 0, SREF =001 = voltage refs = GND to Vref+ // INCHX = 0000 ADClZMCTLO = SREF_1 + INCH_0; // ADC12MCTL1: EOS = 1, SREF =001 = voltage refs = GND to Vref+ // INCHX = 0101 ADC12MCTL1 = SREF_1 + INCH_10 + EOS; // Se: Port 6 Pins 0 to FUNCTION mode (=1) for ADC12 P6SEL = P6SEL | BITO; // Forever loop to take measurements while (1) { //Enable and start single burst conversion ADClZCTLO |= ADCIZSC + ENC; busy = 1; while (busy 1: 0) // Wait until conversion complete busy = ADC12CTL1 & ADClZBUSY; //Check BUSY bit (polling) in_current = ADC12MEMO & OXOFFF; // keep only low 12 bits in_temp = ADC12MEM1 & OXOFFF; // keep only low 12 bits milliamps = (float)in_current * MA_PER_BIT; tempC = ((float)in_temp*MV_PER_BIT — 986.0)/3.55; ‘7 L/ Wt“) U57m5 Zflflefier n¢4}%\ One more ADC example problem... remember its the application that makes it cool... >> Inside the Wii--mote controller is an Analog Devices ADXL330 3-axis accelerometer ——> An accelerometer generates an output voltage proportional to the force of gravity along its axis (a 3 axis accelerometer will have 3 analog outputs) 3V ——> The ADXL330 can measure to i 3g with nominal Sensitivity = 300 mV/g and a 0 g Offset: 1.5V (assuming VS 2 3V) Assume the device is lying on a perfectly flat table, what is the force along each axis? i There 15 no «pa/Ge 0-!)- a {OH/H: gc 0L\OY\5 Aé or {3 avws / I" OJ\& OLSSUmlmi we are On 1 Eav‘l‘m +‘me‘r‘e is if) O¥ Force. aAvos Eat/xi: What would be the output voltage (Xout, Your, Zout) for each axis? \ L . : ,S'V 1C m \l g! erumm EeSt\gh+ El 05 I ( f0 (sq 6k me 01:93Ceret/x‘l\ What would be the readings (in g's) if the device were rotated 90° about its Y—axis Her e. Zoot : yam : OS CL \f\ (\— /)( - \ owl-‘— 8 AS‘JEVME ‘\$ F0458: gout Luau”, AecreafiQ “Pfom L‘SV +0 1.5V Wkike >(0u‘i WOOL; (Increase ‘QFOM Lb‘x/ ’lOuJarcl l-Cév What would be the output voltage along a given axis assuming a force of +2 g's? +3g's? 265 :> {Q53<-3v/3B+l.€v .—. gm 2?.le LR {VB 4/ ’W W CJ‘ g/ U0 < f} K/ + (A K i ' 35 => (#3580346; + \.SV :0. (a V How should be setup an ADC12 to interface with the ADXL330? What FSR do we need (i.e. How should we configure the Vref+ and Vref—)? Vazg LUV we LL)&W+ +0 WiQCLSc/fé 710 ’ +35 4Kme wag: Q.{l/ W‘Il/ work 9 39+ U9 PEF25; er REED“) \xke CUWU‘J’ Ma‘i’EW QXCLVnP/‘é’ What resolution (in mV and in g's) will we have Q£50\U4\LOV\1 Q.t'>’V' 0v H How would we configure the control and memory control registers :9 Se‘iutb Voi‘ikxé’. QQQQTQWQGS 15711152. CurreA-i me+er c) Lrt‘ PUJ‘. $Q3 40-9/3“ A’i'9tj HZeE :DCJOQU meeé burs‘i MOAQ (W‘sc:‘\ 0) SLMWMLV’ JrC Cu~rrem+ me‘Ler §(+e”\P Salsa” QXCgvKPlé; For an application like the Wii—mote we would need to take periodic measurements several times a second -> This can be achieved by using what we know... Use Timer B to measure time and take ADC measurements at desired intervals Lei "bimerB memgure 0,0\ seconcis 'i’l‘flEin we'll be SCvaxP “'43 (kCC‘é‘fiVCy’lA «shew every (“0‘ $6; Uajh'l l6 E “C (“Lime—W > mek$_‘éim€3 2 m eks—‘ETMQ :— éi’mfl.r~ OLCCQ l‘eV‘Ome‘i-QV‘(> : WV“) DUAC+ {on re CKCS’S J 3 E //I Cfl dCL‘i Ck Or figuring out how to use ADC12 timing capabilities for repeated measurements >> See TI examples fet440__adc12_06.c and fet440_adc12_07.c #define MV_P1ER_BIT #define G_PER_MV /* 0.610 // =2.5V/4096 0.00333 // =1/300 mV/g (sensitivity) Global Variables */ float g_X, g_Y, g_Z; void setUpADC12() { // // // // // // // // // // // // // // // // // // // // // // // // // This function sets up the ADC12 to read from ADXL330 3—axis accelerometer Initialize control register ADC12CTLO = 0110 0110 0011 0000 SHTlx and SHTOx = 66h (both 128 clks), MSC = 1 = burst mode on REFZ_5V = 1 (Vref+ = 2.5V), REFON = 1 = use internal reference voltage and ADC120N = l = turn ADC on ADC12CTLO = SHTO_6 + SHT1_6 + MSC + REF2_5 + REFON + ADC120N; Initialize control register ADC12CTL1 = 0000 0010 0000 0010 CSTART ADDx = 0000 = start conversion with ADC12MEMO, SHSx = 00 = use SW conversion initiation trigger, ADC1ZSC bits SHP = 1 = SAMPCON signal sourced from sampling timer, ISSH = 0 = sample input signal not inverted, ADC12DIVx 000: divide ADC12CLK by 1, ADC1ZSSEL=00= ADC clock ADC1ZOSC (~5 MHz), CONSE01 = CONSE00 = ADC1ZBUSY ADC12CTL1 = sequence of channels converted once, 0 = no ADC operation active SHP+CONSE00; II II |--'@ Set conversion memory control registers for 3 input ADC12MCTLO: EOS = 0, SREF =001 = voltage refs = GND INCHX = 0101 = X axis data is on pin A5 ADC12MCTLO = SREF_1 + INCH_5; channels to Vref+ Set conversion memory control registers for 3 input ADC12MCTL1: EOS = 0, SREF =001 = voltage refs = GND INCHx = 0110 = Y axis data is on pin A6 ADC12MCTL1 = SREF_1 + INCH_G; channels to Vref+ ADC12MCTL2: EOS = 1, SREF =001 = voltage refs = INCHX = 0111 = Z axis data is on pin A7 ADC12MCTL1 = SREF_1 + INCH_7 + EOS; GND to Vref+ Set Port 6 Pins 5, 6 & 7 to FUNCTION mode (=1) for ADC12 P65EL = P65EL | (BIT5|BIT6|BIT7): } Here's one way the accelerometer function could be implemented void accelerometer() { unsigned int in_X, in_Y, in_Z; //Enable and start single burst conversion through 3 channels ADC12CTLO |= ADC125C + ENC; busy = while (busy != 0) busy in_X - in_Y in_Z 1: // Wait until conversion complete = ADC12CTL1 & ADC1ZBUSY; //Check BUSY bit (polling) ADC12MEMO & 0x0FFF; // keep only low 12 bits ADC12MEM1 & 0x0FFF; // keep only low 12 bits ADC12MEM2 & OXOFFF; // keep only low 12 bits // Now convert ADC12 measurement to G's g X in_X*MV_PER_BIT * G_PER_MV; in_Y*MV_PER_BIT * G_PER__MV; in_Z*MV_PER_BIT * G_PER_MV; ...
View Full Document

Page1 / 12

lect14_notes - Foundations of Embedded Systems A Term Fall...

This preview shows document pages 1 - 12. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online