MCU Examples.com
PIC Microcontroller Project Examples, free source codes and resources collection.


Automated checking weighing system

PIC assembly code listing of automated check weigher - macros and functions

;Program Macros and Functions
;Program Macros
;UART Initialization Macro
;=============================================================================; The macro is used to initializes Universal Asynchronous Receiver Transmitter 
; module with a Baud rate of 9600bps and the crystal used is a 20MHz crystal.
;=============================================================================

Initialise_UART  macro      ; initialize for 9600bps with 20Mhz crystal

; Setting PORTC 7th pin as input to receive serial data from the weighing 
; scale and PORTC 6th pin as output to send serial data to the computer for 
; testing the system. 

 banksel TRISC
 bsf     TRISC,7         ;I/p to MCU
 bcf     TRISC,6         ;O/p from MCU

; Decimal value 129 (from the PIC16F877A datasheet) is written to SPBRG 
; register since the desired baud rate is 9600bps and the crystal used is 
; 20MHz.

 banksel SPBRG 
 movlw   .129        ; literal value .129 is moved to Working Register
 movwf   SPBRG    ; decimal value of 129 in Working Register is moved to SPBRG

; Since the desired baud rate is high 9600bps and the transmission mode is 
; asynchronous the second bit 'BRGH' in TXSTA register needs to be set and 
; fourth bit 'SYNC' needs to be cleared.
 
 banksel TXSTA         ; Bank containing TXSTA register is selected 
 bsf     TXSTA,BRGH    ; BRGH bit is set since transmission mode is high 
; speed asynchronous transmission

bcf     TXSTA,SYNC    ; the SYNC bit is cleared since the transmission mode 
; is asynchronous 


; In order to receive or send data the RC7 and RC6 pins need to be configured 
; as serial port pins and according to the system the data needs to be 
; received continuously. 

 banksel RCSTA        ; Bank containing RCSTA is selected
 bsf     RCSTA,SPEN    ; 7th bit of RCSTA register 'SPEN' is set to configure 
                    ; RC7 and RC6 pins as serial port pins (serial port 
                    ; enabled)

 bcf RCSTA,CREN        ; Continuous reception of data is disabled
 nop
 bsf RCSTA,CREN        ; Continuous reception of data is enabled by setting 
                    ;   the 'CREN' bit
 banksel RCREG
 movf    RCREG,W        ; Making sure that there are no framing errors 
                        ; initially, by moving the value in RCREG to Working 
                        ; Register
 banksel PIE1            ; Bank containing PIE1 register is selected
 bsf     PIE1,RCIE        ; Since a data byte reception is identified by an 
                        ; interrupt RCIE is set to enable USART receive 
                        ; interrupt 
banksel PORTB            ; Bank containing PORTB is selected before ending the 
                        ; macro
 endm
;________________________________________




