Hoi allemaal.

Ik heb een pic 16f690 en programeer in asm.

ik ben begonnen een programma te schrijven voor twee 7 segment displays, dat op iedere 2e elektrische puls een cijfer hoger gaat.

Dit doe ik op de volgende manier :

      
E_1	BTFSC	PORTC,5      ; IS RC 5 HOOG
	GOTO	E_1          ; WACHT TOT RC5 = 0 EN SKIP GOTO E_1
	BTFSC	PORTA,3      ; RA3 = 0 
	GOTO	START        ; SKIP , ANDERS GA NAAR START
	BTFSC	PORTA,5      ; RA5 = 0
	GOTO	RST          ; SKIP , ANDERS GA NAAR RESET
E_01	MOVLW	B'00000001'
	MOVWF	PORTA
	MOVLW	B'00000010'  ; MAAK RA 0 EN RC 1 HOOG
	MOVWF	PORTC	     ; DIT GEEFT 1 OP HET SEGMENT
	BTFSC	PORTC,5      ; IS RC5 WEER HOOG -->
	GOTO	E_001        ; GA NAAR E_001 , ANDERS SKIP
	BTFSC	PORTA,3
	GOTO	START
	BTFSC	PORTA,5      ; EN HETZELFDE
	GOTO	RST
	GOTO	E_01         ; GEEN ACTIE , GA DAN WEER NAAR E_01

E_001	BTFSC	PORTC,5      ; --> WACHT TOT RC5 = 0 
	GOTO	E_001        ; EN SKIP GOTO E_001
	BTFSC	PORTA,3
	GOTO	START        ; GEEN SWITCHES HOOG, SLA DIT OVER
	BTFSC	PORTA,5     
	GOTO	RST
E_0001	MOVLW	B'00000001'  
	MOVWF	PORTA
	MOVLW	B'00000010'
	MOVWF	PORTC	     ; EN SEGMENR GEEFT NOG STEEDS 
	BTFSC	PORTC,5      ; EEN 1 AAN
	GOTO	E_2          ; IS RC5 WEER HOOG GA NAAR E_2
	BTFSC	PORTA,3      
	GOTO	START
	BTFSC	PORTA,5      
	GOTO	RST
	GOTO	E_0001

Ik wil zo doortellen tot 75 waarna een puls hem weer reset.
op zich super simpel dus.

Het programma wordt zo alleen veel te groot.
Ik zou de cijfers 0 t/m 9 graag opslaan en op kunnen roepen maar heb geen idee hoe dat moet.

wie kan mij op weg helpen ?

grtz Beest

[Bericht gewijzigd door beest820 op (21%)]

Misschien zou een weinig commentaar bij de geplaatste code handig zijn?
Ik denk dat zo niemand een flauw idee heeft wat het zou moeten doen...

Werk met zoiets als een relatieve jump. De waarde in een register bepaald dan hoeveel geheugen plaatsen hij vanaf die plaats moet overslaan. Als er een 1 staan dan slaat het er 1 over. Op die geheugen plaats zet je dan de waarde voor 1

De compiler regelt de geheugen plaatsen jij zet het gewoon in een lijst neer.

[Bericht gewijzigd door benleentje op (39%)]

Hoi benleentje,
ik heb even de datasheet erbij gepakt en bij het geheugen gekeken.
Ik zoek nu bij het ram geheugen.

ik heb een stack level 1 t/m8,
reset vector = 0000h,
interrupt vector = 0004h,
on-chip program memmory = 0FFFh -> 0005h ,
Access 0-FFFh = 1FFFh -> 1000h,

13 bits breed programm counter

en twee instructies : CALL , RETURN
RETFIE , RETLW

Moet ik mijn switchte's en cijfers 0 t/m 9 in de programm counter gaan opslaan ?

Ik zij niet dat je het in de PC moet stoppen maar dat je een relatief jump moest doen.

 table     addwf   PC

Dat is wat deze regel doet. tel de inhoud van het werkregister op bij PC. Je cijfers 0 t/m 9 komen dan ook in het programma geheugen.


 PC   equ  02


    movlw  03
    call       table

    :
    table     addwf   PC
    retlw     01
    retlw     02
    retlw     03
    retlw     04
    retlw     05
    retlw     06
    retlw     07

    return

