Wrox Programmer Forums a.c. 50Hz voltage measurement trouble
 Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
 Welcome to the p2p.wrox.com Forums. You are currently viewing the Assembly Language section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developersâ€™ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
April 9th, 2008, 03:41 AM
 Registered User Join Date: Apr 2008 Location: , , . Posts: 1 Thanks: 0 Thanked 0 Times in 0 Posts
a.c. 50Hz voltage measurement trouble

I have written code in assembly language which can read a voltage and current and display it on my LCD with scaling factors for the application I need. Its fine but I cant figure out how to store numbers and use interrupts in asm. The inputs are from voltage and current transducer circuits including summer amps etc, that I have made so the input range is unipolar 0-5 volts to suit the PIC18F452 microcontroller I am using. The ac inputs need to be sampled 20 times per 50Hz cycle, that being 1000 samples
a second. The samples need to be squared, summed, the mean found and finally the square root is found to get the rms values. I am having great difficulty in doing this.So I need to make the timer read the samples 20 times per second, then store the samples. Thats the basic bit I need, and am stuck with.
Any ideas would be good. the ra0 ACD input on the PIC is fine for the voltage, which is the single part I am working on now. So in summary, I need to store the input at ra0, and at the end of the 20 stored values, just divide the total of the 20 samples by 20. Its really
simplified down but this is as far as I have managed to get on my own.

This is the working code so far, which shows the instantaneous voltage and current in real time.
-------------------------------------------------------

list p=18f452
#include p18f452.inc

;Program Configuration Registers
__CONFIG _CONFIG1H, _OSCS_OFF_1H & _EC_OSC_1H
__CONFIG _CONFIG2L, _BOR_OFF_2L & _PWRT_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _CCP2MX_OFF_3H
__CONFIG _CONFIG4L, _STVR_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
__CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H

#define scroll_dir TRISA,4
#define scroll PORTA,4 ;Push-button RA4 on PCB
#define select_dir TRISB,0
#define select PORTB,0 ;Push-button RB0 on PCB

EXTERN LCDInit, temp_wr, d_write, i_write, LCDLine_1, LCDLine_2
EXTERN UMUL0808L, FXD1608U, AARGB0, AARGB1, BARGB0

ssprw macro ;check for idle SSP module routine
movlw 0x00
andwf SSPCON2,W
sublw 0x00
btfss STATUS,Z
bra \$-8

btfsc SSPSTAT,R_W
bra \$-2
endm

variables UDATA
ptr_pos RES 1
ptr_count RES 1
temp_1 RES 1
temp_2 RES 1
temp_3 RES 1
cmd_byte RES 1
LSD RES 1
MsD RES 1
MSD RES 1

NumH RES 1
NumL RES 1
TenK RES 1
Thou RES 1
Hund RES 1
Tens RES 1
Ones RES 1

STARTUP CODE
NOP
goto start
NOP
NOP
NOP
PROG1 CODE

stan_table ;table for standard code
; "XXXXXXXXXXXXXXXX"
; ptr:
data " Voltage Output " ;0
data " S3 for reading " ;160
data " GENSET OUTPUT " ;32
data "Waiting........." ;48
data " S3=Select " ;64
data "RA4= --> RBO= ++" ;80
data " RESET to EXIT " ;96
data "Volts = " ;112
data " Current " ;128
data "Current = " ;144

start
call LCDInit

movlw B'10100100' ;initialize USART
movwf TXSTA ;8-bit, Async, High Speed
movlw .25
movwf SPBRG ;9.6kbaud @ 4MHz
movlw B'10010000'
movwf RCSTA

bcf TRISC,2 ;configure CCP1 period
movlw 0x80 ;initialize PWM duty cycle
movwf CCPR1L
bcf CCP1CON,CCP1X
bcf CCP1CON,CCP1Y

movlw 0x05 ;postscale 1:1, prescaler 4, Timer2 ON
movwf T2CON

bsf TRISA,4 ;make switch RA4 an Input
bsf TRISB,0 ;make switch RB0 an Input

;**************** STANDARD CODE MENU SELECTION *******************
;Introduction
movlw .32 ;send to LCD
movwf ptr_pos
call stan_char_1