Delay Macro ;============================================================================= ; A delay macro designed to be used in a program where a 20MHz oscillator is ; used. In this macro the value given in par1 is taken and it is decreased 1 ; by 1 until zero and each time the value is decreased by 1 the program is ; delayed almost by 1ms before another literal 1 is reduced from the current ; value. By this method it is possible to get the delay time defined by the ; par1 value in milliseconds. ;============================================================================= pausems macro par1 ; par1 is the delay time required ; Labels only for the macro are defined local Dec_Loop local Delay_Loop_1 local Delay_Loop_2 local Decrease local Delay_1ms local exit movlw HIGH par1 ; High part of the parameter 'par1' is saved to ; the Working Register movwf HIprt ; Value in the Working Register is moved to the ; HIprt variable movlw LOW par1 ; Low part of the parameter 'par1' is saved to ; the Working Register movwf LOprt ; Value in the Working Register is moved to the ; LOprt variable Dec_Loop movf LOprt, F btfsc STATUS, Z ; Value in LOprt is checked for zero goto Decrease ; If the value is zero program jumps to Decrease call Delay_1ms ; If the value is not zero a 1ms delay is given decf LOprt, F ; After the delay the value in LOprt is decremented by ; 1 and the result is saved in LOprt variable goto Dec_Loop ; Program goes to Dec_Loop Decrease movf HIprt, f btfsc STATUS, Z ; Value in HIprt is checked for zero goto exit ; If the value is zero it means that the value ; in both HIprt and LOprt is zero so the value ; is decreased up to zero so the program exits ; from the macro by jumping to exit. call Delay_1ms ; If the value in HIprt is not zero again 1ms ; delay is given decf HIprt, f ; Value in HIprt is decreased by 1 decf LOprt, f ; Value in LOprt is decreased by 1 goto Dec_Loop ; The Program jumps to Dec_Loop ; This is the function written inside the macro to give a delay of ; approximately 1ms. 1 instruction takes 0.2 microseconds to execute when a ; 20MHz oscillator is used. Delay time required is 1ms therefore number of ; instructions required to get 1ms delay is 1ms/0.2us = 5000 so two loops were ; made to execute 5000 instructions where each loop executes almost 2500 ; instructions when each exits from their respective loops. Delay_1ms movlw .250 ; Literal 250 is moved to the Working Register. movwf LOOPcnt1 ; Value in Working Register is moved to LOOPcnt1 ; variable. movlw .250 ; Literal 250 is moved to the Working Register. movwf LOOPcnt2 ; Value in Working Register is moved to LOOPcnt2 ; variable. ; Value in LOOPcnt1 is decreased by one each time as the program goes one loop ; in Delay_Loop_1 thereby executing almost 2500 instructions when the program ; exits from the Delay_Loop_1 Delay_Loop_1 clrwdt ; Watch Dog Timer is cleared since the program ; continues in the loop for a long time. The ; instruction takes one instruction cycle ; 5 nop command are given to get the loop to have 10 instruction cycles per ; loop. Each nop command takes one instruction cycle to execute. nop nop nop nop nop clrwdt ; Watch Dog Timer is cleared and the instruction takes ; one instruction cycle decfsz LOOPcnt1, f ; Value in LOOPcnt1 is decremented by 1 and the result ; is stored in LOOPcnt1. For decrementing the value in ; LOOPcnt1 by 1 it takes one instruction cycle and for ; skipping is zero it takes another one instruction ; cycle. goto Delay_Loop_1 ; If the result after decreasing LOOPcnt1 by 1 is not ; zero the program jumps to Delay_Loop_1 to continue ; the loop. ; Once the value in LOOPcnt1 is zero program comes to Delay_Loop_2 where the ; value in LOOPcnt2 is decreased by one each time as the program loops thereby ; executing almost another 2500 instructions when the program exits from the ; Delay_Loop_2 and hence 5000 instructions executed when exiting from the ; function. Delay_Loop_2 clrwdt nop nop nop nop nop clrwdt decfsz LOOPcnt2, f goto Delay_Loop_2 return exit endm ; End of the pausems macro. ;________________________________________