Je moet nu achter retlw de juiste bitwaarde voor elke cijfer zetten. Deze waarde wordt in W gezet en het programma springt weer terug naar de volgende regel achter

call       table

In dit voorbeeld wordt de waarde 3 opgeteld bij de PC en de geretourneerde waarde is 03

Nu begin ik er iets meer van te begrijpen,en ga hiermee aan de slag.
ik laat je horen hoe het is gegaan.
tnkz beest.

Hoi benleentje ik ben met je hulp aan de slag gegaan.
De relatieve jump werkt goed.

Ik krijg het alleen niet voor elkaar om bij elke 2e puls, pas naar
de table te springen.Ik ging ervan uit dat ik dat met "pc equ 02"
kon instellen.
Maar dit lijkt niet te werken.

 
E_0     CLRF	PORTA
	CLRF	PORTB		; <-- E_03 
	CLRF	PORTC		;alle poorten laag
	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_1
	GOTO	E_0		;anders terug naar E_0


E_1	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_1		;en wacht tot rc 5 = 0
	MOVLW	01
	CALL	TABLE		;rerurn rtlw 01
E_01	MOVLW	B'00000001' 
	MOVWF	PORTA
	MOVLW	B'00000010'	;dit geeft 1 op segment
	MOVWF	PORTC
	BTFSC	PORTC,5
	GOTO	E_2		;rc5 = 1 ga naar E_2
	GOTO	E_01		;anders terug naar e_01


E_2	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_2	        ;en wacht tot rc 5 = 0
	MOVLW	02
	CALL	TABLE
E_02	MOVLW	B'00000011'
	MOVWF	PORTA
	MOVLW	B'00010000'	;dit geeft 2 op segment
	MOVWF	PORTB
	MOVLW	B'00000101'
	MOVWF	PORTC	
	BTFSC	PORTC,5		;rc5 = 1 ga naar E_3
	GOTO	E_3
	GOTO	E_02		;anders terug naar E_02


E_3	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_3
	MOVLW	03
	CALL	TABLE
	CLRF	PORTB
E_03	MOVLW	B'00000011'
	MOVWF	PORTA
	MOVLW	B'00000111'	;dit geeft 3 op segment
	MOVWF	PORTC	
	BTFSC	PORTC,5
	GOTO	E_0		;rc5 = 1 ga naar E_0 -->
	GOTO	E_03		



TABLE	ADDWF	PC

PC	EQU	02	

	RETLW	01     
	RETLW	02     	
	RETLW	03       
	
	RETURN

Zou je me nog een stukje op weg willen helpen.
grtz beest

Gebruik een extra variabele.
Bij start van je programma zet je die op 0.

Bij elke puls test je de variabele:
indien 0: verhoog 'm met 1
indien 1: zet op 0 en doe je ding

Je hebt de bedoeling van die tabel duidelijk niet gesnapt. Die tabel gebruik je als lookup voor het bitpatroon. Dus wil je een 5 op je segment. Dan movlw d'05 call table. En dan komt in je W het juiste bitpatroon te staan. Die stuurt je dan door naar de poort.

Wat je nu doet is de tabel op roepen, dan een nutteloze waarde terug sturen. Eerst doe je movlw d'01 en dan laat je die tabel hetzelfde terug sturen. En dan ipv die waarde te gebruiken zet je met movlw weer een nieuwe waarde in je W.

ok, dan ga ik nog even verder.

Je kan ook niet iets willen programeren voordat je eerst alles even op papier zet wat je programma moet doen.

voorbeeld
Kijk naar een puls op portc.5
Tel elke keer tot de 2de puls
Maak de teller 1 hoger.
Zet de inhoud van de teller op het display.

Hoe je dit dan verder oplost is voor een ieder anders. JE kan voor teller 1 variabele gebruiken die van 0 t/m 99 gaat maar je kan er ook 2 gebruiken die elk van 0 t/m 9 gaat.

