The data acquisition process is similar to the 8-bit system above, but the binary to BCD conversion process is rather more complicated. The result is required in the range 0–4095, so the original result (0–1023) is shifted left twice to multiply it by four. One thousand (03E8) is then loop subtracted from the result to calculate the number of thousands in the number. Correct borrow handling between the high and low byte is particularly important. The process stops when the remainder is less that 1000. The hundreds digit is calculated in a similar way, but the tens calculation is a little easier as the maximum remainder from the previous stage is 99, so the high byte borrow handling is not necessary. This process is outlined in Figure 7.5, and the source code shown in Program 7.2. Interfacing PIC Microcontrollers 146 ADC8 Convert the analogue input to 8-bits and display Hardware: P16F877 (4MHz), Vref+ = 2.56, 16x2 LCD Initialise PortA = Analogue inputs (default) PortC = LCD outputs ADC = Select f/8, RA0 input, left justify result, enable LCD = default setup (include LCD driver routines) Main REPEAT Get ADC 8-bit input Convert to BCD Display on LCD ALWAYS Subroutines Get ADC 8-bit input Start ADC and wait for done Store result Convert to BCD Calculate hundreds digit Calculate tens digit Remainder = ones digit Display on LCD Home cursor Convert BCD to ASCII Send hundreds, point, tens, ones Send ‘Volts’ Include LCD routines Figure 7.3 ADC test program outline Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 146 Analogue Interfacing 147 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Project: Interfacing PICs ; Source File Name: VINTEST.ASM ; Devised by: MPB ; Date: 19 -12-05 ; Status: Fi nal version ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Demonstrates simple analogue input ; using an external reference voltage of 2.56V ; The 8-bit result is converted to BCD for display ; as a voltage using the standard LCD routines. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PR OCESSOR 16F877 ; Clock = XT 4MHz, standard fuse settings __ CONFIG 0x3731 ; LABEL EQUATES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #INCLUDE "P16F877A.INC" ; standard labels ; GPR 70 - 75 allocated to included LCD display routine count EQU 30 ; Counter for ADC setup delay ADbin EQU 31 ; Binary input value huns EQU 32 ; Hundreds digit in decimal value tens EQU 33 ; Tens digit in decimal value ones EQU 34 ; Ones digit in decimal value ; PROGRAM BEGINS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; OR G 0 ; Default start address NO P ; required for ICD mode ; Port & display setup BA NKSEL TRISC ; Select bank 1 CL RF TRISD ; Display port is output MOVLW B'00000011' ; Analogue input setup code MO VWF ADCON1 ; Left justify result, ; Port A = analogue inputs BA NKSEL PORTC ; Select bank 0 CL RF PORTD ; Clear display outputs MOVLW B'01000001' ; Analogue input setup code MOVWF ADCON0 ; f/8, RA0, done, enable CALL inid ; Initialise the display ; MAIN LOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start CALL getADC ; read input CA LL condec ; convert to decimal CA LL putLCD ; display input GO TO start ; jump to main loop ; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Read ADC input and store getADC BSF ADCON0,GO ; start ADC wait BTFSC ADCON0,GO ; and wait for finish GO TO wait MOVF ADRESH,W ; store result high byte RE TURN ; Convert input to decimal condec MOVWF ADbin ; get ADC result CL RF huns ; zero hundreds digit CL RF tens ; zero tens digit CL RF ones ; zero ones digit Program 7.1 8-bit analogue input Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 147 Interfacing PIC Microcontrollers 148 ; Calclulate hundreds BS F STATUS,C ; set carry for subtract MO VLW D'100' ; load 100 sub1 SUBWF ADbin ; and subtract from result INCF huns ; count number of loops BTFSC STATUS,C ; and check if done GO TO sub1 ; no, carry on ADDWF ADbin ; yes, add 100 back on DE CF huns ; and correct loop count ; Calculate tens digit BS F STATUS,C ; repeat process for tens MOVLW D'10' ; load 10 sub2 SUBWF ADbin ; and subtract from result INCF tens ; count number of loops BTFSC STATUS,C ; and check if done GO TO sub2 ; no, carry on ADDWF ADbin ; yes, add 100 back on DE CF tens ; and correct loop count MO VF ADbin,W ; load remainder MOVWF ones ; and store as ones digit RE TURN ; done ; Output to display putLCD BCF Select,RS ; set display command mode MO VLW 080 ; code to home cursor CA LL send ; output it to display BSF Select,RS ; and restore data mode ; Convert digits to ASCII and display MO VLW 030 ; load ASCII offset AD DWF huns ; convert hundreds to ASCII AD DWF tens ; convert tens to ASCII AD DWF ones ; convert ones to ASCII MO VF huns,W ; load hundreds code CALL send ; and send to display MO VLW '.' ; load point code CA LL send ; and output MO VF tens,W ; load tens code CA LL send ; and output MO VF ones,W ; load ones code CA LL send ; and output MO VLW ' ' ; load space code CA LL send ; and output MO VLW 'V' ; load volts code CA LL send ; and output MO VLW 'o' ; load volts code CA LL send ; and output MO VLW 'l' ; load volts code CA LL send ; and output MO VLW 't' ; load volts code CA LL send ; and output MO VLW 's' ; load volts code CA LL send ; and output RE TURN ; done ; INCLUDED ROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Include LCD driver routines ; #I NCLUDE "LCDIS.INC" ; Contains routines: ; inid: Initialises display ; onems: 1 ms delay ; xms: X ms delay ; Receives X in W ; send: Sends a character to display ; Receives: Control code in W (Select,RS=0) ; ASCII character code in W (RS=1) EN D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Program 7.1 Continued Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 148 Amplifier Interfaces Having developed the analogue input conversion and display process, we can move on to the interfacing hardware itself. Input signals often need condition- ing before being fed to the MCU analogue inputs. This can involve amplifiers to increase the signal amplitude, attenuators to reduce it, and filters to change the frequency response. For now, we will limit ourselves to DC signals and amplifiers, as these are most frequently used in MCU applications and are more straightforward. For processing of AC signals, standard references should be consulted. Figure 7.6 shows a range of different amplifiers connected to the PIC MCU. They are connected to RA0 by a multi-way switch, so that the output of each may be displayed, using the previously developed 8-bit conversion and display program (Program 7.1). The basic op-amp configurations are summarised in Figure 7.7. The op-amp (IC amplifier) is a high-gain amplifier with inverting and non- inverting inputs, with the output voltage controlled by the input differential voltage. However, since the differential gain is very high, typically >1,00,000, the operating input differential voltage is very small. As a result, we can as- sume that the gain and bandwidth (frequency response) are controlled by the external components only, and are independent of the amplifier itself. Analogue Interfacing 149 Figure 7.4 10-bit conversion circuit Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 149 When used as a linear amplifier, the feedback must be negative. Essentially, this means the feedback signal path must be connected to the minus input terminal. The basic rules for ideal op-amp circuit analysis are as follows: • Differential gain ϭ - (for voltage applied between + and – terminals) • Differential voltage ϭ 0 (terminals + and – are at the same voltage) • Input resistance = - (zero input current at + and – terminals) • Output impedance = 0 (infinite current can be sunk or source at the output) • Bandwidth = - (all frequencies are amplified equally) • Feedback is negative (signal connected from output to – terminal) These rules allow amplifier circuit analysis to be greatly simplified, and give results which are accurate enough for most applications. IC (integrated circuit) amplifiers can operate with dual or single supplies. Dual supplies, which are the norm, make the circuit design easier, because the output can swing positive and negative around 0 V. ϩ/Ϫ 15 V and ϩ/Ϫ 5 V are typical supply values, with 15 V supplies giving a higher output voltage swing. Interfacing PIC Microcontrollers 150 ADC10 Load 10-bit, right justified binary (0-1023) Multiply by 4 (0-4092) by shift left Clear BCD registers REPEAT Subtract E8 16 from low byte Subtract 3 16 from high byte Increment thousands digit UNTIL remainder < 03E8 16 (1000) REPEAT Subtract 64 16 from low byte Borrow from high byte Increment hundreds digit UNTIL remainder < 64 16 (100) REPEAT Subtract 10 from low byte Increment tens digit UNTIL remainder < 10 Remainder = ones digits RETURN Figure 7.5 10-bit binary conversion routine outline Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 150 Analogue Interfacing 151 Program 7.2 10-bit conversion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Project: Interfacing PICs ; Source File Name: TENBIT.ASM ; Devised by: MPB ; Date: 20-12-05 ; Status: Final ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Demonstrates 10-bit voltage measurement ; using an external reference voltage of 4.096V, ; giving 4mV per bit, and an resolution of 0.1%. ; The result is converted to BCD for display ; as a voltage using the standard LCD routines. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PROCESSOR 16F877 ; Clock = XT 4MHz, standard fuse settings __CONFIG 0x3731 ; LABEL EQUATES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INCLUDE "P16F877A.INC" ; standard register labels ; ; User register labels ; ; GPR 20 - 2F allocated to included LCD display routine count EQU 30 ; Counter for ADC setup delay ADhi EQU 31 ; Binary input high byte ADlo EQU 32 ; Binary input low byte thos EQU 33 ; Thousands digit in decimal huns EQU 34 ; Hundreds digit in decimal value tens EQU 35 ; Tens digit in decimal value ones EQU 36 ; Ones digit in decimal value ; ; PROGRAM BEGINS ; ORG 0 ; Default start address NOP ; required for ICD mode ; ; Port & display setup BANKSEL TRISC ; Select bank 1 CLRF TRISD ; Display port is output MOVLW B'10000011' ; Analogue input setup code MOVWF ADCON1 ; Right justify result, ; Port A = analogue inputs ; with external reference BANKSEL PORTC ; Select bank 0 CLRF PORTD ; Clear display outputs MOVLW B'01000001' ; Analogue input setup code MOVWF ADCON0 ; f/8, RA0, done, enable CALL inid ; Initialise the display ; ; MAIN LOOP ; start CALL getADC ; read input CALL con4 ; convert to decimal CALL putLCD ; display input GOTO start ; jump to main loop Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 151 Interfacing PIC Microcontrollers 152 ; ; SUBROUTINES ; ; Read ADC input and store ; getADC MOVLW 007 ; load counter MOVWF count down DECFSZ count ; and delay 20us GOTO down BSF ADCON0,GO ; start ADC wait BTFSC ADCON0,GO ; and wait for finish GOTO wait RETURN ; ; Convert 10-bit input to decimal ; con4 MOVF ADRESH,W ; get ADC result MOVWF ADhi ; high bits BANKSEL ADRESL ; in bank 1 MOVF ADRESL,W ; get ADC result BANKSEL ADRESH ; default bank 0 MOVWF ADlo ; low byte ; Multiply by 4 for result 0 - 4096 by shifting left BCF STATUS,C ; rotate 0 into LSB and RLF ADlo ; shift low byte left BTFSS STATUS,C ; carry out? GOTO rot1 ; no, leave carry clear BSF STATUS,C ; rotate 1 into LSB and rot1 RLF ADhi ; shift high byte left BCF STATUS,C ; rotate 0 into LSB RLF ADlo ; rotate low byte left again BTFSS STATUS,C ; carry out? GOTO rot2 ; no, leave carry clear BSF STATUS,C ; rotate 1 into LSB and rot2 RLF ADhi ; shift high byte left ; Clear BCD registers clrbcd CLRF thos ; zero thousands digit CLRF huns ; zero hundreds digit CLRF tens ; zero tens digit CLRF ones ; zero ones digit ; Calclulate thousands low byte tholo MOVF ADhi,F ; check high byte BTFSC STATUS,Z ; high byte zero? GOTO hunlo ; yes, next digit BSF STATUS,C ; set carry for subtract MOVLW 0E8 ; load low byte of 1000 SUBWF ADlo ; and subtract low byte BTFSC STATUS,C ; borrow from high bits? GOTO thohi ; no, do high byte DECF ADhi ; yes, subtract borrow ; Calculate thousands high byte thohi BSF STATUS,C ; set carry for subtract MOVLW 003 ; load high byte of 1000 SUBWF ADhi ; subtract from high byte BTFSC STATUS,C ; result negative? GOTO incth ; no, inc digit and repeat ADDWF ADhi ; yes, restore high byte ; Restore remainder when done BCF STATUS,C ; clear carry for add MOVLW 0E8 ; load low byte of 1000 ADDWF ADlo ; add to low byte BTFSC STATUS,C ; carry out? INCF ADhi ; yes, inc high byte GOTO hunlo ; and do next digit ; Increment thousands digit and repeat incth INCF thos ; inc digit GOTO tholo ; and repeat Program 7.2 Continued Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 152 Analogue Interfacing 153 ; Calclulate hundreds hunlo MOVLW 064 ; load 100 BSF STATUS,C ; set carry for subtract SUBWF ADlo ; and subtract low byte BTFSC STATUS,C ; result negative? GOTO inch ; no, inc hundreds & repeat MOVF ADhi,F ; yes, test high byte BTFSC STATUS,Z ; zero? GOTO remh ; yes, done DECF ADhi ; no, subtract borrow inch INCF huns ; inc hundreds digit GOTO hunlo ; and repeat remh ADDWF ADlo ; restore onto low byte ; Calculate tens digit subt MOVLW D'10' ; load 10 BSF STATUS,C ; set carry for subtract SUBWF ADlo ; and subtract from result BTFSS STATUS,C ; and check if done GOTO remt ; yes, restore remainder INCF tens ; no, count number of loops GOTO subt ; and repeat ; Restore remainder remt ADDWF ADlo ; yes, add 10 back on MOVF ADlo,W ; load remainder MOVWF ones ; and store as ones digit RETURN ; done ; ; Output to display ; putLCD BCF Select,RS ; set display command mode MOVLW 080 ; code to home cursor CALL send ; output it to display BSF Select,RS ; and restore data mode ; Convert digits to ASCII and display MOVLW 030 ; load ASCII offset ADDWF thos ; convert thousands to ASCII ADDWF huns ; convert hundreds to ASCII ADDWF tens ; convert tens to ASCII ADDWF ones ; convert ones to ASCII MOVF thos,W ; load thousands code CALL send ; and send to display MOVLW '.' ; load point code CALL send ; and output MOVF huns,W ; load hundreds code CALL send ; and send to display MOVF tens,W ; load tens code CALL send ; and output MOVF ones,W ; load ones code CALL send ; and output MOVLW ' ' ; load space code CALL send ; and output MOVLW 'V' ; load volts code CALL send ; and output MOVLW 'o' ; load volts code CALL send ; and output MOVLW 'l' ; load volts code CALL send ; and output MOVLW 't' ; load volts code CALL send ; and output MOVLW 's' ; load volts code CALL send ; and output RETURN ; done ; ; INCLUDED ROUTINES ; ; Include LCD driver routine ; INCLUDE "LCDIS.INC" ; ; Contains routines: ; init: Initialises display ; onems: 1 ms delay ; xms: X ms delay ; Receives X in W ; send: sends a character to display ; Receives: Control code in W (Select,RS=0) ; ASCII character code in W (RS=1) ; ; END ; of source code Program 7.2 Continued Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 153 Interfacing PIC Microcontrollers 154 Figure 7.6 Basic amplifier interface circuits Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 154 Analogue Interfacing 155 (d) V o = V i I o >>> I i + _ (b) _ + 0V (c) _ + V + (e) I f = V o – 0 = 0 – V 1 + 0 – V 2 R f R 1 R 2 ∴ V o = - ( (R f /R 1 ).V 1 + (R f /R 2 ).V 2 ) (f) I f = V o – V x = V x - V 1 R f R 1 V x = R f / (R 1 + R f ) . V 2 ∴ V o = (R f /R 1 ) . (V 2 – V 1 ) _ + V 1 R 1 R f V o I f 0V V 2 R 2 I 1 I 2 _ + R 1 R f V o I f 0V V 1 I f R f R 1 V 2 V x (a) + _ V i V i V i V i I i 0V R i R i R i R f R f R f V o V o V o V o I o I f I f I f I f I f I f = V o – V i = R f R i ∴ V o = (R f /R i + 1).V i V i – 0 I f = V o – 0 = R f R i ∴ V o = - (R f /R i + 1).V i ∴ V o = - (R f /R 1 ).V i + ((R f /R 1 ) + 1).V r 0 – V i I f = V o – V r = R f R i V r – V i Figure 7.7 Basic amplifier configurations: (a) non-inverting amplifier; (b) inverting amplifier; (c) inverting amplifier with offset; (d) unity gain buffer; (e) summing amplifier; (f) difference amplifier Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 155 . negative around 0 V. ϩ/Ϫ 15 V and ϩ/Ϫ 5 V are typical supply values, with 15 V supplies giving a higher output voltage swing. Interfacing PIC Microcontrollers 150 ADC10 Load 10-bit, right justified. 6/29/2006 11:38 AM Page 153 Interfacing PIC Microcontrollers 154 Figure 7.6 Basic amplifier interface circuits Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 154 Analogue Interfacing 155 (d) V o. Program 7.1 8-bit analogue input Else_IPM-BATES_ch007.qxd 6/29/2006 11:38 AM Page 147 Interfacing PIC Microcontrollers 148 ; Calclulate hundreds BS F STATUS,C ; set carry for subtract MO