;Program Functions ;Function to Multiply a Value by 10 ;============================================================================= ; This is a function developed to multiply the value in mul_x variable by 10 ; and save the result in mul_z ;============================================================================= multiply_by_10 ; xy x<2 banksel mul_z ; Bank containing mul_z is selected clrf mul_z ; mul_z variable is cleared movlw .10 ; Literal value 10 is taken to the Working Register ; since the multiplying factor is 10 movwf mul_y ; Value in working register is moved to mul_y variable movf mul_x,W ; value in mul_x, the value that needs to be multiplied ; by 10, is taken to the Working Register ; This loop keeps on adding the value in the Working Register to the value in ; mul_z until the value in mul_y , which is 10, is decremented by one upto ; zero. ; This process is equivalent to multiplying the value in the Working Register ; by 10.Program exits from the loop once the value in mul_y is zero. add_10_times addwf mul_z,F ; Value in working register is added with value in ; mul_z decfsz mul_y,F ; Each time the value in Working Register is added ; with value in mul_z the value in mul_y is ; decremented by one goto add_10_times ; If the value in mul_y is not zero the program goes ; back to add_10_times movf mul_z,W ; Once the value in mul_y is zero the value in mul_z ; is taken to the Working Register before the program ; returns from the function return ;________________________________________ ;Function to Multiply a Value by 100 ;________________________________________ ;============================================================================= ; This is a function developed to multiply the value in mul_x variable by 100 ; and save the result in mul_z ;============================================================================= multiply_by_100 ; xy x<2 banksel mul_z ; Bank containing mul_z is selected clrf mul_z ; mul_z variable is cleared movlw .100 ; Literal value 100 is taken to the Working Register ; since the multiplying factor is 100 movwf mul_y ; Value in working register is moved to mul_y variable movf mul_x,W ; value in mul_x, the value that needs to be ; multiplied by 100, is taken to the Working Register ; This loop keeps on adding the value in the Working Register to the value in ; mul_z until the value in mul_y , which is 100, is decremented by one up to ; zero. This process is equivalent to multiplying the value in the Working ; Register by 100.Program exits from the loop once the value in mul_y is zero. add_100_times addwf mul_z,F ; Value in working register is added with value in mul_z decfsz mul_y,F ; Each time the value in Working Register is added ; with value in mul_z the value in mul_y is ; decremented by one goto add_100_times ; If the value in mul_y is not zero the program goes ; back to add_100_times movf mul_z,W ; Once the value in mul_y is zero the value in mul_z ; is taken to the Working Register before the program ; returns from the function return ;________________________________________ ;Function to Identify the Starting Point Of Data Packet from the 40 Data Bytes Saved ;________________________________________ ;;=============================================================================; When the program comes here there are data bytes saved from register 0x40 to ; 0x68 by indirect addressing. The starting point of a complete data packet ; from the weighing scale is identified by this function and the starting ; ASCII character is assumed to be 'B'. ;============================================================================= String_start ; Initially starting address value, where the 40 data bytes are saved, is ; moved to the FSR register. movlw 0x40 movwf FSR check_string_start movf INDF,W ; Value in INDF Register is taken to Working Register ; (simillar to taking the value from the FSR Register) ;***************************************************************************** xorlw 'B' ; Exclusive OR operation between the value in Working ; Register and literal ASCII character B btfsc STATUS,Z ; Similarity between the value in Working Register and ; literal ASCII character B is checked by checking the ; Z bit of the STATUS register goto process_weight_val ; If Z is set it means that the two values are ; equal therefore the program jumps to the label ; process_weight_val which is found in the main ; program ;***************************************************************************** incf FSR,F ; If the two values did not match the Z bit is clear ; and the value in FSR register is incremented by one movf FSR,W ; Then the value in FSR Register taken to the Working ; Register xorlw 0x68 ; Exclusive OR operation between the value in the ; Working Register and the literal 0x68 where 0x68 is ; the address value of the final byte of the 40 byte ; string is saved. btfss STATUS,Z ; Equality of the value in the Working Register and ; the literal 0x68 is checked by checking the status ; of the Z bit in the STATUS Register goto check_string_start ; Z clear means that the values did not match ; therefore the program jumps to ; check_string_start label in the function goto start ; Z set means that the two values had matched ; therefore the program jumps to start label in ; the main program return ;________________________________________ ;Function to Transmit a Value from the PIC to the Computer ;________________________________________ ;============================================================================= ; This function is used to transmit a data byte through the serial port RC6 ; but before calling this function the value that is to be transmitted needs ; to be in the Working Register ;============================================================================= UART_Print_Char banksel TXREG ; Bank containing TXREG is selected movwf TXREG ; The data that is to be transmitted is moved to the ; TXREG register ;***************************************************************************** banksel TXSTA bsf TXSTA,TXEN ; To transmit data transmission is enabled banksel PIR1 ; Bank containing PIR1 is selected ;***************************************************************************** ; The data in the TXREG register is not directly transmitted instead it is ; moved to the TSR register after the stop bit of the previous data loaded to ; TSR register is sent when this occur the TXIF flag bit in PIR1 register is ; set so by checking the TXIF flag bit it is possible to check whether the ; data transmission is complete. chk_again btfss PIR1,TXIF ; checking TXIF flag bit goto chk_again ; if TXIF is not set the program goes to ; chk_again to check TXIF flag bit, if TXIF flag ; bit is set the program exits from the macro ; since the desired data byte is sent. RETURN