[ Príspevkov: 3 ] 
AutorSpráva
Offline

Užívateľ
Užívateľ
Obrázok užívateľa

Registrovaný: 23.04.13
Prihlásený: 24.04.13
Príspevky: 2
Témy: 1 | 1
NapísalOffline : 23.04.2013 12:04 | Assembler - PIC (Vykreslovač hodín)

Zdravím,
potreboval by som pomoc s nasledovným programom. Potreboval by som objasnenie pretože mu akosi nemôžem pochopiť. Program je na vykreslovanie hodín pomocou LED na motorčeku

Kód:
;--------
; Noblink.asm
; mechanically scanned LED clock
; Original file mclock.asm
; display of seconds added
; turned off the blinking double dots
;
;--------
                list    p=16F84
                radix   hex
                include "p16F84.inc"
;--------
; remember to set blast-time options: OSC=regular xtal, WDT=ON
; timings all based on 4 MHz crystal
;--------
w               equ     0
f               equ     1
;--------
; Start of available RAM.
;--------
        cblock  0x0C
                safe_w          ;not really temp, used by interrupt svc
                safe_s          ;not really temp, used by interrupt svc
                period_count    ;incremented each interrupt
                period_dup      ;copy of period_count safe from interrupt
                period_calc     ;stable period after hysteresis calc.
                period_use      ;stable period after hysteresis calc.
                flags           ;b2=int b1=minute b4=edge b5=seconds
                dot_index       ;which column is being displayed
                digit_index     ;which digit is being displayed
                hours           ;in display format, not hex(01-12)
                minutes ;00 to 59
                seconds ;00 to 59
                bigtick_dbl     ;incremented each interrupt
                bigtick_hi
                bigtick_lo
               sectick_hi
                sectick_lo
                keys            ;key value
                scratch         ;scratch value
                tick            ;used by delay
        endc
;--------
; Start of ROM
;--------
                org     0x00            ;Start of code space
                goto    Start
;--------
; INTERRUPT SERVICE ROUTINE
;--------
                org     0x04            ;interrupt vector
Intsvc          movwf   safe_w          ;save w
                swapf   STATUS,w        ;swap status, w
                movwf   safe_s          ;save status(nibble swap, remember)
;--------
; done saving, now start working
;--------
; clear watchdog timer to ensure startup
                clrwdt
;
; increment period count
;       incf    skip_cnt,f
;       btfss   STATUS,Z
;       goto    Bigticker
;       movlw   0xfe                    ;play with this one for width of displayed characters
;       movwf   skip_cnt
                incf    period_count,f
                btfsc   STATUS,Z        ;zero set means overflow
                decf    period_count,f
; 234375 interrupts every minute. Increment the bigtick each time.
Bigticker
                incf    bigtick_lo,f
                btfsc   STATUS,Z
                incf    bigtick_hi,f
                btfsc   STATUS,Z
                incfsz  bigtick_dbl,f
                goto    Bigtick_out
;--------
; here? bigtick has rolled over to zero and one minute has passed.
; reload bigtick and set a flag for the main counter
;--------
                movlw   0xFC            ;234375 = 0x039387
                movwf   bigtick_dbl     ;0 - 0x039387 = 0xFC6C79
                movlw   0x6C
                movwf   bigtick_hi
                movlw   0x79
                movwf   bigtick_lo
                bsf     flags,1         ;notify Keep_time
Bigtick_out
;-------- now start with the seconds
                incf    sectick_lo,f
                btfsc   STATUS,Z
                incfsz  sectick_hi,f
                goto    Sectick_out
;--------

; here? sigtick has rolled over to zero and one second has passed.
; reload sectick and set a flag for the main counter
;--------
                movlw   0xF0            ;3907 = 0x0F43
                movwf   sectick_hi      ;0 - 0x0F43 = 0xF0BD
                movlw   0xBD
                movwf   sectick_lo
                bsf     flags,5         ;notify Keep_time
Sectick_out
;--------
; done working, start restoring
;--------
                swapf   safe_s,w        ;fetch status, reswap nibbles
                movwf   STATUS          ;restore status
                swapf   safe_w,f        ;swap nibbles in preparation
                swapf   safe_w,w        ;for the swap restoration of w
                bcf     INTCON,2        ;clear interrupt flag before return
                retfie                  ;return from interrupt
