-- the problem is each 7-segment LED takes, obviously 7 output lines... you might find that the MCU doesn't have 14 spare lines to drive the LED directly...
2 7seg displays? I hope that you're either using an I/O-rich PIC with lots of pins (the 16F877A comes to mind) or you're going to use shift registers to expand your outputs (though this may require a little more code, it'll allow you to have more outputs on a low-pincount device).
;******************************************************************
; 2-Digit Up/Dn Counter, Isochronous Loop Example *
;******************************************************************
processor PIC16F88
include "p16f88.inc"
errorlevel -302
__CONFIG _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_INTRC_IO
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
ones equ 0x20 ; 0..9
tens equ 0x21 ; 0..9
number equ 0x22 ; 00..99
swlatch equ 0x23 ; switch state latch variable
DelayHi equ 0x24 ; DelayCy() subsystem variable
#define DnSw 3 ; RA3
;******************************************************************
;
; K8LH DelayCy() subsystem macro generates four instructions
;
radix dec
clock equ 8 ; clock frequency in Megahertz
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ usecs*1000 ; cycles/millisecond multiplier
DelayCy macro delay ; 11..327690 cycle range
movlw high((delay-11)/5)+1
movwf DelayHi
movlw low ((delay-11)/5)
call uDelay-((delay-11)%5)
endm
;******************************************************************
;
; init hardware and program variables
;
org 0x000
Init
bsf STATUS,RP0 ; bank 1 |B1
movlw b'01110000' ; |B1
movwf OSCCON ; select 8-MHz INTOSC clock |B1
Stable btfss OSCCON,IOFS ; INTOSC Freq Stable bit set? |B1
goto Stable ; no, branch, else |B1
clrf ANSEL ; setup PORT A for digital I/O |B1
movlw b'00001100' ; |B1
movwf TRISA ; RA3-RA2 inputs, others outputs |B1
clrf TRISB ; portb all outputs |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf PORTB ; clear portb output latches |B0
movlw b'00000001' ; digit select bits (RA1-RA0) |B0
movwf PORTA ; select the 'ones' display |B0
clrf swlatch ; clear switch state latch |B0
clrf ones ; clear 'ones' |B0
clrf tens ; clear 'tens' |B0
clrf number ; number = 00 |B0
;
; isochronous 8 msec main program loop (62.5 Hz refresh rate)
;
Main clrf PORTB ; blank the display |B0
movf PORTA,W ; |B0
xorlw b'00000011' ; flip digit select bits |B0
movwf PORTA ; |B0
movf tens,W ; WREG = tens, 0..9 |B0
btfss PORTA,1 ; display tens? yes, skip, else |B0
movf ones,W ; WREG = ones, 0..9 |B0
call segtbl ; get segment data |B0
movwf PORTB ; display new digit |B0
TstSw comf PORTA,W ; sample active low switches |B0
andlw b'00001100' ; on RA3 and RA2 pins |B0
xorwf swlatch,W ; changes (press or release) |B0
xorwf swlatch,F ; update switch state latch |B0
andwf swlatch,W ; filter out "new release" bits |B0
bnz Bump ; branch on a "new press", else |B0
DelayCy(8*msecs-23) ; precise 8 msec loop timing |B0
goto Main ; |B0
;
; bump 'number' up or down with limit checking
;
Bump andlw 1<<DnSw ; the "Dn" switch? |B0
skpz ; no, skip (WREG=0), else |B0
movlw -2 ; WREG = -2 (dn) |B0
addlw 1 ; WREG = 1 (up) or -1 (dn) |B0
addwf number,F ; number++ or number-- |B0
movf number,W ; WREG = number = -1..100 |B0
xorlw 100 ; test upper limit |B0
skpnz ; upper limit? no, skip, else |B0
decf number,F ; reset to 99 |B0
btfsc number,7 ; lower limit? no, skip, else |B0
incf number,F ; reset to 00 |B0
movf number,W ; WREG = number = 00..99 |B0
;
; setup 'tens' and 'ones' for next loop
;
clrf tens ; isochronous bin2bcd routine |B0
addlw -80 ; W = W - 80 |B0
rlf tens,F ; shift in 2^3*10 bit |B0
btfss tens,0 ; borrow? no, skip, else |B0
addlw 80 ; W = W + 80 |B0
addlw -40 ; W = W - 40 |B0
rlf tens,F ; shift in 2^2*10 bit |B0
btfss tens,0 ; borrow? no, skip, else |B0
addlw 40 ; W = W + 40 |B0
addlw -20 ; W = W - 20 |B0
rlf tens,F ; shift in 2^1*10 bit |B0
btfss tens,0 ; borrow? no, skip, else |B0
addlw 20 ; W = W + 20 |B0
addlw -10 ; W = W - 10, now W = "ones" |B0
rlf tens,F ; shift in 2^0*10 bit |B0
btfss tens,0 ; borrow? no, skip, else |B0
addlw 10 ; W = W + 10, now W = "ones" |B0
movwf ones ; save "ones" |B0
DelayCy(8*msecs-54) ; precise 8 msec loop timing |B0
goto Main ; |B0
;
; segment data table (caveat, non-boundary tolerant)
;
segtbl
addwf PCL,F ; |B0
dt b'00111111' ; "0" -|-|F|E|D|C|B|A |B0
dt b'00000110' ; "1" -|-|-|-|-|C|B|- |B0
dt b'01011011' ; "2" -|G|-|E|D|-|B|A |B0
dt b'01001111' ; "3" -|G|-|-|D|C|B|A |B0
dt b'01100110' ; "4" -|G|F|-|-|C|B|- |B0
dt b'01101101' ; "5" -|G|F|-|D|C|-|A |B0
dt b'01111101' ; "6" -|G|F|E|D|C|-|A |B0
dt b'00000111' ; "7" -|-|-|-|-|C|B|A |B0
dt b'01111111' ; "8" -|G|F|E|D|C|B|A |B0
dt b'01101111' ; "9" -|G|F|-|D|C|B|A |B0
;
; K8LH DelayCy() subsystem 16-bit timing subroutine
;
nop ; entry for (delay-11)%5 == 4 |B0
nop ; entry for (delay-11)%5 == 3 |B0
nop ; entry for (delay-11)%5 == 2 |B0
nop ; entry for (delay-11)%5 == 1 |B0
uDelay addlw -1 ; subtract "loop" cycle time |B0
skpc ; borrow? no, skip, else |B0
decfsz DelayHi,F ; done? yes, skip, else |B0
goto uDelay ; do another loop |B0
return ; |B0
end
I don't think he used over 35 commands there. And I hate it when35 PIC instructions and not even using any of the “alternate” instructions.
Mike, K8LH post all the code you want the more showing off the better Ive learned a lot from your work
I apologize if my post offended you. Please consider that while I may be showing off my programming skills I'm also sincerely interested in trying to help others by passing along my knowledge and experience.
thank you .....i really thank you......i can't understand the whole program ....but i can sample somethings from it ......so really thz you.....again , please advise me to improve my program i posted above....i write this program myself.....but i think i need something more in this program.....i posted asm file , HEX file, and design file of my program....i made ckt design with Protesus 6 Professional Software.... so please look at my project and edit it.....OP might be multiplexing the displays to reduce I/O pin requirements. Using "direct drive" from I/O pins could provide about 20 ma 'peak' current or about 10 ma 'average' current to each display segment at a 50% duty cycle which should be pretty bright.
Hundreds of ways to do the software. OP might consider using one big isochronous loop or perhaps use an ISR (interrupt service routine) to refresh the displays as a background task.
I'm surprised OP couldn't find any 2-digit 7-segment up/down counter examples on the Internet.
Kind regards, Mike
<added>
A quickly thrown together (untested) isochronous loop program example;
Code:;****************************************************************** ; 2-Digit Up/Dn Counter, Isochronous Loop Example * ;****************************************************************** processor PIC16F88 include "p16f88.inc" errorlevel -302 __CONFIG _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_INTRC_IO __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ones equ 0x20 ; 0..9 tens equ 0x21 ; 0..9 number equ 0x22 ; 00..99 swlatch equ 0x23 ; switch state latch variable DelayHi equ 0x24 ; DelayCy() subsystem variable #define DnSw 3 ; RA3 ;****************************************************************** ; ; K8LH DelayCy() subsystem macro generates four instructions ; radix dec clock equ 8 ; clock frequency in Megahertz usecs equ clock/4 ; cycles/microsecond multiplier msecs equ usecs*1000 ; cycles/millisecond multiplier DelayCy macro delay ; 11..327690 cycle range movlw high((delay-11)/5)+1 movwf DelayHi movlw low ((delay-11)/5) call uDelay-((delay-11)%5) endm ;****************************************************************** ; ; init hardware and program variables ; org 0x000 Init bsf STATUS,RP0 ; bank 1 |B1 movlw b'01110000' ; |B1 movwf OSCCON ; select 8-MHz INTOSC clock |B1 Stable btfss OSCCON,IOFS ; INTOSC Freq Stable bit set? |B1 goto Stable ; no, branch, else |B1 clrf ANSEL ; setup PORT A for digital I/O |B1 movlw b'00001100' ; |B1 movwf TRISA ; RA3-RA2 inputs, others outputs |B1 clrf TRISB ; portb all outputs |B1 bcf STATUS,RP0 ; bank 0 |B0 clrf PORTB ; clear portb output latches |B0 movlw b'00000001' ; digit select bits (RA1-RA0) |B0 movwf PORTA ; select the 'ones' display |B0 clrf swlatch ; clear switch state latch |B0 clrf ones ; clear 'ones' |B0 clrf tens ; clear 'tens' |B0 clrf number ; number = 00 |B0 ; ; isochronous 8 msec main program loop (62.5 Hz refresh rate) ; Main clrf PORTB ; blank the display |B0 movf PORTA,W ; |B0 xorlw b'00000011' ; flip digit select bits |B0 movwf PORTA ; |B0 movf tens,W ; WREG = tens, 0..9 |B0 btfss PORTA,1 ; display tens? yes, skip, else |B0 movf ones,W ; WREG = ones, 0..9 |B0 call segtbl ; get segment data |B0 movwf PORTB ; display new digit |B0 TstSw comf PORTA,W ; sample active low switches |B0 andlw b'00001100' ; on RA3 and RA2 pins |B0 xorwf swlatch,W ; changes (press or release) |B0 xorwf swlatch,F ; update switch state latch |B0 andwf swlatch,W ; filter out "new release" bits |B0 bnz Bump ; branch on a "new press", else |B0 DelayCy(8*msecs-23) ; precise 8 msec loop timing |B0 goto Main ; |B0 ; ; bump 'number' up or down with limit checking ; Bump andlw 1<<DnSw ; the "Dn" switch? |B0 skpz ; no, skip (WREG=0), else |B0 movlw -2 ; WREG = -2 (dn) |B0 addlw 1 ; WREG = 1 (up) or -1 (dn) |B0 addwf number,F ; number++ or number-- |B0 movf number,W ; WREG = number = -1..100 |B0 xorlw 100 ; test upper limit |B0 skpnz ; upper limit? no, skip, else |B0 decf number,F ; reset to 99 |B0 btfsc number,7 ; lower limit? no, skip, else |B0 incf number,F ; reset to 00 |B0 movf number,W ; WREG = number = 00..99 |B0 ; ; setup 'tens' and 'ones' for next loop ; clrf tens ; isochronous bin2bcd routine |B0 addlw -80 ; W = W - 80 |B0 rlf tens,F ; shift in 2^3*10 bit |B0 btfss tens,0 ; borrow? no, skip, else |B0 addlw 80 ; W = W + 80 |B0 addlw -40 ; W = W - 40 |B0 rlf tens,F ; shift in 2^2*10 bit |B0 btfss tens,0 ; borrow? no, skip, else |B0 addlw 40 ; W = W + 40 |B0 addlw -20 ; W = W - 20 |B0 rlf tens,F ; shift in 2^1*10 bit |B0 btfss tens,0 ; borrow? no, skip, else |B0 addlw 20 ; W = W + 20 |B0 addlw -10 ; W = W - 10, now W = "ones" |B0 rlf tens,F ; shift in 2^0*10 bit |B0 btfss tens,0 ; borrow? no, skip, else |B0 addlw 10 ; W = W + 10, now W = "ones" |B0 movwf ones ; save "ones" |B0 DelayCy(8*msecs-54) ; precise 8 msec loop timing |B0 goto Main ; |B0 ; ; segment data table (caveat, non-boundary tolerant) ; segtbl addwf PCL,F ; |B0 dt b'00111111' ; "0" -|-|F|E|D|C|B|A |B0 dt b'00000110' ; "1" -|-|-|-|-|C|B|- |B0 dt b'01011011' ; "2" -|G|-|E|D|-|B|A |B0 dt b'01001111' ; "3" -|G|-|-|D|C|B|A |B0 dt b'01100110' ; "4" -|G|F|-|-|C|B|- |B0 dt b'01101101' ; "5" -|G|F|-|D|C|-|A |B0 dt b'01111101' ; "6" -|G|F|E|D|C|-|A |B0 dt b'00000111' ; "7" -|-|-|-|-|C|B|A |B0 dt b'01111111' ; "8" -|G|F|E|D|C|B|A |B0 dt b'01101111' ; "9" -|G|F|-|D|C|B|A |B0 ; ; K8LH DelayCy() subsystem 16-bit timing subroutine ; nop ; entry for (delay-11)%5 == 4 |B0 nop ; entry for (delay-11)%5 == 3 |B0 nop ; entry for (delay-11)%5 == 2 |B0 nop ; entry for (delay-11)%5 == 1 |B0 uDelay addlw -1 ; subtract "loop" cycle time |B0 skpc ; borrow? no, skip, else |B0 decfsz DelayHi,F ; done? yes, skip, else |B0 goto uDelay ; do another loop |B0 return ; |B0 end
setup bsf STATUS,RP0 ; bank 1
movlw 03 ;
movwf TRISA ; RA7:RA2 outputs, RA1:RA0 inputs
clrf TRISB ; RB7:RB0 outputs
bcf STATUS,RP0 ; bank 0
clrf TMR1H ; ??? are you trying to use 0x0F as a variable?
clrf CMCON ; ??? are you trying to use 0x1F as a variable?
goto test ;
htunlinkyaw1807
clrf 0f
clrf 1f
I used 0f and 1f as variables.....what do you think of it....
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?