movlw .48 ;send to LCD
movwf ptr_pos
call stan_char_2
call delay_1s ;delay for display
call delay_1s ;delay for display

;------------------ VOLT MEASUREMENT ----------------------------
btfss scroll ;wait for RA4 release
goto \$-2
btfss select ;wait for RB0 release
goto \$-2

movlw 0x00 ;voltmeter
movwf ptr_pos
call stan_char_1

movlw .48 ;RA4=Next RB0=Now
movwf ptr_pos
call stan_char_2
v_wait
btfss select ;voltmeter measurement ??
bra voltmeter
btfsc scroll ;next mode ??
bra v_wait ;NO
btfss scroll ;YES
bra \$-2 ;wait for RA4 release

;------------------ CURRENT MEASUREMENT ----------------------------
btfss scroll ;wait for RA4 release
goto \$-2
btfss select ;wait for RB0 release
goto \$-2

movlw .128 ;voltmeter
movwf ptr_pos
call stan_char_1

movlw .48 ;RA4=Next RB0=Now
movwf ptr_pos
call stan_char_2
c_wait
btfss select ;voltmeter measurement ??
bra current
btfsc scroll ;next mode ??
bra c_wait ;NO
btfss scroll ;YES
bra \$-2 ;wait for RA4 release

;-------------------------------------------------------------------
return

;************************************************* ******************

;************* STANDARD USER CODE **********************************

;------------- Voltmeter----------------------------

voltmeter
btfss select ;wait for RB0 release
bra \$-2

movlw B'01000001' ;configure A/D converter

movlw .112 ;send "Volts = " to the LCD
movwf ptr_pos
call stan_char_1
volts_again
again
goto again

movwf AARGB0 ;move ADRESH into AARGB0
movlw 0x64 ;19.5mV/step 0xC3 = 195
movwf BARGB0
call UMUL0808L

movlw 0x64 ;divide result by 200 (0x128)
movwf BARGB0
call FXD1608U

movf AARGB0,W ;prepare for 16-bit binary to BCD
movwf NumH
movf AARGB1,W
movwf NumL
call bin16_bcd ;get volts ready for LCD

call LCDLine_2 ;display A/D result on 2nd line
movf Hund,W ;get hunds
call bin_bcd
movf LSD,W ;send high digit from LSD
movwf temp_wr

movwf temp_wr
call d_write

movf Tens,W ;get tens
call bin_bcd
movf LSD,W ;send low digit x.#x
movwf temp_wr
call d_write

movf Ones,W ;get ones
call bin_bcd
movf LSD,W ;send low digit x.x#
movwf temp_wr
call d_write
movlw A'V' ;send "V" unit
movwf temp_wr
call d_write

movlw 0x20 ;3 spaces
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
movlw A'R' ;send "RB0=Exit" to LCD
movwf temp_wr
call d_write
movlw A'E'
movwf temp_wr
call d_write
movlw A'S'
movwf temp_wr
call d_write
movlw A'='
movwf temp_wr
call d_write
movlw A'E'
movwf temp_wr
call d_write
movlw A'x'
movwf temp_wr
call d_write
movlw A'i'
movwf temp_wr
call d_write
movlw A't'
movwf temp_wr
call d_write
movlw 0x20 ;2 spaces
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write

movlw "\r" ;move data into TXREG
movwf TXREG ;carriage return
btfss TXSTA,TRMT ;wait for data TX
bra \$-2
btfss select ;exit volt measurement ??
bra volts_again ;NO, do conversion again

;------------- Currentmeter--------------------------------------------
current
btfss select ;wait for RB0 release
bra \$-2

movlw B'01000001' ;configure A/D converter

movlw .144 ;send "Volts = " to the LCD
movwf ptr_pos
call stan_char_1
current_again
again1
goto again1

movwf AARGB0 ;move ADRESH into AARGB0
movlw 0xC3 ;19.5mV/step 0xC3 = 195
movwf BARGB0
call UMUL0808L

movlw 0xAA ;divide result by 100 (0x64)
movwf BARGB0
call FXD1608U