;--------
; CHARACTER LOOKUP TABLE
; ignore high bit. set=LED off, clear=LED on, bit0=bottom LED, bit6=top LED
;--------
Char_tbl
                addwf   PCL,f
                dt      0xC1,0xBE,0xBE,0xBE,0xC1        ;"O"
                dt      0xFF,0xDE,0x80,0xFE,0xFF        ;"1"
                dt      0xDE,0xBC,0xBA,0xB6,0xCE        ;"2"
                dt      0xBD,0xBE,0xAE,0x96,0xB9        ;"3"
                dt      0xF3,0xEB,0xDB,0x80,0xFB        ;"4"
                dt      0x8D,0xAE,0xAE,0xAE,0xB1        ;"5"
                dt      0xE1,0xD6,0xB6,0xB6,0xF9        ;"6"
                dt      0xBF,0xB8,0xB7,0xAF,0x9F        ;"7"
                dt      0xC9,0xB6,0xB6,0xB6,0xC9        ;"8"
                dt      0xCF,0xB6,0xB6,0xB5,0xC3        ;"9"
;               dt      0xE0,0xDB,0xBB,0xDB,0xE0        ;"A"
;               dt      0x80,0xB6,0xB6,0xB6,0xC9        ;"B"
;               dt      0xC1,0xBE,0xBE,0xBE,0xDD        ;"C"
;               dt      0x80,0xBE,0xBE,0xBE,0xC1        ;"D"
;               dt      0x80,0xB6,0xB6,0xBE,0xBE        ;"E"
;               dt      0x80,0xB7,0xB7,0xBF,0xBF        ;"F"
                dt      0xFF,0xFF,0xC9,0xFF,0xFF        ;":"

Char_tbl_end
;--------
; SUBROUTINES STARTING HERE
;--------
; clear important bits of ram
;--------
Ram_init        movlw   0x07
                movwf   keys
                movlw   0x12            ;why do clocks always start
                movwf   hours           ;at 12:00 ?
                clrf    minutes
                clrf    seconds
                clrf    dot_index
                clrf    digit_index
                movlw   0xFC            ;234375 = 0x039387
                movwf   bigtick_dbl     ;0 - 0x039387 = 0xFC6C79
                movlw   0x6C
                movwf   bigtick_hi
                movlw   0x79
                movwf   bigtick_lo
                movlw   0xF0            ;3907 = 0x0F43
                movwf   sectick_hi      ;0 - 0x0F43 = 0xF0BD
                movlw   0xBD
                movwf   sectick_lo
                movlw   0x40
                movwf   period_calc
                retlw   0
;--------
; unused pins I am setting to be outputs
;--------
Port_init       movlw   0x00            ;all output, b7=unused
                tris    PORTB           ;on port b attached to LEDs
                movlw   b'00010111'     ;port a has 5 pins. I need 4 inputs
                                        ;b0=minutes, b1=10mins, b2=hours
                                        ;b3=unused, b4=rotation index
                tris    PORTA           ;on port a
                retlw   0
;--------
; get timer-based interrupts going
;--------
Timer_init      bcf     INTCON,2        ;clear TMR0 int flag
                bsf     INTCON,7        ;enable global interrupts
                bsf     INTCON,5        ;enable TMR0 int
                clrf    TMR0            ;clear timer
                clrwdt                  ;why is this needed? just do it..
                movlw   b'11011000'     ;set up timer. prescaler(bit3)bypassed
                option                  ;send w to option. generate warning.
                clrf    TMR0            ;start timer
                retlw   0
;--------
; test for index in rotation and store period in period_dup
;--------
Check_index     movf    PORTA,w         ;get the state of port a
                xorwf   flags,w         ;compare with saved state
                andlw   b'00010000'     ;only interested in bit 4
                btfsc   STATUS,Z        ;test for edge
                retlw   0               ;not an edge, same as last
                xorwf   flags,f         ;save for next time
                btfsc   flags,4         ;test for falling edge
                retlw   0               ;must have been a rising edge
                movf    period_count,w  ;make a working copy
                movwf   period_dup      ;called period dup
                clrf    period_count    ;a fresh start for next rotation
                clrf    digit_index     ;set to first digit
                clrf    dot_index       ;first column
