Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

To develop a program for the PIC 16F84A using the MPLAB v8.86 IDE simulator soft

ID: 3860763 • Letter: T

Question

To develop a program for the PIC 16F84A using the MPLAB v8.86 IDE simulator software. The program is to function as a 10 second countdown timer which, when started, will display the number 9 on a seven segment display. The number will then be automatically decremented, displayed, decremented etc. until zero is reached. Each number is displayed for 1 second. The countdown sequence will then repeat. Objectives:

-Write the assembly code to be input into MPLAB v8.86

•Describe your program using properly structured flowcharts (main program and subroutines) .

•Demonstrate the use of subroutines e.g To initialize the peripheral registers and to set the time delays, etc .

•Demonstrate the use of indexed addressing to retrieve data from a table in memory.

•Describe the operation of the program in writing .

•Provide a properly formatted program listing

Explanation / Answer

Processor 16F84A
#include<P16F84A.inc>
__config _HS_OSC & _WDT_OFF & _PWRTE_ON

org 0x00
goto Main ;Beginning of program
org 0x04
goto ISR ;Beginning of the interrupt routine

encoder equ 0x05
display equ 0x06
trisa equ 0x05
trisb equ 0x06
temp equ 0x30
counter equ 0x31
old equ 0x32
new equ 0x33
STATUS equ 0x03

Dig1 equ 0x0C ; Variable for storing the tens digit of the number D
Dig2 equ 0x0D ; Variable for storing the ones digit of the number D
Digtemp equ 0x0E
D equ 0x20 ; D stores the number to be displayed
One equ 0x10 ; Auxiliary variable for multiplex display
W_temp equ 0x11 ; Auxiliary variable

NICE MACRO FOR SEPARATING THE DIGITS FOR DISPLAY

digbyte macro arg0
local Pon0
local Exit1
local Exit2
local Pozitiv
clrf Dig1
clrf Dig2
Pozitiv
movf arg0,w
movwf Digtemp
movlw .100
Pon0
incf Dig1,f
subwf Digtemp,f
btfsc STATUS,C
goto Pon0
decf Dig1,f
addwf Digtemp,f
Exit1
movlw .10
incf Dig2,f
subwf Digtemp,f
btfsc STATUS,C
goto Exit1
decf Dig2,f
addwf Digtemp,f
Exit2
movf Digtemp,w
movwf Dig2
endm

Main
banksel TRISA
movlw b'11110011' ; RA2 and RA3 are output pins used for multiplexing
movwf TRISA
clrf TRISB ; Port B is output
movlw b'10000100' ; Prescaler is 32 meaning that TMR0 is incremented every 32 ms
movwf OPTION_REG ; with a 4MHz oscillator
banksel PORTA
movlw .96 ; Starting value of TMR0 is 96, thus interrupt occurs every
; (255-97)*32us = 5.056ms
movwf TMR0
movlw b'10100000' ; TMR0 interrupt enabled
movwf INTCON

; ENCODER IS LOADED AT THIS POINT

movlw 0x00
movwf 0x05
movlw 0xff
movwf 0x06
clrf encoder
movfw encoder
movwf old

Loop
call chk_encoder ; repfresh the counter from the encoder
movwf D ; Value got from counter ready for display
call Bcdto7seg ; Get the equivalent for displaying
movwf display
clrf One ;
goto Loop ; Keep on repeating for ever

chk_encoder

movfw encoder ; load working register with content of encoder file.
andlw 0x03 ; mask working register with literal value 3
movwf new ; store the result in register new
movwf temp ; store the same in register temp
xorwf old,1 ; determine whether new is equal to old
movwf old
btfsc STATUS,Z ; if so then go back to main program
RETURN ; It means nothing has changed so far
rlf old,1 ; If not equal then rotate left old.0 to align with new.1
movfw new ; load working register with content of new
xorwf old,W ; test for equality of new and old
decfsz counter,1 ; if equal decrement counter
incf counter,1 ; if not equal increment counter
movfw counter ; load working register with counter content
andlw 0x0F ; get lsd in working register
movfw new ; update old with content of new
movwf old
movf new,0 ; load counter with content of working register
movwf D
RETURN ; return to main program

ISR
movwf W_temp ; Store the contents of W register
movlw .96
movwf TMR0 ; Initialize TMR0 to have the next interrupt in
; approximately 5ms
bcf INTCON,T0IF ; Clear flag overflow TMR0 to be able to react
; to the next interrupt
bcf PORTA,0 ; Turn off both display
bcf PORTA,1
movf One,f
btfsc STATUS,Z ; Which display should be on?
goto Msdon

Lsdon ; If MSD was previously on,
bcf One,0 ; One stores that LSD is on
movlw high Bcdto7seg ; Prior to jump to lookup table, PCLATH
movwf PCLATH ; register should be initialized with the higher
; byte of the address looup (HIGH lookup),
; to prevent errors in addressing.
digbyte D ; Macro for separating digits of number D
movf Dig2,W ; Dig2 holds the lower digit
call Bcdto7seg ; Call the lookup table from which the appropriate
; mask is read, for the digit to be printed on
movwf PORTB ; 7-segment display with common cathode
bsf PORTA,3 ; Turn on LSD display (remain on for 5ms, until
; the next TMR0 interrupt)
movf W_temp,W ; W register has the same value it had before entering
; the interrupt subroutine
retfie

Msdon
bsf One,0 ;
movlw high Bcdto7seg ;
movwf PCLATH ;
digbyte D ;
movf Dig1,W ;
call Bcdto7seg ;
movwf PORTB
bsf PORTA,2   
movf W_temp,W
retfie