Bij de eerste methode moet je op een lastige manier de waarde van elk van de display omrekenen.

Bij de 2de manier hoeft dat niet. Je zegt dan gewoon als
teller1 = 10 then
teller1 = 0:
teller2 = teller2 + 1

En dit dan in asm code:P
Teller1 kan je dan via de lookup tabel direkt naar het display schrijven. Als teler1 8 is dan spring je naar de 8ste retlw regel in de tabel. Die geeft dan de segment waarden voor.

gaat moeilijker dan verwacht, maar ga gewoon door.

Heb het voor elkaar gekregen om de bitwaarden in te stellen en op te roepen.De segmenten geven nu de juiste nummers aan.
Is het op deze manier wel goed ?

 

E_0     CLRF	PORTA
	CLRF	PORTB		; <-- E_03 
	CLRF	PORTC		;alle poorten laag
	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_1
	GOTO	E_0		;anders terug naar E_0

E_1	CLRF	PORTA
	CLRF	PORTB	
	CLRF	PORTC
	BTFSC	PORTC,5
	GOTO	E_1
E_01	MOVLW	00		;haal bitwaarden op
	CALL	TABLE
	MOVWF	PORTA		
	MOVLW	01
	CALL	TABLE
	MOVWF	PORTC		;--> bitwaarden naar poorten	
	BTFSC	PORTC,5
	GOTO	E_2		;rc5 = 1 ga naar E_2
	GOTO	E_01		;anders terug naar e_01

E_2	CLRF	PORTA
	CLRF	PORTB	
	CLRF	PORTC
	BTFSC	PORTC,5
	GOTO	E_2
E_02	MOVLW	02
	CALL	TABLE
	MOVWF	PORTA
	MOVLW	03
	CALL	TABLE
	MOVWF	PORTC
	MOVLW	04
	CALL	TABLE
	MOVWF	PORTB
	BTFSC	PORTC,5		;rc5 = 1 ga naar E_3
	GOTO	E_3
	GOTO	E_02		;anders terug naar E_02

E_3	CLRF	PORTA
	CLRF	PORTB	
	CLRF	PORTC
	BTFSC	PORTC,5
	GOTO	E_3
E_03	MOVLW	02		; haal bitwaarden op
	CALL	TABLE           
	MOVWF	PORTA           ;--> stuur bitwaarde uit
	MOVLW	04
	CALL	TABLE
	MOVWF	PORTB
	MOVLW	07
	CALL	TABLE
	MOVWF	PORTC		:--> stuur bitwaarde uit
	BTFSC	PORTC,5
	GOTO	E_0		;rc5 = 1 ga naar E_0 -->
	GOTO	E_03		



TABLE	ADDWF	PC

	
	RETLW	01	;1
	RETLW	02	;1 bitwaarden voor 1 -->

	RETLW	03 	;2 
	RETLW	05	;2
	RETLW	10	;2 bitwaarden voor 2 -->

	RETLW	02	;3
	RETLW	07	;3 bitwaarden voor 3 -->
	
	RETURN

grtz beest

[Bericht gewijzigd door beest820 op (36%)]

Ik zie nog niet echt in, dat die tabel iets nuttigs teruggeeft...
Maar het zou natuurlijk wel helpen als je eerst eens opgeeft wat er waar zit aangesloten. (Schakelaars, displays)
Je stuurt nu alledrie de poorten aan om iets op het display te krijgen???

er zit aan gesloten :

2 switches met 2 dioden op 1 poort aangesloten ra3. als input
deze switches resetten de segment displays, en schakelen op een ander ic twee inputs die lampen 24 volt, via een schakeling laat knipperen.(de segment displays begint weer bij 0)

1 switch die de segment displays uitzet,na een loopje.op input ra5.
de segment displays springen na de loop na start.
voor dit loopje word output ra4 hoog die op een ander ic de lampen een stoppuls geeft.

1 switch met twee dioden op input rc5. Deze telt de pulsjes van de lampen."kan er maar een te gelijk branden" en moet op het segment display op iedere tweede puls een cijfer optellen.
dit omdat ze 1 x snel en 1 x iets langzamer knipperen.

