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%)]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
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...
benleentje
Golden Member
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 ?
benleentje
Golden Member
Ik zij niet dat je het in de PC moet stoppen maar dat je een relatief jump moest doen.
table addwf PCDat 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
returnJe 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 tableIn 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
Boudie
Vervangen DOOR.
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.
benleentje
Golden Member
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.
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%)]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
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
benleentje
Golden Member
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_0Je 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%)]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
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...
benleentje
Golden Member
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%)]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
benleentje
Golden Member
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
benleentje
Golden Member
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 RETURN1ste 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
benleentje
Golden Member
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 RETURN1ste 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.
