You mean you want us to write it for you?
You could google 16f887a counter asm find something like this https://www.electro-tech-online.com/threads/two-7-seg-up-down-counter-with-two-switches.93891/
And then try to change the code to your chip at least try. Then post what you did and some one will help you. I may even do that.
Oh and you sure it's not a 16F877a there is no 16F887a
You mean you want us to write it for you?
You could google 16f887a counter asm find something like this https://www.electro-tech-online.com/threads/two-7-seg-up-down-counter-with-two-switches.93891/
And then try to change the code to your chip at least try. Then post what you did and some one will help you. I may even do that.
Oh and you sure it's not a 16F877a there is no 16F887a
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
You have all you need to make one on the page I posted all you have to do is change the code Mike posted to work with your chip.
Look at post4 its for a 16F88 it's still asm and it will work with some changes on your chip
Now is your chip really a 16F887 or a 16F877a there is no 16F887a.
;******************************************************************
; 2-Digit Up/Dn Counter, Isochronous Loop Example *
;******************************************************************
; change the chip name and configure
list p=16f877A ; list directive to define processor
#include <p16f877A.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_ON & _CPD_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
; change the ADC stuff
bsf STATUS, RP0 ; Select Bank 1
movlw 0x06 ; Configure all pins
movwf ADCON1 ; as digital inputs
;
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
Lol all you had to do is this and test it.
Look it over real good
Wire it up to the same pins as the pictureCode:;****************************************************************** ; 2-Digit Up/Dn Counter, Isochronous Loop Example * ;****************************************************************** ; change the chip name and configure list p=16f877A ; list directive to define processor #include <p16f877A.inc> ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_ON & _CPD_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 ; change the ADC stuff bsf STATUS, RP0 ; Select Bank 1 movlw 0x06 ; Configure all pins movwf ADCON1 ; as digital inputs ; 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
View attachment 75630
This is a 16F88 but your chip has the same ports PORTA and PORTB
This Is Mike K8LH Work I just reposted it to help you out and changed code to work with your chip.
it's not working..
Can you describe in a little more detail what you have done to determine that?
Here are some thoughts:
1) Is that conclusion based on a breadboard circuit or simulation?
2) What simulator are you using?
3) Bypass the delays (comment out) and step through the rest of the program. What happens? Post the code from your simulation.
4) If you are not using a simulator, such as MPLAB SIM, it is difficult to troubleshoot code.
5) If breadboard, is anything happening? That is, is it totally dead, or are some led's coming on, but they are not quite right?
6) Is the code you posted a copy and paste of your actual Assembly code or simply copied from what's been posted here? In other words, it is crucial to determine whether some unintentional changes have slipped into the code you are using.
7) I haven't had breakfast yet, but I don't see the HS crystal resonator in your schematic. See Chapter 14.2 of the datasheet.
The above list is not exhaustive.
John
She or he may not be using the right crystal mikes code
Was for a 16f88 at 8 MHz
I changed the code to run on a 16f877a you need a crystal on that one
May of left crystal out but I'm sure the code works
Yes that's oki use mplab ide v8.92 / v8.76 to write the codes? is that ok?
my simulator is ISIS.
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?