Het maken van een uurwerk via het programma MCU 8051 IDE

Dit topic is gesloten

Je zit in een een eeuwige lus... en er gebeurd ook niets, buiten dat je timer0 continu wordt gestopt en gestart en nooit een overflow via TF0 zal geven omdat hij ook steeds TL0 overschrijft.

Als antwoord op je vragen Thomas
1) Ja, timer0 moet nooit gestopt worden. Deze draait in de achtergrond door en jij moet steeds TF0 'pollen' (=afvragen)
2) Ja
3) Ja, geef TL0 en TH0 de juiste waarde bij start van het programma

Wat je looplicht betreft: in bovenstaande code wordt nagekeken of R1 (=seconden) even of oneven is. Hierdoor ga je elke seconde van richting veranderen. Je moet de minuten (R2) bekijken.

Lambiek

Special Member

100 posten verder en nog geen stap wijzer, dat is dan ook weer knap. :)

Als je haar maar goed zit, GROETEN LAMBIEK.

Tja, volgens mij ontbreekt er essentieel inzicht in hoe computers/microcontrollers werken, en is het hem ondanks diverse goede bedoelingen toch deels gelukt om iemand anders z'n huiswerk te laten maken.

Mijn voorstel zou zijn om "eindelijk" S-man z'n eigen werk te laten doen en niet verder regel-voor-regel het met kleine stukjes tegelijk voor te zeggen zodat hij het een keer zelf moet oplossen. De uitslag van dat experiment laat zich raden, en de school moet daaraan z'n conclusies verbinden.

Ik wil best mensen helpen, maar op het moment dat de situatie is: "Ik heb een maand studie-achterstand en 3 dagen de tijd om m'n opdracht af te maken", dan is antwoord op de vraag: "Kan je m'n opdracht voor me maken?" natuurlijk: "nee", en er is geen tijd genoeg voor "wil je me helpen het te snappen, zodat ik het zelf kan doen?".

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

ik heb mijn code aangepast, maar toch onderbreekt hij elke keer. Hoe kan dat?

rob040

Golden Member

Ik heb twee momenten gehad waar ik heb kunnen lachen:
1. De badeend methode, dat daar zelfs een site van is,
2. De wasmachine uitleg, omdat die zo treffend is.

Tranen springen me bijna in de ogen als ik nu bovenstaande vraag van TS lees.

Tijd voor een slotje, want de eigen inzet blijft ver onder de maat?

ik heb mijn code aangepast, maar toch onderbreekt hij elke keer. Hoe kan dat?

Je werkt toch met een simulator o.i.d. Daarbij zit ook altijd een monitorfunctie waarmee je alle cpu registers en willekeurige geheugenplaatsen zichtbaar kunt maken. Netjes naast elkaar op het scherm ook nog.
Bij de alloude 8600 en mpf systeempjes zat een monitor programma die dit kon. Alleen had je maar een stuk of 10 7 segmentjes om het zien.

Als je stap voor stap de code doorloopt terwijl je de registers en alle vlaggen (de zero, negatief, odd/even, carry, half carry's enz) zichtbaar op het scherm hebt zie je toch wat er er gebeurt en waarom.
Dan zie je exact waarom een jmp wel of niet gebeurt.

Als je op die manier je code stap voor stap doorloopt heb je binnen 10 minuten je probleem helder.

GJ_

Moderator

Op 18 augustus 2016 18:08:15 schreef rob040:
Ik heb twee momenten gehad waar ik heb kunnen lachen:
1. De badeend methode,

HelaHola, die badeend is niet om te lachen, dat is een serieuze methode hoor. Ik heb intussen een heel team van badeendjes om me te assisteren.

Ik zou alleen willen dat TS een keer naar de winkel toog om zich een fijne badeend aan te schaffen en zijn programma stap voor stap te doorlopen. Als ie slim is houd ie op een fijn stuk ouderwets papier bij wat de status van alle registers is.

Voor alle zekerheid, papier:

Als TS dat doet, en alle tips van de hulpvaardige medeCO'ers ter harte neemt mag dat hele programmeersel niet echt een groot probleem opleveren.

Op 18 augustus 2016 18:40:45 schreef GJ_:
Ik zou alleen willen dat TS een keer naar de winkel toog om zich een fijne badeend aan te schaffen

Wel in de winkel exact vragen naar een eendje voor programmeurs. Niet alle bad eendjes kunnen coderen.

Simulator warning:

UART: Frame discarded (according to MCS-51 manuel)
PC: 0x62
Line: 26

datkomt er elke keer op

dat is inderdaad de 3e keer al dat je die warning post.

maarja net als bij je opdracht, als je er zelf niets aan doet, wordt je stapel werk alleen maar groter

Wat is dan het probleem? Moet ik dan veranderen van code?

Arco

Special Member

Waar gebeurt dat? Wij weten niet wat regel 26 is; jij wel... ;)
Is trouwens een warning en geen error; hoeft niet altijd ernstig te zijn...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op 18 augustus 2016 19:59:29 schreef Arco:
Waar gebeurt dat? Wij weten niet wat regel 26 is; jij wel... ;)
Is trouwens een warning en geen error; hoeft niet altijd ernstig te zzijnijn...