org 0x300
Bcdto7seg
addwf PCL+W
retlw b'00111111' ; Code for 0
retlw b'00000110' ; Code for 1
retlw b'01011011' ; Code for 2
retlw b'01001111' ; Code for 3
retlw b'01100110' ; Code for 4
retlw b'01101101' ; Code for 5
retlw b'01111101' ; Code for 6
retlw b'00000111' ; Code for 7
retlw b'01111111' ; Code for 8
retlw b'01100111' ; Code for 9
end

#1
4 Replies Related Threads
Output DS1307 to 7-Segment Led Display
jeronimo
jeronimo
Super Member

Total Posts : 325
Reward points : 0
Joined: 7/6/2007
Location: Cambridgeshire, UK
Status: offline

RE: DRIVING Dual Seven Segment Display Using PIC16F84A Friday, July 06, 2007 9:42 PM (permalink)
0
Hi

I found your code hard to follow and was about to give up when I saw at the start of your look-up table you used "addwf pcl+w"

This probably evaluates to zero which maybe is why you just get zero display.

Try "addwf pcl,f"

ie: you are adding w to the file (program counter).

Hope this fixes.... and put more info in your code! No offence intended. I usually can't read ANYONE else's code.

j
#2
lawriem72
lawriem72
New Member

Total Posts : 4
Reward points : 0
Joined: 6/25/2007
Location: 0
Status: offline

RE: DRIVING Dual Seven Segment Display Using PIC16F84A Monday, July 09, 2007 4:12 PM (permalink)
0
Hi

Thanks for spoting the error at the start of the table. I have run the code again but it seems it does not now leave the zero value in the table. Could you please help me develop a code that shall be reading the content of the register and displaying on the two 7-Segment display. On one display, it can show but displaying both digits, is quite hard for me. I will really appreciate.

Lawrence
#3
jeronimo
jeronimo
Super Member

Total Posts : 325
Reward points : 0
Joined: 7/6/2007

CHANNEL_7_SEG_1_TO_24

;(This subroutine is somewhere on PageO,sub O).
;This returns a byte of two nibbles. Bits 7 - 4 is the "tens" digit, bits 3 - 0
;is the "units".
;The 4511 7-segment decoder / latch / driver chip accepts a (4-bit) BCD input on its
;address lines (A0 - A3) taking its STORE line low then high will latch the four bits.
;It does the decoding and supplies the drive current and outputs the binary value as
a decimal digit. How cool is that!
;Check the 4511 data sheet. It has pins labeled A - F which match to the 7-seg pins...
;I tie pins 3 and 4 to +5v... can't remember why.)
;If the BCD nibble is greater than "9" then they output a blank (ie: "leading zero"
;is suppressed). Useful for 0 - 9.

ADDWF PCL,F
RETLW .0 ;Catches the CALL if W = zero. Displays "00" (see above to blank display).
  
; msb lsb
RETLW B'11110001' ;Ch 1 (Upper nibble = '1111xxxx' for channels 1 to 9. This
RETLW B'11110010' ;Ch 2 will give a blank "tens" digit).
RETLW B'11110011' ;Ch 3
RETLW B'11110100' ;Ch 4
RETLW B'11110101' ;Ch 5
RETLW B'11110110' ;Ch 6
RETLW B'11110111' ;Ch 7
RETLW B'11111000' ;Ch 8
RETLW B'11111001' ;Ch 9

RETLW B'00010000' ;Ch 1O (Upper nibble = 'OOO1xxxx' for channels 1O to 19. This
RETLW B'00010001' ;Ch 11 gives a "1" in the "tens" digit).
RETLW B'00010010' ;Ch 12
RETLW B'00010011' ;Ch 13
RETLW B'00010100' ;Ch 14
RETLW B'00010101' ;Ch 15
RETLW B'00010110' ;Ch 16
RETLW B'00010111' ;Ch 17
RETLW B'00011000' ;Ch 18
RETLW B'00011001' ;Ch 19

RETLW B'00100000' ;Ch 2O (Upper nibble = 'OO1Oxxxx' for channels 2O to 24. This
RETLW B'00100001' ;Ch 21 gives a "2" in the "tens" digit).
RETLW B'00100010' ;Ch 22
RETLW B'00100011' ;Ch 23
RETLW B'00100100' ;Ch 24

;End of subroutine

_7_SEG_LOOKUP

;(CALL-ing and output code)

MOVF CHANNEL_NUMBER,W ;Retrieve the selected channel number for lookup
CALL CHANNEL_7_SEG_1_TO_24 ;(PageO,sub O).The returned look-up data is
;formatted in nibbles, one for each of the
;double-digit channel number display.
_7_SEG_OUTPUT

MOVWF PORTB ;Output the byte-wide nibble-data.

;Exercise the "channel number" 4511 latch-enables (In my application these are wired as
;one and the STORE output pin services both 4511 latches simultaneously).

;(Programming note: I ALWAYS use a "MODELx" register for outputing individual bits
;.... modify the appropriate bit in the MODELx register and then output the whole register.

;The MODELx register avoids being corrupted by spurious read-modify-writes. J.).
;Note: PORTD,STORE and MODELD,STORE must be initialised as "1", it just gets dropped low
;briefly (strobed) to latch-out the PortB data.

BCF MODELD,STORE
MOVF MODELD,W
MOVWF PORTD
BSF MODELD,STORE
MOVF MODELD,W
MOVWF PORTD

;(Finish

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote