Embedded Systems Interfacing PIC with external devices Analog to digital Converter Eng. Anis Nazer Second Semester 2016-2017
What is the time?
What is the time?
Definition Analog: can take any value Digital: takes a set of fixed values Examples of analog things : temperature velocity distance etc Examples of digital things : light: ON, OFF number of heartbeats in a minute number of students in lecture
Example: Analog Signal Voltage Time
Example: Digital Signal Grade Distribution [ 18-20 ] 3 [ 16-18 ) 5 [ 14-16 ) 7 Grade Range [ 12-14 ) [ 10-12 ) [ 8-10 ) [ 6-8 ) [ 4-6 ) 2 4 5 9 12 [ 2-4 ) 0 [ 0-2 ) 0 0 2 4 6 8 10 12 14 Number of students
Advantages What are the advantages of digital systems? What are the advantages of analog systems?
Problem Almost all real life signals are analog How to deal with them using digital systems? 1) convert analog signal to digital signal 2) process converted signal using a digital processor (CPU, microcontroller, ) 3) convert signal back to analog
ADC Analog Input ADC Digital Output in binary
Analog to digital converter ADC: a device that takes an analog value and converts it to a digital value Analog input: A value within a predetermined range (Vmin to Vmax) Digital output: a number between 0 and Nmax Nmax is determined by the number of digital output pins of the converter: ex: an 8 bit converter has an output range: min: b'0000 0000' 0 max: b'1111 1111' 255 what is the range if the converter has 10 bits?
ADC input/output Vmax Nmax Vmin 3 2 1 0 Analog Input Digital Output
ADC operation the analog input is converted to a number this means that a range of analog input is converted to the same digital output Definitions: Vmin, Vmax: range of possible analog input Nmax: maximum digital outuput Step size = (Vmax Vmin)/Nmax
ADC operation How to calculate the output given a certain input Vin? output = (Vin Vmin) / step size note: the result should be rounded up or down Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the step size? what is the digital output if the input is 0 V, 3 V, 1.5V, 2.3 V, 1.2V? what is the input if the digital output is b'0110 1101', b'1100 1010'?
Solution Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the step size? step size = ( 3 0 ) / 255 = 0.011765 V
Solution Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the digital output if the input is 0 V, 3 V, 1.5V? Vin = 0 Out = ( 0-0) / 0.011765 = 0 Out = b'0000 0000' Vin = 3 V Out = (3-0) / 0.011765 = 255 Out = b'1111 1111' Vin = 1.5 V Out = (1.5-0) / 0.011765 = 127.5 Out = 127 or 128 = b'0111 1111' or b'1000 0000'
Solution Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the digital output if the input is 2.3 V, 1.2V? Vin = 2.3 Out = ( 2.3-0) / 0.011765 = 195.5 Out = 195 or 196 = b'1100 0011' or b'1100 0100' Vin = 1.2 V Out = (1.2-0) / 0.011765 = 102 Out = b'0110 0110'
Solution Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the input if the digital output is b'0110 1101'? Out = (Vin Vmin) / step size Vin = Out * step size + Vmin Out = b'0110 1101' = 109 Vin = 109 * 0.011765 + 0 = 1.2824 V The input is a range input range: 1.2824 < Vin < 1.2941 (if the ADC rounds down) or 1.2706 < Vin < 1.2824 (if the ADC rounds up)
Solution Ex: Assume that Vmin = 0V, Vmax = 3 V and we have an 8 bit ADC what is the input if the digital output is b'1100 1010'? Out = b'1100 1010' = 202 Vin = 202 * 0.011765 + 0 = 2.3765 V The input is a range input range: 2.3765 < Vin < 2.3882 (if the ADC rounds down) 2.3647 < Vin < 2.3765 (if the ADC rounds up)
Practical considerations An ADC takes some time to convert an input value Usually the converter has clock signal input (ADC_CLK) Each bit takes one pulse to convert So, the conversion time is approximately ADC_CLK period times number of bits The analog input should not change during this time
Practical considerations during the conversion, the analog input should be held constant... why? A special circuit is used to hold the analog value Sample and hold circuit:
Practical considerations So, to perform a conversion, you need to 1) start conversion 2) hold the analog value 3) wait until conversion is finished this time depends on the number of bits 4) proccess the result of conversion
PIC internal ADC Some PICs have an internal ADC module PIC16F877A has a 10 bit converter It has an 8 channel ADC: you can convert up to 8 analog signals the channels are multiplexed to a single ADC you can select the channel in the program only one conversion is possible at a given time
ADC module Pins that can be used as Analog inpupts: AN <0:7> To use the pin as analog input, you have to select the pin as an input through the TRIS register Registers to control ADC: ADCON0 (in bank 0) ADCON1 (in bank 1) Registers that hold the result: ADRESH: Most significant (in bank 0) ADRESL: Least significant (in bank 1)
ADC module ADCON0: ADON: turn the ADC on 0 : ADC module is shut off and consumes no power 1 : ADC module is operating
ADC module ADCON0: GO/DONE : 1 conversion is in progress, setting this to 1 will start the conversion process 0 conversion is not in progress, bit is automatically cleared when conversion in finished
ADC module ADCON0: CHS<2:0>: select ADC channel 000 Channel 0 (AN0) 001 Channel 1 (AN1) 010 Channel 2 (AN2) 011 Channel 3 (AN3) 100 Channel 4 (AN4) 101 Channel 5 (AN5) 110 Channel 6 (AN6) 111 Channel 7 (AN7)
ADC module ADCON0: ADCS0, ADCS1: ADC clock select 00 F_OSC / 2 01 F_OSC / 4 10 F_OSC / 8 11 Internal ADC module RC oscillator
ADC module ADCON1: ADFM: result format, 0 : left justified (ADRESH<7:0> with ADRESL<7:6> ) 1: right justified (ADRESH<1:0> with ADRESL<7:0> ) PCFG3-PCFG0: ADC configuration bits
ADC module Steps to use ADC module in the PIC 16F877A: Configure ADC configure pins, Vref, Analog pins (ADCON1) select channel (ADCON0) select ADC clock (ADCON0) turn ADC on (ADCON0) Wait for the ADC to acquire the analog value (Sample time) Start conversion (set GO/DONE bit ADCON0) Wait until conversion is finished ( wait until GO/Done is 0 ) Read result ( ADRESH:ADRESL )
ADC application Assume you have an analog input between -2V and 2 V, we need to convert this analog input and display the equivalent digital value on the output pins Questions: Which channel is suitable Which ports are used (inputs/outputs) How to connect the circuit
ADC application Assume you have an analog input between -2V and 2 V, we need to convert this analog input and display the equivalent digital value on the output pins Which channel is suitable? we need Vref- =-2V, and Vref+ = 2V and we need a single channel, from the table PCFG<3:0> could be one of the following: 1000, 1011, 1100, 1101, 1111 Assume we want to use ADC channel 4 PCFG<3:0> = 1100, CHS<2:0> = 100
ADC application Assume you have an analog input between -2V and 2 V, we need to convert this analog input and display the equivalent digital value on the output pins Which ports are used (inputs/outputs) input: AN4 (RA5), so we need to set TRISA<5> to 1 RA2, RA3 inputs for Vref- and Vref+ outputs: 10 bits we can use PORTB with two bits from PORTC
ADC application Assume you have an analog input between -2V and 2 V, we need to convert this analog input and display the equivalent digital value on the output pins How to connect the circuit PORTA<5> connected to the analog input PORTC<1:0> and PORTB<7:0> outputs connected to LEDS Vmin connected to AN2 Vmax connected to AN3
ADC application Circuit diagram:
ADC application ADCON0 setup ADON = 1 GO/DONE = 0 CHS<2:0> = channel 4 100 ADCS<1:0> = 00 => ADCON0 = B'0010 0001'
ADC application ADCON1 setup ADFM = right justified = 1 PCFG<3:0> = 1100 => ADCON1 = B'1000 1100'
ADC application Program: initialize ports: RA5, RA2, RA3 inputs PORTB output, RC1, RC0 output initialize ADC (ADCON0 and ADCON1) Loop delay for sampling time Start conversion (ADCON0.GO_DONE = 1) Wait until end of conversion ( while ADCON0.GO_DONE not 0 ) display result on LEDS ADRESL PORTB ADRESH PORTC
ADC application - Program Initialize ports TRISA = 0xFF; TRISB = 0; TRISC = 0; Initialize ADC ADCON0 = 0b00100001; ADCON1 = 0b10001100;
ADC application - Program Start Conversion ADCON0.GO_DONE = 1; Wait until end of conversion while(adcon0.go_done!= 0) ; Display the conversion result PORTB = ADRESL; PORTC = ADRESH;
ADC application Complete program void main() { TRISA = 0xFF; TRISB = 0; TRISC = 0; ADCON1 = 0b10001100; ADCON0 = 0b11100001; while (1) { Delay_ms(10); // delay for acquisition time ADCON0.GO_DONE = 1; // start conversion while(adcon0.go_done!= 0) ; // wait till conversion is done PORTB = ADRESL; // put result on output ports PORTC = ADRESH; Delay_ms(10); // delay for next conversion } }
ADC application Extra :) Complete program in assembly: #include "p16f877a.inc" C1 equ 0x20 C2 equ 0x21 ORG GOTO 0x00 start ORG 0x04 start BSF STATUS, RP0 MOVLW 0xFF MOVWF TRISA CLRF TRISB CLRF TRISC MOVLW B'10001100' MOVWF ADCON1 BCF STATUS, RP0 MOVLW B'00100001' MOVWF ADCON0 loop CALL delay BSF ADCON0, GO_DONE wait BTFSC ADCON0, GO_DONE GOTO wait BSF STATUS, RP0 MOVF ADRESL, 0 BCF STATUS, RP0 MOVWF PORTB MOVF ADRESH, 0 MOVWF PORTC CALL GOTO delay loop delay...... ; delay subroutine RETURN END
ADC application 2 Assume that you want to measure the value of a resistor ( 0-15K W ) and you want to display the value of the resistor on an LCD (like a digital multimeter) Questions: how many inputs / Outputs are needed? Which PIC is suitable? How to connect the pins of the PIC?
ADC application Use the ADC module of the PIC16F877 to measure a resistor value ( between 0-15K) and display result on an LCD Questions: How many pins are required? 1 analog input 6 for LCD How to connect the pins? AN0 : analog input PORTC to LCD
ADC application The resistance to be measured is connected to form a voltage divider with a resistor Review voltage divider: V X =( R X R+R X ) V DD
Voltage divider Assume that VDD = 5 V, R = 5 K What is Vx if RX = 3 K? What is Vx if RX = 10 K? What is the minimum, maximum value of Vx?
Voltage divider Write a formula to calculate Rx given a value of Vx : V X =( R X R+R X ) V DD V X (R+R X )=R X V DD V X R+V X R X =R X V DD V X R=R X V DD V X R X V X R=R X (V DD V X ) R X = V X R V DD V X
ADC application How to calculate the value of R Inside PIC we have a number N that reflects the voltage Vx N is between 0 and 1023 Vx is between 0 and 5V N = V X 0 step size = V X = 5 N 1023 V X 5 1023 = 1023V X 5
ADC application: Circuit digram
ADC application ADCON0 setup: channel 0 CHS<2:0> = 000 ADON = 1 GO_DONE = 0 ADCS<1:0> = 10 => ADCON0 = B'1000 0001' = 0x81 ADCON1 setup: ADFM = 1 (right justified) PCFG<3:0> = 1110 (AN0 analog, Vmin=0, Vmax = 5V) => ADCON1 = B'1000 1110' = 0x8E
ADC application - Program void main() { int N; float Vx, Rx; char s[20]; TRISA = 0x01; // configure ADC ADCON1 = 0x8E; ADCON0 = 0x81; TRISC = 0; Lcd_Init(&PORTC); Lcd_Cmd(LCD_CLEAR); Lcd_Cmd(LCD_CURSOR_OFF); Lcd_Out(1,1,"R = "); while ( 1 ) { Delay_ms(1); ADCON0.GO_DONE = 1; // start // wait till end of conversion while( ADCON0.GO_DONE == 1); N = ADRESH; N = N << 8; // shift left 8 bits N = N + ADRESL; // calculate value of resistor Vx = 5.0 * N / 1023.0 ; Rx = ( 5.0*Vx ) / (5.0 Vx); // display value on LCD FloatToStr(Rx, s); Lcd_Out(1,5,s); Lcd_Out_Cp(" K"); } Delay_ms(100); }