2 Digit up/down COUNTER -->

Translate

2 Digit up/down COUNTER

Proyek ini menunjukkan apa yang dapat dilakukan dengan mikro dan Anda dapat memodifikasi untuk mengatur alarm pada setiap count-nilai atau menetapkan batas seperti "menghitung-to-60." Anda dapat menambahkan bel atau me-relay atau meningkatkan tampilan untuk 3 digit. Anda harus ingat bahwa setiap tampilan tambahan akan mengurangi pencahayaan dari setiap digit karena mereka "multiplexing (time-sharing)."



The basic 2-Digit Up/Down Counter CircuitFull circuit diagram including programming socket 

The "In Circuit Programming" Connectionsby jumpers at the top and bottom Any 7-Segment displays will work in this circuit. You need toidentify the pinout of any display you use.(Common Anode displays can be used providing you invert thevalues in the display table. A PNP transistor will need to be used.)PENGUJIAN SIRKUIT
;****************************************************************
;* 2 Digit UP / Down Counter    17/6/2009
;Port B drives two 7 segment displays
;Up Sw on RA2   Down Sw on RA3
;"Units" drive on RA0   "Tens" drive on RA1  
;*         *
;****************************************************************

 list P = 16F628A ;microcontroller
 include   ;registers for F628A


 __Config _cp_off & _lvp_off & _pwrte_on &
   _wdt_off & _intRC_osc_noclkout & _mclre_off

;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out


;****************************************************************
; variables - names and files
;****************************************************************


  ;Files for F628A start at 20h
         
temp1  equ  20h ;for delay
temp2  equ  21h ;for delay
SwUp  equ  22h ;
SwDwn  equ 23h ;
units  equ 24h ;
tens  equ 25h ;
Sw_Flag  equ 26h ;
FastCount equ 27h ;counts loops fast incrementing

;****************************************************************
;Equates
;****************************************************************
status  equ 0x03
cmcon  equ 0x1F
rp1  equ 0x06
rp0  equ 0x05
portA  equ 0x05
portB  equ 0x06
trisA           equ     0x85
trisB           equ     0x86


;****************************************************************
;Beginning of program
;****************************************************************
reset org 00 ;reset vector address
 goto SetUp
 
table addwf   PCL,F           ;02h,1  add W to program counter
        retlw   b'00111111'     ; "0"   -|F|E|D|C|B|A
        retlw   b'00000110'     ; "1"   -|-|-|-|C|B|-
        retlw   b'01011011'     ; "2"   G|-|E|D|-|B|A
        retlw   b'01001111'     ; "3"   G|-|-|D|C|B|A
        retlw   b'01100110'     ; "4"   G|F|-|-|C|B|-
        retlw   b'01101101'     ; "5"   G|F|-|D|C|-|A
        retlw   b'01111101'     ; "6"   G|F|E|D|C|-|A
        retlw   b'00000111'     ; "7"   -|-|-|-|C|B|A
        retlw   b'01111111'     ; "8"   G|F|E|D|C|B|A
        retlw   b'01101111'     ; "9"   G|F|-|D|C|B|A


;****************************************************************
;* port A and B initialisation     *
;****************************************************************

SetUp bsf status,rp0
 movlw b'00001100' ;Make RA0,1 out   RA2,3 in
 movwf 05h  ;trisA
 clrf 06h  ;trisB Make all RB output
 bcf status,rp0 ;select programming area - bank0
 movlw b'10000000' ;Turn off T0CKI
 movwf option_reg
 clrf  portB  ;Clear Port B of junk
 clrf units  ;zero the units file
 clrf tens  ;zero the tens file
 clrf Sw_Flag
 movlw 07h  ;turn comparators off and enable
 movwf cmcon  ;    pins for I/O functions
 goto  Main    

   ;Delay 10mS   10 x 1,000uS

D_10mS movlw 0Ah
 movwf temp2