; calculate a period that does not dither or jitter
; period will not be changed unless new period is really different
                movf    period_calc,w
                subwf   period_dup,w    ;find difference
                btfss   STATUS,C        ;carry flag set means no borrow
                goto    Calc_period_neg ;must be other way
                sublw   2               ;allowable deviation = 3
                btfss   STATUS,C        ;borrow won't skip
                incf    period_calc     ;new value much larger than calc
                movf    period_calc,w
                movwf   period_use
                bcf     STATUS,C        ;clear carry before a rotate
                rrf     period_use,f   
                bcf     STATUS,C        ;clear carry before a rotate
                rrf     period_use,f   
                retlw   0
Calc_period_neg addlw   2               ;allowable deviation = 3
                btfss   STATUS,C        ;carry will skip
                decf    period_calc     ;no carry means it must be changed
                retlw   0
;--------
; change LED pattern based on state of digit_index and dot_index
;--------
Display_now   movlw   0x05
      xorwf   dot_index,w   ;test for end of digit
      movlw   0xFF      ;pattern for blank column
      btfsc   STATUS,Z
      goto   D_lookup_3   ;it needs a blank
      bcf   STATUS,C   ;clear carry before a rotate
      rlf   digit_index,w   ;double the index because each
      addwf   PCL,f      ;takes two instructions
D_10hr      swapf   hours,w   ;D_10hr      
;swapf      period_calc,w
      goto   D_lookup   ;what a great rush of power
D_1hr      movf   hours,w      ;I feel when modifying
;D_1hr      movf   period_calc,w      ;I feel when modifying
      goto   D_lookup   ;the program counter
D_colon   movlw   0x0A   ;the semicolon
      goto   D_lookup
D_10min   swapf   minutes,w
      goto   D_lookup
D_1min      movf   minutes,w
      goto   D_lookup
D_colon2   movlw   0x0A   ;the semicolon
      goto   D_lookup
D_10sec   swapf   seconds,w
      goto   D_lookup
D_1sec      movf   seconds,w
      goto   D_lookup
D_nothing   retlw   0
D_lookup   andlw   b'00001111'   ;strip off hi bits
      movwf   scratch      ;multiply this by 5 for lookup
      addwf   scratch,f   ;table base position
      addwf   scratch,f   ;is this cheating?
      addwf   scratch,f   ;I think not.
      addwf   scratch,f   ;I think it is conserving energy!
      btfss   STATUS,Z   ;test for zero
      goto   D_lookup_2   ;not a zero
      movf   digit_index,f   ;this is just to test/set flag
      movlw   0xFF      ;this makes a blank LED pattern
      btfsc   STATUS,Z   ;test if it is 10 hrs digit
      goto   D_lookup_3   ;it's a leading zero
D_lookup_2   movf   dot_index,w   ;get column
      addwf   scratch,w   ;add it to digit base
      call   Char_tbl   ;get the dot pattern for this column
D_lookup_3   movwf   PORTB      ;send it to the LEDs
;      movlw   0x2C      ;overhead value sub from period
;      subwf   period_use,w   ;compensate for overhead and set
      movfw   period_use
      call   Delay      ;width of digits with this delay
      incf   dot_index,f   ;increment to the next column
      movlw   0x06      ;6 columns is a digit plus space
      xorwf   dot_index,w   ;next digit test
      btfss   STATUS,Z
      retlw   0      ;not a new digit
      clrf   dot_index   ;new digit time
      incf   digit_index,f
      retlw   0      ;Display_now done.
;--------
; a short delay routine
;--------
Delay           movwf   tick
Delay_loop      decfsz  tick,f
                goto    Delay_loop      ;w is not damaged, so Delay can
                return                  ;be recalled without reloading