Het is een warning, geen error

Op 18 augustus 2016 19:57:11 schreef S-man:
Wat is dan het probleem?

Een mogelijke probleem hier kan zijn: Staat je rubber duck met zijn/haar gezicht naar het scherm. maw. kan het meekijken naar je code ?

Serieus: We hebben geen glazen bol, je hebt iets gewijzigd, maar je zegt niet wat, enkel dat je een error hebt.

Op 18 augustus 2016 19:57:11 schreef S-man:Wat is dan het probleem?

PEBKAC

maar serieus, als je zoiets gaat roepen, zet dan op z'n minst de regelnummers langs je code

code:

ORG 0h
           LJMP start
           ORG 30h

Start:     MOV SCON,#40h         ;serieel kanaal van mode1 8-bit UART variabele baudrate instellen
           MOV TMOD,#22h         ;instellen timer1 als 8-bit auto reload voor baudrategenerator
           ORL PCON,#80h         ;baudrate verdubbelaar activeren
           MOV TH1,#243          ;4800 baudrate
           MOV TL1,#243          ;4800 baudrate
           SETB TR1              ;baudrategenerator activeren
           MOV R1,#000H          ;seconden op 0 (hoef je maar 1x uit te voeren
           MOV R2,#000H          ;minuten op 0
           MOV R3,#000H          ;uren op 0
           MOV P0,#00000001B     ;P0 op 1 zetten, Po wordt gebruikt voor het looplicht 

MAIN:      CALL KLOK
           CALL optellen
           CALL weergave
           LJMP MAIN

KLOK:      CLR TR0               ;de timer0 wordt eerst gewist voor de programma begint
           CLR TF0               ;wissen van de overflow vlag van timer0
           MOV TH0,#37h         ;startwaarde voor 200µs( 65535 - 200 = 65335 = FF37) FF bij de hoogste waarde
           MOV TL0,#37h          ;startwaarde voor 200µs( 65535 - 200 = 65335 = FF37) 37 bij de laagste waarde
           SETB TR0              ;timer0 starten
           JNB TF0,$             ;als TF0=0, spring naar klok
           CLR TF0
           MOV A,R2
           ANL A,#00000001B
           JNZ ONEVEN            ;bit 0=1; spring naar ONEVEN

EVEN:      MOV A,P0
           RL A
           MOV P0,A
           RET

ONEVEN:    MOV A,P0
           RR A
           MOV P0,A
           RET

optellen:  INC R1
           CJNE R1,#60d,optel_ret ;max.waarde = 59 seconden
           MOV R1,#0
           INC R2                 ;verhogen van de minuten
           CJNE R2,#60d,optel_ret ;max.waarde = 59 minuten
           MOV R2,#0
           INC R3                 ;verhogen van de uren
           CJNE R3,#24d,optel_ret ;maximumwaarde = 23 uren
           MOV R3,#0
optel_ret: RET

weergave:
          MOV P1,R1               ;seconden worden weergegeven op poort1
          MOV P2,R2               ;minuten worden weergegeven op poort2
          MOV P3,R3               ;uren worden weergegeven op poort3
          RET
       
          END
{/code}

dit heb ik als code bij JNB TF0,$ onderbreekt altijd de simulatie

ff mezelf quoten:

Op 18 augustus 2016 14:45:13 schreef kohen:
Timer 0 configureer je als mode 2 (auto reload), wat goed is.

Echter, wat jij doet in routine klok is
1. je stopt, steeds keer op keer, de timer0 met het commando CLR TR0, wat niet logisch is. TR0 staat voor 'timer run'
2. je overschrijft steeds de TL0 en TH0 registers waardoor je in een eeuwige lus blijft.
3. logischerwijs zijn TL0 en TH0 gelijk aan elkaar (hoef je maar 1 keer te configureren)

Zie bijlage hoe een (atmel) auto reload timer werkt.

Bron: http://www.atmel.com/images/doc4316.pdf

Van waar komt dat $ teken ? Ik heb het allesinds nog nooit gezien in assembler

ben het vaker tegengekomen als JNB TF0,$ "als timer niet overflow, jump naar laatste instructie"
maar ben niet goed genoeg in assembly thuis of het een zo standaard assembly instructie is dat alle compilers daar mee om kunnen gaan?

Ah, dat wist ik niet. Mijn oude DOS5.0 MC-51 compiler geeft er in ieder geval geen error of warning op :)

Man man man man....

Ik hoop dat het gauw 21 augustus 2016 is......

Wordt werkelijk niet goed van dit geklungel en dat al een paar dagen lang...

GA NOU EINDELIJK EENS GOED KIJKEN WAT DIE CODE STAP VOOR STAP DOET!!!

Ik heb al sinds 1986 geen ASM meer gedaan, maar in twee minuten kun je deze code aan het werk krijgen, zelfs in een Z80 die ik vroeger had... (P2000T voor de liefhebbers)...