movf AARGB0,W ;prepare for 16-bit binary to BCD
movwf NumH
movf AARGB1,W
movwf NumL
call bin16_bcd ;get volts ready for LCD

call LCDLine_2 ;display A/D result on 2nd line
movf Hund,W ;get hunds
call bin_bcd
movf LSD,W ;send high digit from the LSD #.xx
movwf temp_wr
call d_write

movf Tens,W ;get tens
call bin_bcd
movf LSD,W ;send low digit x.#x
movwf temp_wr
call d_write
movlw A'.' ;send decimal point "."
movwf temp_wr
call d_write

movf Ones,W ;get ones
call bin_bcd
movf LSD,W ;send low digit x.x#
movwf temp_wr
call d_write
movlw A'A' ;send "A" unit
movwf temp_wr
call d_write

movlw 0x20 ;3 spaces
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write
movlw A'R' ;send "RB0=Exit" to LCD
movwf temp_wr
call d_write
movlw A'E'
movwf temp_wr
call d_write
movlw A'S'
movwf temp_wr
call d_write
movlw A'='
movwf temp_wr
call d_write
movlw A'E'
movwf temp_wr
call d_write
movlw A'x'
movwf temp_wr
call d_write
movlw A'i'
movwf temp_wr
call d_write
movlw A't'
movwf temp_wr
call d_write
movlw 0x20 ;2 spaces
movwf temp_wr
call d_write
movlw 0x20
movwf temp_wr
call d_write

movlw "\r" ;move data into TXREG
movwf TXREG ;carriage return
btfss TXSTA,TRMT ;wait for data TX
bra \$-2

bra current_again ;NO, do conversion again

;------------------------
inc_dc
btfss scroll ;wait for button release
bra \$-2

inc_ccpr1l
btfsc select ;increment CCPR1L ???
goto ccpr1l_out ;NO
call delay_100ms ;YES
call delay_100ms
incf CCPR1L,F ;increment CCPR1L
ccpr1l_out
movlw 0x8C ;move cursor into position
movwf temp_wr
call i_write

col1
btfss scroll ;exit?
bra pwm_out
btfsc select ;wait for RB0 press
bra col1

movf CCPR1L,W ;send PR2 register to conversion
call bin_bcd

movf MSD,W ;send high digit
movwf temp_wr
call d_write
movf MsD,W ;send middle digit
movwf temp_wr
call d_write
movf LSD,W ;send low digit
movwf temp_wr
call d_write
bra inc_ccpr1l

pwm_out
movlw 0
movwf CCP1CON ;turn buzzer off

;************************************************* ******************

;************************** ROUTINES ******************************

;----Standard code, Place characters on line-1--------------

stan_char_1
call LCDLine_1 ;move cursor to line 1
movlw .16 ;1-full line of LCD
movwf ptr_count
movlw UPPER stan_table
movwf TBLPTRU
movlw HIGH stan_table
movwf TBLPTRH
movlw LOW stan_table
movwf TBLPTRL
movf ptr_pos,W
clrf WREG

stan_next_char_1
tblrd *+
movff TABLAT,temp_wr
call d_write ;send character to LCD

decfsz ptr_count,F ;move pointer to next char
bra stan_next_char_1

movlw "\n" ;move data into TXREG
movwf TXREG ;next line
btfss TXSTA,TRMT ;wait for data TX
goto \$-2
movlw "\r" ;move data into TXREG
movwf TXREG ;carriage return
btfss TXSTA,TRMT ;wait for data TX
goto \$-2

return

;----Standard code, Place characters on line-2--------------------------
stan_char_2
call LCDLine_2 ;move cursor to line 2
movlw .16 ;1-full line of LCD
movwf ptr_count
movlw UPPER stan_table
movwf TBLPTRU
movlw HIGH stan_table
movwf TBLPTRH
movlw LOW stan_table
movwf TBLPTRL
movf ptr_pos,W
clrf WREG

stan_next_char_2
tblrd *+
movff TABLAT,temp_wr
call d_write ;send character to LCD

decfsz ptr_count,F ;move pointer to next char
bra stan_next_char_2