;--------
; test for keypress and call time adjust if needed
;--------
Check_keys      movf    PORTA,w         ;get port "a"
                xorwf   keys,w          ;compare with previous
                andlw   b'00000111'     ;only care about button pins
                btfsc   STATUS,Z        ;zero set=no buttons
                retlw   0               ;return
                xorwf   keys,f          ;store key value
                movlw   0x64            ;a fairly long delay will
                movwf   scratch         ;prevent key bounces
Key_delay       movlw   0xFF
                call    Delay
                decfsz  scratch
                goto    Key_delay
                btfss   keys,2          ;test "minutes" button
                goto    Inc_mins
                btfss   keys,1          ;test "tens" button
                goto    Inc_tens
                btfss   keys,0          ;test "hours" button
                goto    Inc_hours
                retlw   0               ;must be a glitch. yeah, right!
;--------
; increment ten minutes
;--------
Inc_tens        movlw   0x0A
                movwf   scratch         ;scratch has ten
Inc_tens_loop   call    Inc_mins
                decfsz  scratch
                goto    Inc_tens_loop   ;another minute added
                retlw   0
;--------
; increment one hour
;--------
Inc_hours       movlw   0x12
                xorwf   hours,w
                btfsc   STATUS,Z
                goto    Inc_hours_12
                movlw   0x07            ;this part gets a little sloppy
                addwf   hours,w
                movlw   0x07
                btfss   STATUS,DC
                movlw   1
                addwf   hours,f
                retlw   0
Inc_hours_12    movlw   0x01
                movwf   hours
                retlw   0
;--------
; increment the time based on flags,1 as sent by interrupt routine
; Inc_mins loop also used by time-setting routine
;--------
Keep_time       btfss   flags,5         ;the minutes flag
                goto    Keep_time2              ;no change in seconds
                bcf     flags,5         ;clear the minutes flag
                movlw   0x07            ;start incrementing time
                addwf   seconds,f       ;add 7 seconds into f
                movlw   0x06            ;'oops' decrementing time
                btfsc   STATUS,DC       ;did adding 7 cause digit carry?
                goto    Keep_time2      ;then test for an hour change
                subwf   seconds,f       ;dec 6 seconds into f
Keep_time2      btfss   flags,1         ;the minutes flag
                retlw   0               ;not this time
                bcf     flags,1         ;clear the minutes flag
                clrf    seconds ; clear the seconds & seconds timervalues
                movlw   0xF0            ;3907 = 0x0F43
                movwf   sectick_hi      ;0 - 0x0F43 = 0xF0BD
                movlw   0xBD
                movwf   sectick_lo
Inc_mins        movlw   0x07            ;start incrementing time
                addwf   minutes,w       ;add 7 minutes into w
                btfsc   STATUS,DC       ;did adding 7 cause digit carry?
                goto    Sixty_mins      ;then test for an hour change
                incf    minutes         ;otherwise add 1 for real
                retlw   0               ;and go back
Sixty_mins      movwf   minutes         ;save the minutes
                movlw   0x60            ;test for 60
                xorwf   minutes,w       ;are minutes at 60?
                btfss   STATUS,Z
                retlw   0               ;no? go back
                clrf    minutes         ;otherwise zero minutes
                goto    Inc_hours       ;and increment hours
;--------
; End of subroutines
; Program starts here
;--------
Start           call    Ram_init        ;set variables to nice values
                call    Port_init       ;set port directions
                call    Timer_init      ;start timer based interrupt
;--------
; Done initializing, start the endless loop.
;--------
;
Circle                                  ;begin the big loop
; detect falling edge on PORTA,4 to determine rotary index
; calculate rotation period and store in period_dup
; compare with working period(period_calc) and adjust if way different
                call    Check_index
; check display state and change if needed
                call    Display_now
; check keyboard and adjust time
                call    Check_keys
; check minute flag and increment time if a minute has passed
                call    Keep_time
                goto    Circle          ;you heard the man, get going!
                end
;--------
; end of file
;--------

 


Offline

Skúsený užívateľ
Skúsený užívateľ
Assembler - PIC (Vykreslovač hodín)

