Re: Shift Register - 4006B DIP-14 18-Stage Static Shift Regi
Postat: 6 september 2011, 12:46:10
(ursäkta - felpost)
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Jepps.Har du seriemotstånd till varje segment?
Kod: Markera allt
;**********************************************************************
; This file is a basic code template for assembly code generation *
; on the PIC16F690. This file contains the basic code *
; building blocks to build upon. *
; *
; Refer to the MPASM User's Guide for additional information on *
; features of the assembler (Document DS33014). *
; *
; Refer to the respective PIC data sheet for additional *
; information on the instruction set. *
; *
;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
; *
;**********************************************************************
; *
; Files Required: P16F690.INC *
; *
;**********************************************************************
; *
; Notes: Påbörjad klocka med 7 segmentssdisplay *
; *
;**********************************************************************
list p=16f690 ; list directive to define processor
#include <P16F690.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;***** VARIABLE DEFINITIONS
w_temp EQU 0x7D ; variable used for context saving
status_temp EQU 0x7E ; variable used for context saving
pclath_temp EQU 0x7F ; variable used for context saving
TMR0_extra EQU .122
udata 0x20 ;Minnesbanker som används i koden
d1 res 1 ;Tilläggs räknare till TMR0 för att öka tiden
sec res 1 ;Råvärdet för sec, min hour, 2 siffror
min res 1
hour res 1
sec_one res 1 ;Entalet i sekunderna, minuterna och timmarna
sec_ten res 1 ;Tiotalet i sekunderna, minuterna och timmarna
min_one res 1
min_ten res 1
hour_one res 1
hour_ten res 1
t1 res 1
w2 res 1
getones res 1
VARL res 1
VAR res 1
;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
; isr code can go here or be located as a call subroutine elsewhere
MOVLW .0 ; Nollställ TMR0
MOVWF TMR0 ;
BCF INTCON, T0IF ;Nolla TMR0s interrupt flagga
DECFSZ d1 ;Räkna ner TMR0 tillägsräknare, kolla om den är noll
GOTO endIsr ;NEJ, fortsätt räkna
movlw TMR0_extra ;JA, Återställ TMR0 Tillägsräknare
movwf d1
;------ Dela upp i ental tiotal och shifta ut, en ggr i sekunden
;---------Sekunder
INCF sec
MOVFW sec ; Sekunder ++
MOVF sec,W ; Kolla om sekunderna = 60
SUBLW .60 ; Kolla om sekunderna = 60
BTFSS STATUS,Z ; Kolla om sekunderna = 60
GOTO endIsr ; else {
clrf sec ; sec = 0;
;---------Minuter
INCF min
MOVFW min ; Minuter ++
MOVF min,W ; Kolla om Minuterna = 60
SUBLW .60 ; Kolla om Minuterna = 60
BTFSS STATUS,Z ; Kolla om Minuterna = 60
GOTO endIsr ; else {
clrf min ; min = 0;
;---------Timmar
INCF hour
MOVFW hour ; Timmar ++
MOVF hour,W ; Kolla om Timmar = 24
SUBLW .24 ; Kolla om Timmar = 24
BTFSS STATUS,Z ; Kolla om Timmar = 24
GOTO endIsr ; else {
clrf hour ; hour = 0;
endIsr
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
main
; remaining code goes here
BANKSEL PORTA
CLRF PORTA ;Init PORTC
BANKSEL ANSEL
CLRF ANSEL ;digital I/O
BANKSEL TRISA
MOVLW b'00000000' ;Set RA<0-7> as Outputs
MOVWF TRISA
BCF STATUS,RP0 ;Bank 0
CLRWDT ;Clear WDT and prescaler
BANKSEL OPTION_REG
MOVLW b'00000100' ;Select TMR0, prescale, and clock source
MOVWF OPTION_REG
BANKSEL INTCON
MOVLW 0xA0 ;Global interrupt and TMR0 interrupt enabled
MOVWF INTCON
movlw TMR0_extra ;Ladda TMR0s extraräknare med förbestämt värde,
movwf d1 ;definieras i början av koden.
MOVLW .3 ;Nollställ klockan på uppstart.
MOVWF sec
MOVWF min
MOVWF hour
MainLoop
CALL SplitNum
MOVFW sec_one
CALL bin2seg
MOVWF VAR
CALL ShiftOut
GOTO MainLoop
;This routine will return the number of decimal
;hundreds from an 8-bit binary
;Input: w
;Output: w
;RAM:2
;Cycles: 12-24
GETHNDS
movwf t1
clrf w2
gethnds_loop
movlw .100
incf w2,f
subwf t1,f
btfsc STATUS,C
goto gethnds_loop
decf w2,w
return
;---
;This routine will return the number of decimal
;tens from an 8-bit binary
;Loop based, so it might take some time...
;It needs getones too
GETTENS
movwf t1
clrf w2
gettens_loop
movlw .10
incf w2,f
subwf t1,f
btfsc STATUS,C
goto gettens_loop
decf w2,w
return
;---
;This routine will return the number of decimal
;ones from an 8-bit binary
GETONES
movwf w2
movlw .10
deltens_loop
subwf w2,f
btfsc STATUS,C
goto deltens_loop
addwf w2,w
return
;---------------- LookUpTable för 7 segments displayerna
bin2seg
addwf PCL, F ; Jump into the lookup table
retlw H'C0' ; Return segment code for 0
retlw H'F9' ; Return segment code for 1
retlw H'A4' ; Return segment code for 2
retlw H'B0' ; Return segment code for 3
retlw H'99' ; Return segment code for 4
retlw H'92' ; Return segment code for 5
retlw H'82' ; Return segment code for 6
retlw H'F8' ; Return segment code for 7
retlw H'80' ; Return segment code for 8
retlw H'98' ; Return segment code for 9
ShiftOut
MOVLW .8 ;Transfer eight bits
MOVWF VARL ;Initialising counter
LOCALLOOP
RLF VAR,F ;Rotate "Var" on place to the left
BTFSS STATUS,C ;Is carry = "1" ?
BCF PORTA,0 ;If not, set Dataa line to "0"
BTFSC STATUS,C ;Is carry = "0" ?
BSF PORTA,0 ;If not, set Dataa line to "1"
BSF PORTA,1 ;Generate one clock
NOP
BCF PORTA,1
DECFSZ VARL,F ;Has eight bits been sent ?
GOTO LOCALLOOP ;If not, repeat
BSF PORTA,2 ;If all 8 bits have been sent,
NOP ;contents of SHIFT register to send the output latch
BCF PORTA,2
RETURN
SplitNum
MOVFW sec ;Ladda W med sekunder för att få entalen
CALL GETONES
MOVWF sec_one ;Här lagras entalen
MOVFW sec ;Ladda W med sekunder för att få tiotalen
CALL GETTENS
MOVWF sec_ten ;Här lagras tiotalen
MOVFW min ;Ladda W med sekunder för att få entalen
CALL GETONES
MOVWF min_one ;Här lagras entalen
MOVFW min ;Ladda W med sekunder för att få tiotalen
CALL GETTENS
MOVWF min_ten ;Här lagras tiotalen
MOVFW hour ;Ladda W med sekunder för att få entalen
CALL GETONES
MOVWF hour_one ;Här lagras entalen
MOVFW hour ;Ladda W med sekunder för att få tiotalen
CALL GETTENS
MOVWF hour_ten ;Här lagras tiotalen
RETURN
ORG 0x2100 ; data EEPROM location
DE 1,2,3,4 ; define first four EEPROM locations as 1, 2, 3, and 4
END ; directive 'end of program'
Kod: Markera allt
CALL SplitNum
MOVFW sec_one
CALL bin2seg
MOVWF VAR
CALL ShiftOut
Kod: Markera allt
BSF PORTA,2 ;If all 8 bits have been sent,
NOP ;contents of SHIFT register to send the output latch
BCF PORTA,2
Tänker jag rätt så här?:
Jag har Registrena i serie, efter varandra, 4st (en till vaje display).
Istället för att ha en Loop för att "klocka ut" 8 bitar till en display så har jag en Loop som klockar ut 32 bitar (4x8). De första 8 bitarna hamnar på displayen längst ut på serien med register och de sista 8 bitarna hamnar på displayen "närmast" PICen.