Domoticz en ESP8266, goede combo!!!
Arco

Special Member

'$' wordt al sinds het begin gebruikt als 'jump to program counter'. Ik heb nog geen assembler gezien die dat niet ondersteunde.
Is geen instructie, maar een compiler/assembler directive...
(er is trouwens geen enkele reden meer tegenwoordig om dat nog te gebruiken. Beter een label nemen, is veel handiger/duidelijker)

"Location Counter Symbol.
The current value of the location counter (PC) can be used in expressions by placing a '$' in the desired place.
The Location Counter Symbol is allowable anywhere a numeric constant is."

[Bericht gewijzigd door Arco op donderdag 18 augustus 2016 21:27:23 (13%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

In de lessen gebruiken wij die $-teken altijd. Als ik die teken verandert in klok,dan blijft hij in een eeuwig lus zitten. Wat moet ik dan invullen?

Ik heb even de vorige code overgenomen, zodat we gemakshalve met dezelfde code werken en alles niet door elkaar halen.
Opmerkingen, bemerkingen:
1) Die waarden van TH0 en TL0, waarom dienen deze hetzelfde te zijn?
Na 200 microseconden gaat mn Timerflag omhoog en wordt daarna automatisch gereset.. Die 200 microseconden zijn toch juist ingesteld?
2) Bij mij werkt het programma hoe het moet denk ik (buiten het sturen via de seriële poort) Geen foutmeldingen of dergelijke. Na 200 microseconden gaat timer flag omhoog, telt een bit bij op R1 en P1, Eenmaal deze zijn max waarde van 60 bereikt heeft telt hij een bit op R2 en P2, hetzelfde geld voor de uren. Als de LSB bit van R2 = 0 is wordt het gesette bitje op P0 links opgeschoven, als LSB van R2 =1 dan gaat hij naar rechts.
3) Zijn er momenteel nog fouten t.o.v. de opgave? (sturen via de seriële poort niet meegerekend)

code:


           ORG 0h
           LJMP start
           ORG 30h

Start:     MOV SCON,#40h         ;serieel kanaal van mode1 8-bit UART variabele baudrate instellen
           MOV TMOD,#22h         ;instellen timer1 als 8-bit auto reload voor baudrategenerator
           ORL PCON,#80h         ;baudrate verdubbelaar activeren
           MOV TH1,#243          ;4800 baudrate
           MOV TL1,#243          ;4800 baudrate
           SETB TR1              ;baudrategenerator activeren

           MOV TH0,#0FFh         ;startwaarde voor 200µs( 65535 - 200 = 65335 = FF37) FF bij de hoogste waarde
           MOV TL0,#37h          ;startwaarde voor 200µs( 65535 - 200 = 65335 = FF37) 37 bij de laagste waarde
           SETB TR0              ;timer0 starten

           MOV R1,#000H          ;seconden op 0 (hoef je maar 1x uit te voeren
           MOV R2,#000H          ;minuten op 0
           MOV R3,#000H          ;uren op 0
           MOV P0,#00000001B     ;P0 op 1 zetten, Po wordt gebruikt voor het looplicht 

MAIN:      CALL KLOK
           CALL optellen
           CALL weergave
           CALL looplicht
           LJMP MAIN

KLOK:	   
           JNB TF0,klok             ;als TF0=0, spring naar klok
           CLR TF0
           RET

LOOPLICHT: MOV A,R2
           ANL A,#00000001B
           JZ EVEN
           JNZ ONEVEN            ;bit 0=1; spring naar ONEVEN
           RET

EVEN:      MOV A,P0
           RL A
           MOV P0,A
           RET

ONEVEN:    MOV A,P0
           RR A
           MOV P0,A
           RET

optellen:  INC R1
           CJNE R1,#60d,optel_ret ;max.waarde = 59 seconden
           MOV R1,#0
           INC R2                 ;verhogen van de minuten
           CJNE R2,#60d,optel_ret ;max.waarde = 59 minuten
           MOV R2,#0
           INC R3                 ;verhogen van de uren
           CJNE R3,#24d,optel_ret ;maximumwaarde = 23 uren
           MOV R3,#0
optel_ret: RET

weergave:
           MOV P1,R1               ;seconden worden weergegeven op poort0
           MOV P2,R2               ;minuten worden weergegeven op poort1
           MOV P3,R3               ;uren worden weergegeven op poort2
           RET
       
           END

Thomas, wat een verademing tov SMan. Jij leest tenminste wat er gesuggereerd wordt. Sman wacht gewoon op een pasklaar antwoord.

Hou er rekening mee dat de kans bestaat dat jullie uiteindelijk programma sterk op elkaar zal lijken, wat wel zal opvallen bij de leraar... of zitten jullie in een andere school ?

Sman zit in Gent, dat weten we al.

Je code ziet er redelijk goed uit. Timer0 kan je nog 55 microseconden trager instellen, maar dat is dan zijn maximale grens. Hou het dus op 200 uS, zoals het is. Bedenk, Wat moet je doen om aan een 1 sec timer te komen ?

Dit topic is gesloten