D_a nop
 decfsz  temp1,f
 goto  D_a
 decfsz  temp2,f
 goto  D_a
 retlw  00
 
Up btfsc Sw_Flag,2
 retlw 00
 bsf Sw_Flag,2
 incf units,f
 movlw 0Ah  ;put 10 into w
 xorwf units,w  ;compare units file with 10
 btfss status,2 ;zero flag in status file. Set if units is 10
 retlw 00
 clrf units
 incf tens,f
 movlw 0Ah  ;put 10 into w
 xorwf tens,w  ;compare units file with 10
 btfsc status,2 ;zero flag in status file. Set if tens is 10
 clrf tens  
 retlw 00  ;display passes 99 but not below 0
 
 
Dwn btfsc Sw_Flag,3
 retlw 00
 bsf Sw_Flag,3
 decf units,f
 movlw 0FFh  ;put FFh into w
 xorwf units,w  ;compare units file with FFh
 btfss status,2 ;zero flag in status file. Set if units is 10
 retlw 00
 movlw 09
 movwf units  ;put 9 into units file
 decf tens,f
 movlw 0FFh  ;put 0FFh into w
 xorwf tens,w  ;compare tens file with 0FFh
 btfsc status,2 ;zero flag status file). Set if tens is 0FFh
 goto $+2  ;tens file is 0FFh  Jump down 2 instructions
 retlw 00    
 clrf tens
 clrf units
 retlw 00  ;display  not below 0
     

Main btfss portA,2  ;test switch-press for UP
 call Up  ;UP switch pressed
 btfss portA,3  ;test switch-press for Down
 call Dwn  ;Down switch pressed
 movlw b'00000001' ;Make RA0 HIGH for units drive
 movwf portA
 movf units,f  ;copy unit value into w
 call table  ;unit display value will return in w
 movwf portB  ;output units value
 call D_10mS  ;call delay
 clrf portB  ;clear display
 movlw b'00000010' ;Make RA1 HIGH for tens drive
 movwf portA  
 movf tens,f  ;copy tens value into w
 call table  ;tens display value will return in w
 movwf portB  ;output tens value
 call D_10mS  ;call delay
 clrf portB  ;clear display
 btfsc portA,2  ;bit will be zero when sw is pressed
 bcf Sw_Flag,2
 btfsc portA,3  ;bit will be zero when sw is pressed
 bcf Sw_Flag,3  
 goto Main
 
  END

Program di atas menggunakan petunjuk yang sangat sederhana dan sangat mudah untuk melihat bagaimana setiap baris kode bekerja. Satu-satunya instruksi Boolean adalah xorwf dan ini adalah mantan atau instruksi (eksklusif-atau) yang berarti dua file dibandingkan dengan masing-masing bit dalam satu file dibandingkan dengan bit yang sama dalam file lain. Hasilnya adalah "1" ketika salah satu (dan hanya satu) dari angka adalah "1." XOR mendeteksi MATCH a. Jika dua angka yang sama dibandingkan, jawaban untuk mengatakan bit terendah akan "0" karena hanya salah satu nomor harus "1." Jika kedua file berisi nilai yang sama, hasil XOR adalah "0"

Kita sekarang melihat berkas 03, (file Status) dan periksa bit 2. ini adalah bit nol. Hasil dari instruksi XOR adalah "0" dan dengan demikian bit nol SET.

Ini adalah kompleks sebagian besar instruksi yang digunakan dalam program ini.
Sekarang kita datang ke sebuah program yang ditulis oleh PROGRAMMER a.
Namun sangat menarik untuk melihat bagaimana program di "tingkat berikutnya pemahaman," dan kami akan mencakup beberapa fitur (ini terletak setelah program).
P16F628.INC  P16F628A.INC
To add RESET to the up/down counter, add the following instructions:
SetUp bsf status,rp0
movlw b'00011100' ;Make RA0,1 out RA2,3,4 in
Put reset on RA4 pin3
put 22k to positive and the switch between pin3 and 0v.
When sw is pressed the input will go low.
in main, the least few lines will be
        bcf Sw_Flag,2 ;button not pressed. Clear Up flag