movlw "\n" ;move data into TXREG
movwf TXREG ;next line
btfss TXSTA,TRMT ;wait for data TX
goto \$-2
movlw "\r" ;move data into TXREG
movwf TXREG ;carriage return
btfss TXSTA,TRMT ;wait for data TX
goto \$-2

return
;----------------------------------------------------------------------

;------------------ 100ms Delay --------------------------------
delay_100ms
movlw 0xFF
movwf temp_1
movlw 0x83
movwf temp_2

d100l1
decfsz temp_1,F
bra d100l1
decfsz temp_2,F
bra d100l1
return

;---------------- 1s Delay -----------------------------------
delay_1s
movlw 0xFF
movwf temp_1
movwf temp_2
movlw 0x05
movwf temp_3
d1l1
decfsz temp_1,F
bra d1l1
decfsz temp_2,F
bra d1l1
decfsz temp_3,F
bra d1l1
return

;---------------- Binary (8-bit) to BCD -----------------------
; 255 = highest possible result
bin_bcd
clrf MSD
clrf MsD
movwf LSD ;move value to LSD
ghundreth
movlw .100 ;subtract 100 from LSD
subwf LSD,W
btfss STATUS,C ;is value greater then 100
bra gtenth ;NO goto tenths
movwf LSD ;YES, move subtraction result into LSD
incf MSD,F ;increment hundreths
bra ghundreth
gtenth
movlw .10 ;take care of tenths
subwf LSD,W
btfss STATUS,C
bra over ;finished conversion
movwf LSD
incf MsD,F ;increment tenths position
bra gtenth
over ;0 - 9, high nibble = 3 for LCD
movf MSD,W ;get BCD values ready for LCD display
xorlw 0x30 ;convert to LCD digit
movwf MSD
movf MsD,W
xorlw 0x30 ;convert to LCD digit
movwf MsD
movf LSD,W
xorlw 0x30 ;convert to LCD digit
movwf LSD
retlw 0

;---------------- Binary (16-bit) to BCD -----------------------
; xxx = highest possible result
bin16_bcd
; Takes number in NumH:NumL
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf NumH,W
andlw 0x0F
movwf Thou
movwf Hund
movwf Ones

movf NumH,W
andlw 0x0F
movwf Tens

swapf NumL,W
andlw 0x0F

rlcf Tens,F
rlcf Ones,F
comf Ones,F
rlcf Ones,F

movf NumL,W
andlw 0x0F
rlcf Thou,F

movlw 0x07
movwf TenK

movlw 0x0A ; Ten
Lb1:
decf Tens,F
btfss STATUS,C
bra Lb1
Lb2:
decf Hund,F
btfss STATUS,C
bra Lb2
Lb3:
decf Thou,F
btfss STATUS,C
bra Lb3
Lb4:
decf TenK,F
btfss STATUS,C
bra Lb4

retlw 0

;---------------------------- EEPROM WRITE -------------------------------
write_eeprom
bsf SSPCON2,SEN ;start bit
btfsc SSPCON2,SEN
goto \$-2
movlw B'10100000' ;send control byte (write)
movwf SSPBUF
ssprw
btfsc SSPCON2,ACKSTAT
goto \$-2

movlw 0x00 ;send slave address HIGH byte
movwf SSPBUF
ssprw
btfsc SSPCON2,ACKSTAT
goto \$-2

movlw 0x05 ;send slave address LOW byte(0x0005)
movwf SSPBUF
ssprw
btfsc SSPCON2,ACKSTAT
goto \$-2

bsf SSPCON2,PEN ;stop bit
btfsc SSPCON2,PEN
goto \$-2

bcf PIR1,TMR1IF ;clear TIMER1 overflow flag
clrf TMR1L ;clear registers for next overflow
clrf TMR1H

return

;************************************************* ********************
end

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is Off HTML code is OffTrackbacks are Off Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post If Else Trouble Cibressus Beginning PHP 0 May 1st, 2007 02:04 PM How to draw fix measurement lines Abhi.Win C# 0 December 23rd, 2005 12:43 PM Please i have had a Trouble hurted Wrox Book Feedback 1 June 28th, 2004 02:18 AM trouble databass Classic ASP Databases 2 August 16th, 2003 10:27 AM

All times are GMT -4. The time now is 03:15 PM.