op het moment dat het segment display 75 toont.Ga ik weer naar het eerder genoemde loopje, de flitslampen gaan uit, en daarna weer naar
start.

in start geeft het segment display ON aan.

alle overige I/O 's zijn outputs.

rc6
__
rc7 | |rc3
--rb7
rc4 |__|rb5
rb6 10 tallen

......ra1
.......__
..ra2 | |ra0
.......--rc0
..rb4 |__|rc1
.......rb6 1 tallen

Het zit zo door elkaar omdat het op een prinje zit
ik zou anders veel kruisingen krijgen

Sterker nog het hele programma doet niets nuttigs. Er zal elke keer wel wat op het display komen maar dat heeft helemaal niets met enige vorm van tellen te maken.

Maak de teller 1 hoger.
Zet de inhoud van de teller op het display.

Waar gebruik je een teller in je programma?????????


E_0     CLRF	PORTA
	CLRF	PORTB		; <-- E_03 
	CLRF	PORTC		;alle poorten laag
	BTFSC	PORTC,5		;rc5 = 1 ga naar E_1
	GOTO	E_1
	GOTO	E_0		;anders terug naar E_0

Je wilt hier enkel kijken of pin c,5 hoog word. Waarom clear je dan eerst 3 poorten. Je cleart zelfs de poort waarin je te testen pin zit. Niet een logische manier van testen.
Op portA zit je display en die clear je ook als je enkel 1 pin wil testen.

Ik adviseer je om eerst even deze cursus tot je te nemen alvoren het verder te proberen.
http://www.mstracey.btinternet.co.uk/pictutorial/progtut5.htm

Ik clear de ouputs omdat die niet laag worden gemaak bij mijn effecten.Als ik dit niet doe blijven ze dus aan staan.

De pulsjes zijn lang genoeg om gezien te worden.Dit levert geen probleem op.
grtz beest

[Bericht gewijzigd door beest820 op (28%)]

2 switches met 2 dioden op 1 poort aangesloten ra3. als input

Heb je geen schema dat je kunt posten? Bovenstaande zin is niet erg begrijpelijk...
Ook zie ik het display nog steeds nergens terug...

Op 29 augustus 2009 13:34:52 schreef beest820:
Ik clear de ouputs omdat die niet laag worden gemaak bij mijn effecten.Als ik dit niet doe blijven ze dus aan staan.

Welke effecten dat zie ik nergens in je programma terug.
En bij een display is het wel de bedoeling dat een output aan blijft staan anders ziet je niet zoveel op dat display.

De pulsjes zijn lang genoeg om gezien te worden.Dit levert geen probleem op.

Ik probeer je enkel een logische manier van programmeren aan te leren.
Als het nodig is om poorten te clearen doe je dat niet in het gedeelte waar je een pin test. Dat doe je in het gedeelte van het programma waar je de poorten aanstuurt.

[Bericht gewijzigd door benleentje op (30%)]

