I started writing the code before I even had the PIC Programmer or PIC chips. On the first run, I found I had an issue with the inputs not being grounded with pull-down resistors, causing the inputs to fluctuate randomly, but some 10K resistors on the inputs connected to ground sorted that. If you have a switch, when its on its fine, a voltage goes to set the pin high or 1. When the switch is off the pull-down resistors connect the pin to ground giving a low or 0 input.
I did initially opt to use one pin on the PIC16F505 as a latch, so it would only display the input when a button was pressed. I decided it wasn't necessary and the program loops around reading the inputs and setting the outputs to light up the LEDs.
Hers's a pic of the setup with annotation.
; include file with config bit definitions include "p16f505.inc" ; ; config - enable internal OSC and allow use of RB4 ; - disable MCLRE and allow use of RB3 (input only) ; - disable Watchdog Timer, we don't use it. __config _IntRC_OSC_RB4EN & _MCLRE_OFF & _WDT_OFF ; local regsiters INB equ 0x08 INC equ 0x09
INPUT equ 0x0A
OUTB equ 0x0B OUTC equ 0x0C PWRSTS equ 0x0D
SEGDATA equ 0x10 SEG0 equ 0x10 SEG1 equ 0x11 SEG2 equ 0x12 SEG3 equ 0x13 SEG4 equ 0x14 SEG5 equ 0x15 SEG6 equ 0x16 SEG7 equ 0x17 SEG8 equ 0x18 SEG9 equ 0x19 SEGA equ 0x1A SEGB equ 0x1B SEGC equ 0x1C SEGD equ 0x1D SEGE equ 0x1E SEGF equ 0x1F ; start here org 000 movf STATUS,PWRSTS ; Save Power on status ; Port configuration ; a ; +-----+ --- ; VCC [| |] GND f| g |b ; D3 --> RB5 [| |] RB0 --> a --- ; D2 --> RB4 [| PIC |] RB1 --> b e| |c ; D1 --> RB3 [| 16F |] RB2 --> c --- ; D0 --> RC5 [| 505 |] RC0 --> d d ; NC RC4 [| |] RC1 --> e ; g <-- RC3 [| |] RC2 --> f ; +-----+ ; ; RRRRRR ; BBBBBB ; 543210 init movlw b'111000' ; Set PORTB Pins tris PORTB ; RRRRRR ; CCCCCC ; 543210 movlw b'100000' ; Set PORTC Pins tris PORTC ; Load Segment values into memory. ;Digit gfedcba abcdefg a b c d e f g ;0 0x3F 0x7E on on on on on on off ;1 0x06 0x30 off on on off off off off ;2 0x5B 0x6D on on off on on off on ;3 0x4F 0x79 on on on on off off on ;4 0x66 0x33 off on on off off on on ;5 0x6D 0x5B on off on on off on on ;6 0x7D 0x5F on off on on on on on ;7 0x07 0x70 on on on off off off off ;8 0x7F 0x7F on on on on on on on ;9 0x6F 0x7B on on on on off on on ;A 0x77 0x77 on on on off on on on ;b 0x7C 0x1F off off on on on on on ;C 0x39 0x4E on off off on on on off ;d 0x5E 0x3D off on on on on off on ;E 0x79 0x4F on off off on on on on ;F 0x71 0x47 on off off off on on on movlw 0x3F movwf SEG0 movlw 0x06 movwf SEG1 movlw 0x5B movwf SEG2 movlw 0x4F movwf SEG3 movlw 0x66 movwf SEG4 movlw 0x6D movwf SEG5 movlw 0x7D movwf SEG6 movlw 0x07 movwf SEG7 movlw 0x7F movwf SEG8 movlw 0x6F movwf SEG9 movlw 0x77 movwf SEGA movlw 0x7C movwf SEGB movlw 0x39 movwf SEGC movlw 0x5E movwf SEGD movlw 0x79 movwf SEGE movlw 0x71 movwf SEGF ; End of initialisation ; To here 37 Instructions @ 4MHz = 37uS ; Main Program Starts here. poweron clrf OUTB ; Clear output Register B clrf OUTC ; Clear output Register C btfss PWRSTS,RBWUF; Check Power-On Status goto display ; blank if power on ; Reset output values and indexes loop clrf OUTB ; Clear output Register B clrf OUTC ; Clear output Register C movlw SEGDATA ; Load W with SEG DATA base movwf FSR ; Save to FSR ; read value from PORTs movf PORTB,W ; Read PORTB
movwf INB ; Save PORTB
movf PORTC,W ; Read PORTC movwf INC ; Save PORTC ; combine port reads into a nibble in W register clrf INPUT ; Clear INPUT register btfsc INB,RB5 ; Test RB5 (D3) bsf INPUT,3 ; Set D0
btfsc INB,RB4 ; Test RB4 (D2) bsf INPUT,2 ; Set D1 btfsc INB,RB3 ; Test RB3 (D1) bsf INPUT,1 ; Set D2 btfsc INC,RC5 ; Test RC5 (D0) bsf INPUT,0 ; Set D3 movf INPUT,W ; Move value to W ; add value to index register and fetch segment value addwf FSR,F ; Add index to FSR pointer ; prepare register output bits btfsc INDF,0 ; Test for 'a' segment bsf OUTB,RB0 ; Set 'a' segment btfsc INDF,1 ; Test for 'b' segment bsf OUTB,RB1 ; Set 'b' segment btfsc INDF,2 ; Test for 'c' segment bsf OUTB,RB2 ; Set 'c' segment btfsc INDF,3 ; Test for 'd' segment bsf OUTC,RC0 ; Set 'd' segment btfsc INDF,4 ; Test for 'e' segment bsf OUTC,RB1 ; Set 'e' segment btfsc INDF,5 ; Test for 'f' segment bsf OUTC,RB2 ; Set 'f' segment btfsc INDF,6 ; Test for 'g' segment bsf OUTC,RB3 ; Set 'g' segment ; move output to ports display movf OUTB,W ; Get values to send to PORTB movwf PORTB ; Send to PORTB movf OUTC,W ; Get values to send to PORTC movwf PORTC ; Send to PORTC ; around again goto loop ; go back to loop - 50uS loop end
hey!!!! I badly need this. can you share your codes? :(((
ReplyDeleteHi, I've post the code. Enjoy!
ReplyDeletewow! thank you so much sir dave!!!! thanks thanks thanks!!!!!!!!!!!!!!!
Deleteso you've received my first and last tweet. haha
-glenn
Thanks for posting this up - I had been searching the web for a bin -> 7-seg display that shows 0-9,A-F and stumbled the same road block as you (the 74 series only did 0-9). I might have a look at this solution and build it.
ReplyDelete