bcf Sw_Flag,7 ;Clear Up repeat flag
clrf FastCount
btfss portA,4 ;test reset
        goto SetUp
goto Main
END
;******************************************************************
;  2-Digit Up/Dn Counter, Isochronous Loop Example
;           Isochronous - to occur at equal time intervals.       *
;******************************************************************

        processor PIC16F628
        include "p16f628.inc"
        errorlevel -302

       __Config _cp_off & _lvp_off & _pwrte_on &
  _wdt_off & _intRC_osc_noclkout & _mclre_off

;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out

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

;******************************************************************
;
;  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                      
        movlw 07h  ;turn comparators off and enable
 movwf cmcon  ;    pins for I/O functions  
        movlw   b'00001100'     ;                                
        movwf   TRISA           ; RA3-RA2 inputs, others outputs
        clrf    TRISB           ; portb all outputs              
        bcf     STATUS,RP0      ; bank 0                        
        clrf    PORTB           ; clear portb output latches    
        movlw   b'00000001'     ; digit select bits (RA1-RA0)    
        movwf   PORTA           ; select the 'ones' display      
        clrf    swlatch         ; clear switch state latch      
        clrf    ones            ; clear 'ones'                  
        clrf    tens            ; clear 'tens'                  
        clrf    number          ; number = 00                    
;
;  isochronous 8 msec main program loop (62.5Hz refresh rate)
;
Main    clrf    PORTB           ; blank the display              
        movf    PORTA,W         ;                                
        xorlw   b'00000011'     ; flip digit select bits        
        movwf   PORTA           ;                                
        movf    tens,W          ; WREG = tens, 0..9              
        btfss   PORTA,1         ; display tens? yes, skip, else  
        movf    ones,W          ; WREG = ones, 0..9              
        call    segtbl          ; get segment data              
        movwf   PORTB           ; display new digit              
TstSw   comf    PORTA,W         ; sample active low switches    
        andlw   b'00001100'     ; on RA3 and RA2 pins            
        xorwf   swlatch,W       ; changes (press or release)    
        xorwf   swlatch,F       ; update switch state latch      
        andwf   swlatch,W       ; filter out "new release" bits  
        bnz     Bump            ; branch on a "new press", else  
        DelayCy(8*msecs-23)     ; precise 8 msec loop timing    
        goto    Main            ;                                
;
;  bump 'number' up or down with limit checking
;
Bump    andlw   1<<DnSw         ; the "Dn" switch?              
        skpz                    ; no, skip (WREG=0), else        
        movlw   -2              ; WREG = -2 (dn)                
        addlw   1               ; WREG = 1 (up) or -1 (dn)      
        addwf   number,F        ; number++ or number--          
        movf    number,W        ; WREG = number = -1..100        
        xorlw   100             ; test upper limit              
        skpnz                   ; upper limit? no, skip, else    
        decf    number,F        ; reset to 99                    
        btfsc   number,7        ; lower limit? no, skip, else    
        incf    number,F        ; reset to 00                    
        movf    number,W        ; WREG = number = 00..99        
;
;  setup 'tens' and 'ones' for next loop
;
        clrf    tens            ; isochronous bin2bcd routine    
        addlw   -80             ; W = W - 80                    
        rlf     tens,F          ; shift in 2^3*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   80              ; W = W + 80                    
        addlw   -40             ; W = W - 40                    
        rlf     tens,F          ; shift in 2^2*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   40              ; W = W + 40                    
        addlw   -20             ; W = W - 20                    
        rlf     tens,F          ; shift in 2^1*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   20              ; W = W + 20                    
        addlw   -10             ; W = W - 10, now W = "ones"    
        rlf     tens,F          ; shift in 2^0*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   10              ; W = W + 10, now W = "ones"    
        movwf   ones            ; save "ones"                    
        DelayCy(8*msecs-54)     ; precise 8 msec loop timing    
        goto    Main            ;                                