Ik geef het op. Kan nu zelfs de antwoorden niet meer volgen... |:(

IK geef het ook op. Dit slaat echt helemaal nergens meer op.
HEt lijkt me sterk dat je enig idee hebt waar je mee bezig bent. Je programma trekt op niks en je antwoorden ook niet.

Geeft eens wat meer info.
Welk schema gebruik je.
Gebruik geen crossposting. Je zet antwoorden neer van ergens anders vandaan maar niet van dit topic.

[Bericht gewijzigd door benleentje op (30%)]

3 wazige posts verwijderd, beest820 probeert het nog maar eens, en nu duidelijk zodat we er nog wat van snappen.

Ben nog even aan de slag gegaan om alles duidelijker toe te lichten.

Ik omschrijf alle functies onder dit schema




                                                  IC 2
                                                   __
                                           rb6o--o|  |o--orb7            T
                                           rb5o--o|  |o--orc7           ---
                                           rb4o--o|  |o--orc6        .--o o- +  sw1
                         o                 rc2o--o|  |o--orc3        |
                         |                 rc1o--o|  |o--orc4        |   T
                         -                 rc0o--o| rc5  /-ra3|<-o---'  ---
                         ^ ->              ra2o--o| ||o-/-ra3-|<-).-----o o- +  sw2
                         |                 ra1o--o| ||o--ra4-->|-))--.
                   LED   |                 ra0o--o| ||o-ra5---|<-))--|   T
                 o-|<----)->|---\          vsso--o|_||o-+        ||  |  ---
                       | |->|----\------------------'            ||  |--o o- +  sw3 reset
                     o | |                    |                  ||  |
                     | | | | | | | | | |      |                  ||  |
                     o_o_o_o o_o_o_o o_o     .-.                 ||  |
                    |rc0 1              |    | |                 ||  |
               IC 1 | _ _ _   _ _ _   _ |    | |                 ||  |
                     o o o o o o o o o o     '-'                 ||  |
                     | | | | | | | | | |      |                  ||  |
                     + | | |                  o                  ||  |
                       | | 'ra3----------------------------------'|  |
                       | 'ra4----|--------------------------------'  |
                       ra5--|---.-.----------------------------------'
                       |   .-.  | |
                      .-.  | |  | |
                      | |  | |  '-'
                      | |  '-'   |
                      '-'   |    o
                       o    o

 

als er spanning aanwezig is : ic2 gaat naar het start effect en geeft op het 7 segment display ON aan
ic 1 wacht op een startpuls van sw1 of sw2

sw1: input ra3 ic 2 --> 7 segment display begint te tellen vanaf 1 als rc5 hoog word,iedere 2e puls word hij een cijfer hoger.
input ra3 ic 1 --> laat led 1 knipperen via output rc0

sw2: input ra3 ic 2 --> 7 segment display begint te tellen vanaf 1 als rc5 hoog word,iedere 2e puls word hij een cijfer hoger.
input ra4 ic 1 --> laat led 2 knipperen via output rc1

sw3 reset: input ra5 ic2 --> ga naar effect voor afsluiten voor het 7 segment display.
input ra5 ic 1 --> wacht op een startpuls van sw1 of sw2

als de outputs rc0 of rc1 van ic 1 hoog zijn. wordt op iedere 2e puls die op ingang rc5 van ic2 binnen komt, het getal op het 7 segment display met 1 verhoogd.

als het 7 segment display 75 weergeeft --> word output ra4 ic2 hoog en ic1 gaat weer naar de startpositie.ic2 geeft het effect voor het afsluiten weer,hierna gaat hij naar het start effect,waar hij weer on aangeeft.

Mijn vraag : hoe kan ik programeren dat op iedere 2e puls mijn 7 segment display een cijfer omhoog gaat ?

hoe zet ik de outputs voor de cijfers : 0 t/m 9 op een plaats in het programma die ik op kan roepen.

De aansluiting van de display's zijn van vss tot rb6 , en van rc4 tot rb7.Dat is dus voor ieder segment een uitgang, en vss.
De aansluiting op het display kan ik makkelijk veranderen.
dus daar hoef je met tips waarschijnlijk geen rekening mee te houden ?

grtz beest

Het is me nog steeds niet duidelijk.
In je verhaal verwissel je denk een paar ic1 en ic2 met elkaar

als de outputs rc0 of rc1 van ic 1 hoog zijn. wordt op iedere 2e puls die op ingang rc5 van ic1 binnen komt, het getal op het 7 segment display met 1 verhoogd

Dit gebeurt toch allemaal op ic2 neem ik aan?

Welk ic is IC1 en IC2?
Waar zit het 7 segment display op aangesloten

hoe zet ik de outputs voor de cijfers : 0 t/m 9 op een plaats in het programma die ik op kan roepen.

Heb ik je al vertelt en er ook al een voorbeeld van gegeven


   PC          EQU     02


01  TABLE	ADDWF	PC
 
 
02     	RETLW	01	;1
03	RETLW	02	;1 bitwaarden voor 1 -->
 
04	RETLW	03 	;2 
05	RETLW	05	;2
06	RETLW	10	;2 bitwaarden voor 2 -->
 
07	RETLW	02	;3
08	RETLW	07	;3 bitwaarden voor 3 -->
 
