LIST P = PIC16F877A ;declares the chip to be used
#INCLUDE "P16F877A.INC" ;Includes for resolving the
;SFR locations of this particular chip
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _LVP_OFF
;This directive sets the configuratuion
;bits of the controller
; DEFINES
;*******************************************************************************
LEDEN EQU .01 ; for enabling LED array ON PORTC
LATCH EQU .00 ; for latching the relays ON PORTC
BUZZER EQU .05 ; buzzer on RB5 of PORTB
DIG1 EQU .03
DIG2 EQU .02
DIG3 EQU .01 ; Seven segment digit enable transistors on these
DIG4 EQU .00 ; PORTB pins
;******************************************************************************
;GENERAL PURPOSE REGISTERS
cblock 20h
wait_cnt ; variable which holds the timing
delay_var1
delay_var2 ; For PIC16F877A RAM starts from 20H adress.
delay_var3 ; variables used for delay generation
digit1
digit2 ; These 4 vriables hold the value to be displayed in each digit
digit3 ;
digit4
rxtemp ; temparary holder of received data
stringcnt ; variable used to count the postion index of string to be transmited
endc
;***********************MAIN PROGRAM*******************************************
; reset location of the PIC, Execution starts from here.
ORG 0X00 ; RESET VECTOR
MOVLW 00H
MOVWF PCLATH
CLRF STATUS ; INITIALISE BANK AND PAGES
GOTO start ; jump to the programe area
;********************************************************************************
org 04h
retfie ;This part takes care of the intrupt locations
;Interupts are not enabled ,but to make sure....
;********************************************************************************
look_up ; This subroutine should be placed within the botton 255 locations of PIC programe memmory- like this!
;This subroutines returns the segment pattern of
addwf PCL,F ;digit to be displayed
retlw b'00111111' ;'0'
retlw b'00000110' ;'1'
retlw b'01011011' ;'2'
retlw b'01001111' ;'3'
retlw b'01100110' ;'4'
retlw b'01101101' ;'5'
retlw b'01111101' ;'6'
retlw b'00000111' ;'7'
retlw b'01111111' ;'8'
retlw b'01101111' ;'9'
retlw b'00000000' ; This is for blanking a digit if required
;*************************************************************************************************
id_string ; This lookuptable will return the string to be send to PC on 'a' Command
addwf PCL,f
DT " This is 'MICROMASTER' from Microcode Solutions;connected"
DT " in the communication port of your system",0Dh,0Ah,0
;**************************************************************************************************
salute_string ;; This lookuptable will return the string to be send to PC on 's' Command
addwf PCL,f
DT " You are learning Serial port usage? "
DT " All the best",0Dh,0Ah,0
;*************************************************************************************************
start
call ports_ini ;call the subroutine to configure the ports as input or output
call board_ini ;configure the peripherals to avoid unwanted current drain
call var_ini ;initialise all the required variables.
call usart_ini ;initialises the onboard serial port of PIC
goto mainline ;goto mainline of the programe
;*****************************************************************************************
mainline
btfss PIR1,RCIF ; check weather any data received from serial port
goto xx ; if no just go and do the display
bcf PIR1,RCIF ; if yes process the data received
movfw RCREG
movwf rxtemp ; copy to a temparary register
movfw rxtemp
xorlw 'a'
btfsc STATUS,Z
call id_send ; if the received letter is 'a' send this string
movfw rxtemp
xorlw 's' ;if the received letter is 's' send the following string
btfsc STATUS,Z
call salute_send
xx call sevsegdisp ; this routine handles the seven segment display
goto mainline ;
;************************************************************************************************
;Here onwards functions for the programe
;**************************************************************************************************
id_send
clrf stringcnt ; clear the counter
loopagn movfw stringcnt ;take the count in working register and call string table
call id_string ; returns with the letter to send
xorlw 00h ;check weather it is 0
btfsc STATUS,Z ; if 0 return
return
call transmit ; else transmit the letter
call sevsegdisp
incf stringcnt,f ; repeat this to send the entire string
goto loopagn
;***************************************************************************************************
salute_send
clrf stringcnt
loopagan movfw stringcnt
call salute_string ; just do as the previous string
xorlw 00h
btfsc STATUS,Z ; only the text changes
return
call transmit
call sevsegdisp
incf stringcnt,f
goto loopagan
;****************************************************************************************************
usart_ini
bsf STATUS,RP0 ;switch to bank1
bsf TRISC,6 ; as per datasheet these pins have to be made input .
bsf TRISC,7
clrf TXSTA ; TXSTA=0
movlw .25 ; SPBRG = .25 for baud9600(Datasheet)
movwf SPBRG
bsf TXSTA,TXEN ; TXSTA.TXEN=1 -TRANSMIT ENABLE
bsf TXSTA,BRGH ; High speed
bcf PIE1,TXIE ; PIE1.TXIE=0 -NO INTS
; bsf PIE1,RCIE ;receive interupt enabled
bcf STATUS,RP0 ; back to bank0
bsf RCSTA,SPEN ; RCSTA.SPEN=1 -RC.6 ANS RC.7 FOR SCI
bcf RCSTA,RX9
bsf RCSTA,CREN ; continius receive enabled
return
;********************************************************************************************
transmit
; this routine transmits a 8 bit data
movwf TXREG ; TXREG=trans_data; // 8BIT DATA
clrwdt
btfss PIR1,TXIF ; wait until transmition complete to return
goto $-2
return
;********************************************************************************************
sevsegdisp ;This handles seven segment display
movfw digit1 ; using the method of digit multiplexing
call look_up
movwf PORTD ; Segment pattern of digit1 to PORTD
bsf PORTB,DIG1 ; Select digit1
call delaySs ; Wait for a small delay
bcf PORTB,DIG1 ; off this digit
movfw digit2 ; pattern of digit2 to PORTD
call look_up
movwf PORTD
bsf PORTB,DIG2 ; enable second digit
call delaySs ; keep it glowing for some time
bcf PORTB,DIG2 ; off it
movfw digit3
call look_up
movwf PORTD ; patern for digit3
bsf PORTB,DIG3
call delaySs
bcf PORTB,DIG3
movfw digit4 ; pattern of digit4
call look_up
movwf PORTD
bsf PORTB,DIG4
call delaySs
bcf PORTB,DIG4 ; when this repeated glowing of each digit at high speed
return
;********************************************************************************************
var_ini movlw .0
movwf digit1
movwf digit2 ; clear all digit values to avoid garbage display
movwf digit3
movwf digit4
clrf wait_cnt
return
;******************************************************************************************
ports_ini
bsf STATUS,RP0 ;select bank1 for tris registers
bcf TRISC,LEDEN ;make the transistor driving pin output
bcf TRISC,LATCH ;make the relay latching pin output
movlw b'00000000'
movwf TRISD ; make all portd as output
bcf TRISB,BUZZER ; enable buzzer line as output
movlw b'11110000' ; make all digit selecting pins output
movwf TRISB
bcf STATUS,RP0 ;back to bank0
bcf PORTC,LATCH ;pull the latch pin low
bcf PORTC,LEDEN ;keep led array off
bcf PORTB,BUZZER ;switch off buzzer
movlw b'11110000' ;Clear all the digit selecting ..
andwf PORTB,F ;transistors
return
;****************************************************************************************
board_ini
bsf STATUS,RP0
movlw b'10000100' ; These settings are done for the board components
movwf ADCON1 ; not to interfere- not a part of this lesson.
movlw b'00001011'
iorwf TRISA,F ; analogue input with Vdd as Vref
bcf TRISA,2 ; Make sure This is output.
bcf STATUS,RP0
clrf PORTD ;clear the lines to switch of the relays.
bsf PORTC,LATCH ;enable and disable the control line.
bcf PORTC,LATCH ;latched!(relays off)
bcf PORTA,2 ; keep Disabld the LCD module.
return
;*****************************************************************************************
delaySs ; This routine creates a small delay(7mS) of processor
movlw .2 ; time enough to elude our persistence of vision .
movwf delay_var1
out_loop decf delay_var1,f ; outer most loop variable
btfsc STATUS,Z
return ; when all variables are 0 delay returns !
movlw .40
movwf delay_var2
midle_loop decf delay_var2,f ;midle loop variable
btfsc STATUS,Z
goto out_loop
movlw .35
movwf delay_var3
inner_loop decf delay_var3,f ;inner most loop
btfsc STATUS,Z
goto midle_loop ; total delay = (innerloop*middleloop*outerloop)time
goto inner_loop
;*****************************************************************************************
end ; end directive to assembler
this is an exmple program........for rs232 interface