;
;  segment data table (caveat, non-boundary tolerant)
;
segtbl
        addwf      PCL,F                                          
        retlw      b'00111111'     ; "0"   -|F|E|D|C|B|A          
        retlw      b'00000110'     ; "1"   -|-|-|-|C|B|-          
        retlw      b'01011011'     ; "2"   G|-|E|D|-|B|A          
        retlw      b'01001111'     ; "3"   G|-|-|D|C|B|A          
        retlw      b'01100110'     ; "4"   G|F|-|-|C|B|-          
        retlw      b'01101101'     ; "5"   G|F|-|D|C|-|A          
        retlw      b'01111101'     ; "6"   G|F|E|D|C|-|A          
        retlw      b'00000111'     ; "7"   -|-|-|-|C|B|A          
        retlw      b'01111111'     ; "8"   G|F|E|D|C|B|A          
        retlw      b'01101111'     ; "9"   G|F|-|D|C|B|A          
;
; DelayCy() subsystem 16-bit timing subroutine
;
        nop                     ; entry for (delay-11)%5 == 4    
        nop                     ; entry for (delay-11)%5 == 3    
        nop                     ; entry for (delay-11)%5 == 2    
        nop                     ; entry for (delay-11)%5 == 1    
uDelay  addlw   -1              ; subtract "loop" cycle time    
        skpc                    ; borrow? no, skip, else        
        decfsz  DelayHi,F       ; done?  yes, skip, else        
        goto    uDelay          ; do another loop                
        retlw 00              ;                                

        end
Pada lulus pertama dari program ini, mikro melengkapi nilai port input, (Porta) dan beban itu ke w. instruksi bisa saja movwf PORTA, w dan instruksi berikut akan perlu b'11110011 andlw 'untuk menghasilkan hasil yang sama. Instruksi perubahan h semua "0" untuk "1" dan semua "1" untuk "0 ini." Proyek ini menggunakan "logika negatif." Ini berarti garis input "aktif" saat LOW.

Jika tidak ada tombol yang ditekan, pembacaan pada RA2 dan Ra3 akan "1" dan "1." Hasil PORTA h akan: xxxx00xx mana "x" tidak ditetapkan sebagai bit masukan.
instruksi: andlw b'00001100 'disebut "operasi masking." Semua bit kecuali bit 2 dan 3 yang bertopeng atau "dihapus" dari hasilnya.
Ketika xxxx00xx adalah AND'ed dengan 00.001.100 hasilnya adalah: aaaa00aa di w mendaftar, di mana "a" tidak diperhitungkan karena kami hanya diperbolehkan bit 2 dan 3 untuk "masuk persamaan."
swlatch adalah file bendera untuk switch. Hal ini awalnya dibersihkan dan hasil swlatch xorwf, w akan: xxxx00xx di "w" file.

Instruksi: xorwf swlatch, F melakukan operasi Boolean XOR pada xxxx00xx di "w" file dan 00000000 di file swlatch dan menempatkan hasilnya: 00000000 dalam file swlatch.

instruksi: swlatch andwf, W melakukan Boolean AND operasi pada: 00000000 di file w DAN 00000000 di file swlatch dan menempatkan hasilnya: 00000000 di w. mikro terlihat di bit nol dalam file STATUS dan hasilnya adalah nol, bit yang akan SET. Instruksi BNZ menyebabkan mikro untuk pergi Bump jika bit nol tidak diatur. Nol bit tidak diatur dan dengan demikian mikro tidak pergi ke Bump.

The clever part of these 6 instructions is this:  The micro will only branch on the first detection of a button being pressed.