Registrovaný: 24.01.08
Prihlásený: 13.09.17
Príspevky: 14572
Témy: 66 | 66
Bydlisko: Žilina
NapísalOffline : 23.04.2013 12:28 | Assembler - PIC (Vykreslovač hodín)

Objasnenie ČOHO? Hádam nie celého kódu :) Skús byť konkrétnejší, budeš mať väčšiu šancu, že ti s tým niekto poradí...


_________________
C#, PHP, ...
Offline

Užívateľ
Užívateľ
Obrázok užívateľa

Registrovaný: 23.04.13
Prihlásený: 24.04.13
Príspevky: 2
Témy: 1 | 1
Napísal autor témyOffline : 23.04.2013 12:29 | Assembler - PIC (Vykreslovač hodín)

Okomentovaný ale fakt tomu nerozumiem :(
Keby aspoň tie komentáre boli preložené.. Mne ale stačí prakticky popísať že "Táto časť slúži na... Táto časť na.." a tak


 [ Príspevkov: 3 ] 


Assembler - PIC (Vykreslovač hodín)



Podobné témy

 Témy  Odpovede  Zobrazenia  Posledný príspevok 
V tomto fóre nie sú ďalšie neprečítané témy.

Schéma: Sériový programátor procesoru PIC 16C84 a PIC 16F84

v Elektronika

0

2910

23.01.2007 4:29

Elektronic

V tomto fóre nie sú ďalšie neprečítané témy.

simulator pic

v Ostatné programy

0

333

26.03.2010 22:45

dsljohn

V tomto fóre nie sú ďalšie neprečítané témy.

programovanie mikroprocesor PIC

v Elektronika

10

2068

26.11.2010 19:06

Xiao Zhuänjiä

V tomto fóre nie sú ďalšie neprečítané témy.

Schéma: Programátor PIC

v Elektronika

8

7990

06.12.2010 23:56

mato3000

V tomto fóre nie sú ďalšie neprečítané témy.

Pic v delphi

v Delphi, Visual Basic

8

581

07.12.2008 15:43

shiro

V tomto fóre nie sú ďalšie neprečítané témy.

program pre pic PIC12F675

v Elektronika

0

352

17.09.2011 22:29

pic12345

V tomto fóre nie sú ďalšie neprečítané témy.

Schemy s procesormy PIC

v Elektronika

0

893

24.12.2006 22:23

Black-Man

V tomto fóre nie sú ďalšie neprečítané témy.

Generator pre piezo s PIC

v Assembler, C, C++, Pascal, Java

0

617

08.08.2007 12:26

Dias

V tomto fóre nie sú ďalšie neprečítané témy.

jednoduchy program do pic 12F675

v Assembler, C, C++, Pascal, Java

3

536

20.09.2011 11:22

Fico

V tomto fóre nie sú ďalšie neprečítané témy.

pomozte program pre pic 12F675

v Elektronika

3

453

18.09.2011 23:20

ac.milan

V tomto fóre nie sú ďalšie neprečítané témy.

Schéma: Regulovateľný zdroj s PIC

v Elektronika

0

2702

23.01.2007 4:37

Elektronic

V tomto fóre nie sú ďalšie neprečítané témy.

Schéma: Človeče nezlob sa s PIC

v Elektronika

0

679

23.01.2007 6:38

Elektronic

V tomto fóre nie sú ďalšie neprečítané témy.

Koľko hodín spávate?

[ Choď na stránku:Choď na stránku: 1, 2 ]

v Život, životný štýl, móda, bývanie

32

2469

27.11.2008 17:57

tommy1104

V tomto fóre nie sú ďalšie neprečítané témy.

Počet nultých hodín

[ Choď na stránku:Choď na stránku: 1, 2 ]

v Vzdelanie, štúdium, škola

33

2622

18.12.2009 12:28

psichac

V tomto fóre nie sú ďalšie neprečítané témy.

Vplyv hodin na SSD

v SSD disky

1

323

26.02.2011 22:43

Psycho

V tomto fóre nie sú ďalšie neprečítané témy.

Zmiznutie ikoniek vedla hodin

v Operačné systémy Microsoft

9

317

29.07.2007 15:17

Rbot



© 2005 - 2018 PCforum, edited by JanoF