09	RETURN

1ste regel zegt dat Programma counter PC op geheugen plaats 02 staat. Dit is enkel een declaratie van een variabele

2de regel tel de inhoud van W bij een register op. In dit geval is dat register PC waarvan we gezegd hebben dat die op geheugen locatie 2 staat.

Nu wordt het interessant. De PC houd heel precies bij op welke plaats in het geheugen de volgende insructie staat die uitgevoert moet worden. Normaal zou de 3de regel worden uitgevoerd maar nu gebeurt er iets bijzonders. JE hebt nu een getal bij de PC opgeteld. Stel dat dit getal 4 is en de instructie.

addwf,pc wordt uitgevoerd.

W = 4
PC = 02

De cpu in de PIC staat nu op de 1ste regel in je programma maar heeft ondertussen automatisch de PC met 1 verhoogt. De PC staat altijd 1 geheugen locatie verder daan waar de cpu mee bezig is om uit te voeren.

add 4 bij 02 = 6 en stop dit in PC. PC is nu 6

De cpu in de PIC zit nu 06 in de PC staan en gaat nu verder met instructies uitvoeren vanaf locatie 06 in je programma. Zodra het daar is aangekomen wordt de pc weer automatisch met 1 verhoogd.

De 6 de regel wordt nu uitgevoerd.

RETLW 10h

RET is return en laat het programma terug springen naar

Het is me nog steeds niet duidelijk.
In je verhaal verwissel je denk een paar ic1 en ic2 met elkaar

als de outputs rc0 of rc1 van ic 1 hoog zijn. wordt op iedere 2e puls die op ingang rc5 van ic1 binnen komt, het getal op het 7 segment display met 1 verhoogd

Dit gebeurt toch allemaal op ic2 neem ik aan?

Welk ic is IC1 en IC2?
Waar zit het 7 segment display op aangesloten

hoe zet ik de outputs voor de cijfers : 0 t/m 9 op een plaats in het programma die ik op kan roepen.

Heb ik je al vertelt en er ook al een voorbeeld van gegeven


   PC          EQU     02

01        MOVLW 4
02        call table
03        MOVWF portA

101  TABLE	ADDWF	PC
 
 
102    	RETLW	01	;1
103	RETLW	02	;1 bitwaarden voor 1 -->
 
104	RETLW	03 	;2 
105	RETLW	05	;2
106	RETLW	10	;2 bitwaarden voor 2 -->
 
107	RETLW	02	;3
108	RETLW	07	;3 bitwaarden voor 3 -->
 
109	RETURN

1ste regel zegt dat Programma counter PC op geheugen plaats 02 staat. Dit is enkel een declaratie van een variabele

2de regel is de 1ste regel van je programma
Zet de waarde 4 in W. Dit is de waarde van het cijfer die je uit de tabel wilt halen. We gaan nu naar de 4de regel in de tabel

CALL table. De cpu gaat nu verder met instructies uitvoeren op locatie table De instructie die het daar vind is

ADDWF,pc

tel de inhoud van W bij een register op. In dit geval is dat register PC waarvan we gezegd hebben dat die op geheugen locatie 2 staat.

Nu wordt het interessant. De PC houd heel precies bij op welke plaats in het geheugen de volgende instructie staat die uitgevoerd moet worden.

addwf,pc wordt uitgevoerd met
W = 4
PC = 102

De PC wordt altijd automatisch met 1 verhoogd door de cpu als het daar is aangekomen vandaar dat pc niet 101 is maar 102.

add 4 bij 102 = 106 en stop dit in PC.

De cpu in de PIC ziet nu 106 in de PC staan en gaat nu verder met instructies uitvoeren vanaf locatie 106 in je programma. Zodra het daar is aangekomen wordt de pc weer automatisch met 1 verhoogd.

De 106 de regel wordt nu uitgevoerd.

RETLW 10h

RET is return en laat het programma terug springen naar de regel achter de CALL instructie. Het programma gaat nu naar regel 03 en W heeft de waarde 10h mee gekregen. Deze waarde kan je nu op je display zetten.