We will now look at how the first detection is created, but it will take a lot of investigation to see how the Boolean operations perform the task:
The result of comf PORTA will be:  xxxx01xx and this will be stored in w.
andlw   b'00001100'  will AND xxxx01xx with  00001100 to get 00000100 in w.
xorwf   swlatch,W  will XOR 00000100 in w with  00000000 in swlatch to get 00000100 in w.
xorwf   swlatch,F  will XOR 00000100 in w with  00000000 in swlatch to get 00000100 in swlatch file.
andwf   swlatch,W will AND 00000100 in w with  00000100 in swlatch to get 00000100 in w.
bnz     Bump   will look at the zero flag in the STATUS file. This flag will not be set and thus the micro will jump to the sub-routine Bump.
If the button is still pressed when the micro executes: TstSw  the second time, we will see what happens:
The result of comf PORTA will be:  xxxx01xx and this will be stored in w.
andlw   b'00001100'  will AND xxxx01xx with  00001100 to get 00000100 in w.
xorwf   swlatch,W  will XOR 00000100 in w with 00000100 in swlatch to get 00000000 in w.
xorwf   swlatch,F  will XOR 00000000 in w with  00000100 in swlatch to get 00000100 in swlatch file.
andwf   swlatch,W will AND 00000000 in w with  00000100 in swlatch to get 00000000 in w.
bnz     Bump   will look at the zero flag in the STATUS file. This flag will be set and thus the micro will not jump to the sub-routine Bump.
If the button is released when the micro executes: TstSw  we will see how the swlatch file is changed to: 00000000.
If no buttons are pressed, the reading on port A will be: xxxx11xx
The result of comf PORTA will be:  xxxx00xx and this will be stored in w.
andlw   b'00001100'  will AND xxxx00xx with  00001100 to get 00000000 in w.
xorwf   swlatch,W  will XOR 00000000 in w with 00000100 in swlatch to get 00000100 in w.
xorwf   swlatch,F  will XOR 00000100 in w with  00000100 in swlatch to get 00000000 in swlatch file.
andwf   swlatch,W will AND 00000000 in w with  00000000 in swlatch to get 00000000 in w.
bnz     Bump   will look at the zero flag in the STATUS file. This flag will be set and thus the micro will not jump to the sub-routine Bump. And the swlatch file will be changed to 00000000.The Bump sub-routineThe Bump sub-routine detects
If Up button is pressed, "w" will enter Bump sub-routine with: 00000100.
If Down button is pressed, "w" will enter Bump sub-routine with:  00001000
If Up button is pressed, "w" will enter Bump sub-routine with: 00000100.
If Down button is pressed, "w" will enter Bump sub-routine with:  00001000
If Up button is pressed, "w" will enter Bump sub-routine with: 00000100.
If Down button is pressed, "w" will enter Bump sub-routine with:  00001000
Bump    andlw   1<<DnSw         ; the "Dn" switch?              
        skpz                    ; no, skip (WREG=0), else        
        movlw   -2              ; WREG = -2 (dn)                
        addlw   1               ; WREG = 1 (up) or -1 (dn)      
        addwf   number,F        ; number++ or number--          
        movf    number,W        ; WREG = number = -1..100        
        xorlw   100             ; test upper limit              
        skpnz                   ; upper limit? no, skip, else    
        decf    number,F        ; reset to 99                    
        btfsc   number,7        ; lower limit? no, skip, else    
        incf    number,F        ; reset to 00                    
        movf    number,W        ; WREG = number = 00..99
addwf   number,F will increment the number file.
movf    number,W  the value in the number file will be copied to "w"
xorlw   100    The value in w will be XOR'ed with 100. The XOR operation detects a match. Since each binary digit will be the same (i.e. either a 0 or 1) the result will be 0000 0000. The result will set the zero flag in the status (03) file and by testing bit 2 (the Z flag) you can skip when SET.decf    number,F The number file will be detected as 100. Decrement it to 99.
btfsc   number,7  If the number file is decremented below zero, it rolls-over to 0FFh (255) and bit 7 is tested to see if it is SET.
incf    number,F    The number file is incremented (rolled over) from 256 to 000.
movf    number,W  The number file is copied to w. The Binary to Binary Coded Decimal RoutineThis routine is so complex that I am not going to explain it.
 ; isochronous bin2bcd routine

 clrf    tens              
        addlw   -80             ; W = W - 80                    
        rlf     tens,F          ; shift in 2^3*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   80              ; W = W + 80                    
        addlw   -40             ; W = W - 40                    
        rlf     tens,F          ; shift in 2^2*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   40              ; W = W + 40                    
        addlw   -20             ; W = W - 20                    
        rlf     tens,F          ; shift in 2^1*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   20              ; W = W + 20                    
        addlw   -10             ; W = W - 10, now W = "ones"    
        rlf     tens,F          ; shift in 2^0*10 bit            
        btfss   tens,0          ; borrow? no, skip, else        
        addlw   10              ; W = W + 10, now W = "ones"    
        movwf   ones            ; save "ones"                    
        DelayCy(8*msecs-54)     ; precise 8 msec loop timing    
        goto    Main            ;      
; Convert a binary number into two packed BCD digits
; ON ENTRY:
; w register has binary value in range 0 t o 9 9
; ON EXIT:
; output variables bcdLow and bcdHigh contain two
; BCD digits
; w contains two packed BCD digits
; Routine logic:
; The value 10 is subtracted from the source operand
; until the reminder is < 0 (carry cleared). The number
; of subtractions is the high-order BCD digit. 10 is
; then added back to the subtrahend to compensate
; for the last subtraction. The final remainder is the
; low-order BCD digit
; Variables:
; inNum storage for source operand
; bcdHigh storage for high-order nibble
; bcdLow storage for low-order nibble
; thisDig Digit counter

bin2bcd:
 movwf inNum  ; Save copy of source value
 clrf bcdHigh  ; Clear storage
 clrf bcdLow
 clrf thisDig
min10:
 movlw .10
 subwf inNum,f  ; Subtract 10
 btfsc STATUS,C  ; Did subtract overflow?
 goto sum10  ; No. Count subtraction
 goto fin10
sum10:
 incf thisDig,f  ;increment digit counter
 goto min10
   ; Store 10th digit
fin10:
 movlw .10
 addwf inNum,f  ; Adjust for last subtract
 movf thisDig,w  ; get digit counter
 movwf bcdHigh  ; Store it

   ; Calculate and store low-order BCD digit
 movf inNum,w  ; Store units value
 movwf bcdLow  ; Store digit
   ; Combine both digits
 swapf bcdHigh,w ; High nibble to HOBs
 iorwf bcdLow,w  ; ORin low nibble
 retlw 00
;  Binary-to-Decimal, 00..99
;
         radix   dec
btod99
         clrf    temp            ; W = 0x00..0x63, 0..99 input
         decf    temp,F          ; preset temp to -1
sub10    incf    temp,F          ; unconditionally
         addlw   -10             ; subtract 10. borrow?
         btfsc   status,0        ; no, test carry bit
  goto  sub10
         addlw   10              ; fix 'ones' in Wreg
         swapf   temp,F          ; put 'tens' in left nibble
         iorwf   temp,W          ; W = packed bcd 0x00..0x99

         retlw  00            

selengkapnya kunjungi : http://www.talkingelectronics.com

SEMUA ISI  ADALAH  HASIL KUMPULAN PENCARIAN DAN BEBERAPA SUMBER MEDIA BUKU MAJALAH DLL, KAMI TIDAK BERTANGGUNG JAWAB ATAS KEGAGALAN YANG DISEBABKAN OLEH GAMBAR YANG DIMUAT DI BLOG INI.