2de zit Microcontrollers

Dit topic is gesloten

Tot ziens soldeertin

Ik denk dat de opmerking over het compenseren van de timer niet van toepassing is in deze opdracht, gezien je kennis van assembler en embedded programming kan ik me niet indenken dat je leraar dat van je verwacht.

Magoed, succes met je opdracht, en mijn opmerking over wachttijden geldt natuurlijk ook voor wachten op een karakter via de serieele poort (je bent immers ongeveer 2ms bezig met 1 karakter...)

Meep! Meep!
free_electron

Silicon Member

Op 15 juli 2011 11:11:06 schreef PbSn:
Afdrukken van een der drie tijdcounters bv hh in ACC:

code:



      mov B,#10
      div AB
      add a,#'0'
      acall write_uart
      mov a,B
      add a,#'0'
      acall write_uart

je bent KNETTERGEK . waarom haal je daar nou al dat rekenwerk bij ?
en een CALL ? komaan zeg.... inline !
zenduart is 2 instructies... karakter in scon gooien en wachten op TX1 ...

je verspeelt meer tijd met call en return dan dat het waard is.
en die call en ret vreten 3 bytes rom + de nodige cpu cycli.
je moet de dptr immers laden en trug plaatsen. ( we gaan er dan nog niet vanuit dat je de context saved. dan verspil je nog meer tijd , en code en rom space en stackspace. )

ik tel niet in het hoofdprogramma. de teller logica zit in de inthandler. die updated de 6 bytes en zet een vlag.
in de main thread test ik vlaggen en dispatch ik daar de zendroutines.

ik heb al eens ganse epistels gepost over hoe je threaded low level programmeert.

kwestie van een pak sequences te maken. die zijn netjes allemaal deterministisch in lengte.
interrupthandlers doen het hoogstnodige en de atomaire operaties. eenmaal klaar zetten ze een vlag.

het hoofdprogramma is een while(1) die gewoon vlaggen checkt en de sequences dispatcht.

ik gebruik meestal een van de hardware counters om een timed interrupt te maken. die levert dan een heartbeat af. daar haak je dan software tellers op in. als die aflopen . vlag zetten. de dispatcher handelt de rest wel af.

je kan zo mooi sequences maken om iets te doen. eentje doet poort output. eentje input. eenje het lcd , eentje doet het menu eentje doet dit en eentje doet dat.
als de input sequence iets detecteert ( key_hit) dan dispatcht ie de processor daar voor. enzovoort.

er is nog een ander element: Je kan gebruik maken van een watchdog.
in princiepe moet je dispatcher om de zoveel tijd doorlopen worden ( sequences zijn altijd non-blocking. )
als er toch ene vastloopt dan gaat die watchdog gegarandeerd komen bijten.

ik was gisteren ook zoiet aant debuggen. bleek dat die de 'codeschijters' geen benul hebben hoe ze met een watchdog moeten omgaan. ze waren vanuit 3 verschillende threads die watchdog aant clearen.. zo werkt dat natuurlijk niet he..
eentje had commentaar. 'ik haat watchdogs. ik zet ze meestal af [ERM]kreun[/ERM]'

Op 15 juli 2011 11:17:31 schreef Uranium:
Ik zou de code van FE nog aanpassen als volgt.

Ipv bv t_minuten te laten beginnen op 0 en tot 5 te laten gaan laten beginnen bij '0' (48) en tot '5' (53)

ssst. die hield ik achter de hand voor als er iemand toch per se wou bewijzen dat hij compactere code kon schrijven. met die truuk kon ik nog een 30 tal instructies van mijn piepklijn programmatje afschaven.

Bravo ! dikke kus van de juffrouw en een bank vooruit.

inderdaad. voor die processor maakt het geen fluit uit of hij nu 0 tot 9 moet doen of '0' tot '9'. ascii karakters zijn ook binaire waardes voor een cpu.

je kan dus direct in ascii tellen. ben je gelijk van al dat gemov en add vanaf.

je code blijft identiek. alleen initialiseer je de variabelen niet op nul maar op 48 ( ascii waarde van '0' is 48 decimaal )

ziet er dan zo uit :

code:


[init]

eseconden=48
tseconden=48
blaaa
port1 = 1.

if tick
   
   eseconden = eseconden +1
   if eseconden = 57 then
      eseconden = 48
      tseconden = tseconden +1
      if tseconden = 54 then
         tseconden = 48
         eminuten = eminuten +1
       .... blablabla
    
  nu gaan we zenden
   scon = turen
   wacht op txclear
   scon = euren
   wacht op txclear
   scon = ':'
   blaaaa

   scon = 10  ' carriage return . we overschrijven huidige lijn
   wacht op txclear vlag
  
   if (tminuten and 1) ' test even of oneven van eenheden minuten
      port1 = rol(port1)
     else
      port1 = ror (port1)
end if

tis wreed moeilijk he ?

@pbsn : timer1 in 16 bit of 13 bit mode vlammen. kijken welk kristal je hebt en daar een downcounter met automatic reload programmeren.
11.520 is een mooi getal. je kan daar zonder problemen 200 us uit halen. desnoods met de prescaler spelen.
als je per se met 8 bit moet dan doe je dat maar je plaatst een regel commentaar dat het niet accuraat is en je geeft het alternatief er meteen bij. tis 2 minuten werk.

kwestie van even in datasheet van intel te kijken waar je allemaal kan mee spelen. En als je echt een luie reet wilt zijn : ga bij silicon labs hun IDE halen. die is gratis. er zit een timer wizard in, en een c compiler en een assembler.
je pletst er je kristal requentie in en je tikt de gewenste waarde. de assembly rolt er zo uit.

en als je je code wilt simuleren : ik geloof dat oshonsoft een gratis 8051 emulator heeft. anders ga je maar naar 8051.com. daar staan bakken tools en voorbeelden voor die core.
8051 is de meest gebruikte core ter wereld. Er zijn meest fabrikanten die het ding maken en meest varianten van. Het is ook een van de oudste cores.
Dat ding is gemaakt voor deep embedded spul. De architecten van dat ding wisten heel goed waar ze mee bezig waren. er zijn zelfs registerbanken zodat je context swap compleet kan vermijden.

als we natuurlijk Crap++ gewend zijn van het vliegend schijt type...
@TS

Je aanpak is totaal verkeerd. ik zie daar overal wachtlussen. dat is dus not done.
lees mijn posts of threaded programmeren. Twas iets met ledjes die moesten knipperen en branden afhankelijk van druktoetsen.

je praat over variableen definieren. er is niks te definieren in assembly. je pakt gewoon een vrij ram plaats en vooruit met de geit.

doe me een lol.
gooi je code daar weg en begin met een schone lei.

alloceer 6 bytes uit en initialiseer ze op 48(decimaal)

schrijf je baudrate generator code ( ik zie in jouw code veeeeel te veel instructies daarvoor. het kan met 3 of 4. )

laad poort1 met het getal 1 zo hebben we al een ledje wat brandt

vlooi nu je 200us code uit.

schrijf een interrupt handler en maak daar die teller ladder.
op het end van die ladder zet je een boolean op '1'.

je hoofdprogramma is een eindeloze lus met daarin een if-then

code:


  if 'tick' ( de eerder genoemde boolean )
   tick = 0
   scon = digit
   wacht op TI
   scon = volgend digit
   blabla
   if minuten and 1 ror(poort)
     else rol (poort)

post wanneer je een stukje hebt. We gaan je wel helpen de boel te optimaliseren.

die ganse code is geen bladzijde assembly.

[Bericht gewijzigd door Henry S. op vrijdag 15 juli 2011 20:58:31 (46%)

Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
free_electron

Silicon Member

we gaan eens commentarieren.

code:


PROGRAMMA 2de ZIT

 
        ORG 0h
        LJMP start    / wat is er ms met een SJMP ? geen rom verspillen ! en waar is die start ?
        ORG 30h

        CLR TR0         / zever in pakskes. die liggen stil na reset. weg ermee
        CLR TF0         / zever in pakskes. die liggen stil na reset. weg ermee.
        CLR TR1         / zever in pakskes. die liggen stil na reset. weg ermee   
        CLR TF1         / zever in pakskes. die liggen stil na reset. weg ermee        
        MOV TMOD,#00100010b     ; timer0 en 1 in 8-bit auto-reload timer
        MOV TH0,#37             /zever. je staat in 8 bit mode. high speelt niet mee
        MOV TL0,#37             ; 200µs
        MOV TH1,#243            ; 4800 baud
        MOV TL1,#243
        MOV SCON,#40h           ; mode 1
        ORL PCON,#80h           ; baud verdubbelaar
        MOV IE,#10001010b       ; interrupts enablen
        SETB TR0                ; timer 0 starten
        SETB TR1                ; timer 1 starten
        JNB TF0,$         //  waarom ? das zever. GO !
 // je baud init is ook vele te lang. ik moet eens juist rekenen maar het kan korter.        
        
send:   CLR TI                  ; transmitvlag laag zetten
        MOV SBUF,#'Z’           ; letter Z in SBUF plaatsen
        JNB TI,$                ; wachten tot transmitvlag hoog komt (= byte verstuurd)
        JMP send // a nee. we gaan niet terug zende hee. RET !

loopli: MOV P0,#11111110b
        CALL tijd          / nee
        MOV P0,#11111101b
        CALL tijd          / Nee
        MOV P0,#11111011b
        CALL tijd          / nog nee-er
        MOV P0,#11110111b
        CALL tijd          / nog meer nee
        MOV P0,#11101111b
        CALL tijd          nog eens nee
        MOV P0,#11011111b
        CALL tijd         / njet
        MOV P0,#10111111b
        CALL tijd         /nada
        MOV P0,#01111111b 
        CALL tijd         /niente
        LJMP loopli

loopre: MOV P0,#01111111b
        CALL tijd          / ist'nu bijna gedaan ja ?
        MOV P0,#10111111b
        CALL tijd
        MOV P0,#11011111b
        CALL tijd
        MOV P0,#11101111b
        CALL tijd
        MOV P0,#11110111b
        CALL tijd
        MOV P0,#11111011b
        CALL tijd
        MOV P0,#11111101b
        CALL tijd
        MOV P0,#11111110b
        CALL tijd
        LJMP loopli

        en wat is al dat gefrunnik met die bits. ?
gebruik SHL en SHR of RR en RL.
hier staan al de opcodes. http://www.8052.com/set8051

mov acc,p0
rr a
mov p0 acc

klaar.


Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM

@FE: toch ben ik het niet helemaal met je eens; het tellen van pulsjes doe je met een veel hogere frequentie dan het verzenden van de tijd. Toegegeven, aangezien de gewenste update frequentie hier 1Hz is, en je secondes telt, is jouw aanpak hier efficiënter (wat processortijd betreft). Als de gewenste resolutie (veel) groter wordt dan de update frequentie (dus de frequentie waarmee je de data naar buiten moet sturen), wordt het interessanter om de gewoon pulsjes te tellen, en het pas om te rekenen als je het gaat versturen.

Daarbij, je hebt hier het voordeel dat je zelf kunt beslissen wanneer je de data gaat versturen, en dat doe je dus vlak nadat je deze geupdate hebt. Als er een externe trigger komt, of het verzenden van de data (mogelijk) langer duurt dan de update periode, zul je een mirror van die data moeten maken. Dat is een stuk eenvoudiger als het een grote integer is, dan met 6 losse variabelen.

Het is natuurlijk ook afhankelijk van de mogelijkheden van de processor; met een hardware multiplier en divider ligt het optimum ergens anders dan wanneer die allebei ontbreken.

Een timediff() functie is veel eenvoudiger met getelde pulsen, dan met losse bytes. Als je de tijd door wilt geven aan een andere functie, zul je er een struct van moeten maken, of alle 6 de variabelen los moeten doorgeven.

Het is altijd nuttig om iets verder te denken dan de huidige opdracht, en rekening te houden met toekomstige aanpassingen.

Kortom: voor de gegeven opdracht ben ik met je eens dat jouw code waarschijnlijk (bijna) optimaal is, maar ik vind het geen goed idee om mensen dit soort dingen aan te gaan leren, omdat het niet bruikbaar is voor grotere projecten.

Aangezien de delers constant zijn, kun je Horners methode met CSD toepassen, dan kost de deling je nog 21 cycles.

Efficiëntie gaat niet alleen om processortijd, of RAM, of code space; welke het belangrijkst is, is afhankelijk van de controller en welke resources schaars zijn. In mijn ervaring is code space meestal niet het probleem, en als het wel een probleem is, komt dat meestal door grote look-up tables.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Op 15 juli 2011 15:40:18 schreef PbSn:
Nou,

in C declareer je een variable v als bijvoorbeeld:

int v;

en in assembler als

code:


v    .equ $30   ; een of andere ram pos tussen $30 en $7F

...
Niks bijzonders dus. (die declaratie, ..dat wel)

WEL DUS:

Nou ik hoop niet dat je dat altijd in assembler zo doet, dit is gaat onherroepelijk een keer de mist in. Je moet nu zelf alle allocatie shit bijhouden.
'een of andere ram locatie' daar zit het geniep.

In het algemeen declareer de in assembly een variable in een datasegment en laat je de linker (slag) de fysieke allocatie doen.

Zoiets dus (effe voor een AVR):

code:


     .dseg           ; Start data segment
v:   .byte   1     ; Reserve 1 bytes for variable 'v'

... ETC.

Zoiets dus voor 8051:

code:


	.area	ISEG	(DATA)
v:	.ds	1
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
free_electron

Silicon Member

Op 15 juli 2011 19:09:00 schreef SparkyGSX:
@FE: toch ben ik het niet helemaal met je eens; het tellen van pulsjes doe je met een veel hogere frequentie dan het verzenden van de tijd. Toegegeven, aangezien de gewenste update frequentie hier 1Hz is, en je secondes telt, is jouw aanpak hier efficiënter (wat processortijd betreft). Als de gewenste resolutie (veel) groter wordt dan de update frequentie (dus de frequentie waarmee je de data naar buiten moet sturen), wordt het interessanter om de gewoon pulsjes te tellen, en het pas om te rekenen als je het gaat versturen.

jaaaa. maar dat is de opgave niet. de opgave is een clock met looplichtje. en zelfs als het modulair moet. Ik heb een inthandler die de 200us omzet naar een 1 seconde tick en dan een update van de timecounters doet. ( dus er is geen kans dat de werkelijk tijd verloren gaat. die update zit in de inthandler.
die zet dan een vlag.
in mijn main thread test ik die en clear ik die vlag. daar roep ik dan de dispatcher op die de string 1 keer buitenduwt.
ondertussen kan ik allerhande ander spul doen.
zelfs als ik daar even 'overloaded' ben , bijvoorbeeld 3 seconden iets anders doen. dan staat de uart even stil. de timecounters blijven draaien. Dus de data integriteit blijft gewaarborgd.
na 3 seconden gaat de uart dan wel de correcte tijd doorpleuren. de user kan wel effe wachten.

je moet een opgave ook kunnen partitioneren naar criticaliteit.

stel dat je een balvolg algoritme maakt. wat is er belnagrijkst ? de bal effectief volgen ? of het updaten van een flikkerledje..
als je balvolger crasht omdat het ledje even teveel resources vreet.

je moet prioriteit kunnen bepalen in een systeem.

in dit geval is het : reageren op een 200us interval en dit vertalen in correcte data.
met mijn aanpak is dat gewaarborgd.

de 'visualisatie' zit in een andere, low priority thread. als die even stilvalt. 'who cares'... dat is alleen 'eye candy'.

zul je een mirror van die data moeten maken. Dat is een stuk eenvoudiger als het een grote integer is, dan met 6 losse variabelen.

neen. niks mirror. Een van de fundamentel princiepes van embedded programmeren is dat data NOOIT gedupliceerd wordt. er mag en kan slechts 1 plaats zijn waar de data bestaat. alles moet tegen die plaats werken. Anders krijg je problemen met synchronisatie en outdated info.

vandaar : in mijn inthandler doe ik de update van de 6 bytes.
voor een extern process is dat dus een atomair gebeuren. de integriteit van de echte tijd is gewaarborgd.

Het kan nu natuurlijk zijn dat er een time update geweest is in het midden van een transfer.
daar kan je tegen testen. kwestie van voor elke volgend karakter die 'tick' vlag te bekijken. als die aan is : er is ondertussen een update geweest.
dat ondervang je dan door een 'linefeed' te sturen en je uart handler opnieuw te starten.

in dat geval is het wenselijker om dei uart handler als een routine te maken. je kan dat ook weer gaan aanpakken.
je maakt een lus die een vanaf een pointer een vast aantal bytes naar buiten jast.

je alloceert die 6 teller zo dat ze in volgorde staan. ( en je gooit er de twee ':' tussen. zo heb je dan 8 bytes nodig in ram. je kan dan die : ook nog laten knipperen als je wilt... )
dan passeer je een pointer naar de root. en nu call je die uart handler.

code:


sub sendtime(pointer to base)
for x = pointer to pointer +8
scon = karakter(x)
if tick then 
   x=xpointer   ' reset x. we hebben een tussentijdse update gehad
   send linefeed
end
wacht op TI
next
exit

om mensen dit soort dingen aan te gaan leren, omdat het niet bruikbaar is voor grotere projecten.

dat is het probleem net. ze gaan alles behandelen als 'grote projecten' en dan krijg je draken van systemen.

Ik heb een ouwe dvd speler ( generatie 1 ) dat ding gaat van disc spinup naar eerste beeld in onder de 3 seconden...
Je moet dat eens proberen met een blu-ray player waar je een dvd schijfje in smijt. dat duurt verdorie dik een minuut !. daar sta je dan met je quadcore mips , cryptoacceleerators en weetikveel wat nog.
die ouwe speler doet dat met een paar 100 k code aan 33 MHz.. die nieuwe zijn quadcores aan 1GHz..

Allemaal de schuld van shitprogrammeurs die alles 'modulair' doen. ze hebben totaal geen binding meer met de machiene. en dat is compleet verkeerd.

We pakken wat code die we vinden op het internet (liefst in een hogere programmeertaal waar we totaal geen binding meer hebben met de onderpinnende hardware) , we snokken dat door de compiler en gaan ondertussen koffie slurpen. als het niet werkt dan vragen we meer horsepower .. FOUT !

In mijn ervaring is code space meestal niet het probleem, en als het wel een probleem is, komt dat meestal door grote look-up tables.

de opgave is een 8051... je hebt 4 k rom en 128 byte ram...
moest het aan mij liggen mogen ze er nog 7 segment displays bij in rammen met pwm dimming die ze software matig mogen uitscannen , alarm functie en temperatuuraanduiding. en de temperatuur wordt gemeten ZONDER A/D. je moet maar een temperatuurgevoelige oscillator maken en die timen met de derde timer.

( zovele extra werk is dat niet. 7 segment displays scannen kost je hoop en al 50 instructies. pwm dimming is kwestie van je scanloop aan te passen door blanking in te stellen. )
iemand die een beetje kan programmeren krijgt dat ganse spul in minder dan 1k gestampt.

Nu . ik kijk daar waarschijnlijk anders tegen aan. Ik ben namelijk haast altijd met dat low level spul bezig. ( dei disk draait en wacht niet. mis je de servowedge dan kan je een volledige toer wachten , en dat is een eeuwigheid in disk termen.... )

als ik visualisatie programmatjes op pc maak : doe me maar visual basic hoor. minst werk , rap klaar. tis toch maar eye candy.
Maar voor embedded werk mag er best wat tijd gespendeerd worden aan optimalisatie.

Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
Henry S.

Moderator

Op 15 juli 2011 13:44:52 schreef Davidof:
Ik weet het ik was zelf nog bezig met alles neer te zetten wat ik al had

Right... De volgende keer weer een volledige startpost waar uit blijkt dat je wel inzet toont?

En lees vanwege je beroerde postgedrag de hele FAQ eens goed door.

Op 15 juli 2011 15:03:58 schreef PbSn:
Jei ken van Old Shatterhand lere, dat je beter je eige probleme ken oplosse door na te denke dan door te gaan frage op foroms waarbei je ellef antwoorde kreig en der welligt een goeie bijsit maar je door gebrek an oefene met je eige greise selle niet deragter komt wat nouw de goeie is.

Hou eens op met die zeurposts van je...begint heel erg irritant te worden.

73's de PA2HS - ik ben een radiohead, De 2019 CO labvoeding.

Op 15 juli 2011 17:57:35 schreef free_electron:
we gaan eens commentarieren.

code:



MOV TMOD,#00100010b     ; timer0 en 1 in 8-bit auto-reload timer
        MOV TH0,#37             /zever. je staat in 8 bit mode. high speelt niet mee
        MOV TL0,#37             ; 200µs
        MOV TH1,#243            ; 4800 baud

ivm die "/zever. je staat in 8 bit mode"

de functie van de timer is toch dat je TL telkens geladen wordt met de waarde in TH? dus als TL zijn max bereikt begint iet terug vanaf 37 .. dit las ik toch in de tutorials

Mijn opdracht is bijna volledig, ik heb nog 1 probleem: Ik heb een register nodig dat 2 byte kan bijhouden (R4). Iemand een oplossing?

code:

         ORG 0h
         LJMP start
         ORG 30h
 start:  MOV SCON,#40h ; serieel kanaal in mode1 8-bit UART variabele baudrate
         MOV TMOD,#22h ; timer1 als 8-bit auto reload voor baudrate generator
         ORL PCON,#80h ; baudrate verdubbelaar activeren
         MOV TH1,#243 ; 4800 baud
         MOV TL1,#243
         SETB TR1 ; baudrategenerator starten
 
         MOV P0,#00000001b
         MOV R0,#0       ; register voor seconden
         MOV R1,#0       ; register voor minuten
         MOV R2,#0       ; register voor uren
 lus3:   MOV R4,#5000d     ; =5000 R4 houdt bij hoeveel keer de tijdroutine van 50ms reeds werd doorlopen
 KLOK:   CLR TR0
         CLR TF0         ; timer0 stoppen en vlag resetten
         MOV TH0,#37h
         MOV TL0,#37h    ; startwaarde voor 200µs
         SETB TR0        ; timer0 starten

          
         MOV A, R1
         ANL A, #00000001b
         JZ loopl
         JNZ loopr


 lus2:   JNB TF0,lus2    ; wachten tot vlag van timer0 omhoog gaat
         DJNZ R4,KLOK
         CALL aanpassen  ; seconde bijtellen op klok
         LJMP lus3       ; volgende seconde afpassen
 
 aanpassen:
         INC R0
         CJNE R0,#60d,tonen
         MOV R0,#0
         INC R1
         CJNE R1,#60d,tonen
         MOV R1,#0
         INC R2
         CJNE R2,#24,tonen
         MOV R2,#0
 tonen:  MOV P1,R0       ; seconden op poort0 tonen
         MOV P2,R1       ; minuten op poort1 tonen
         MOV P3,R2       ; uren op poort2 tonen
         
         RET

loopr:   MOV A,P0
         RR A
         MOV P0,A
         CALL lus2
loopl:   MOV A,P0
         RL A
         MOV P0,A
         CALL lus2

Ik heb ook deze opdracht, maar bij mij gaan de lichten altijd naar rechts. Ongeacht bij even en oneven minuten

En hoe kan je je uren, minuten en seconden simuleren op die programma? doe je dat met een LCD-display en welke instellingen?

Hoe heb jij die kunnen oplossen Davidof?

[Bericht gewijzigd door S-man op maandag 15 augustus 2016 17:09:03 (31%)

Ik denk dat Davidof die code na 5 jaar ook niet meer echt paraat heeft.

Heb je zelf nog wat aan de opdracht gedaan, of simpelweg de code van Davidof over zitten tikken? Onderstaand deel bepaalt welke kant er op gescrolld wordt:
[code=asm] MOV A, R1
ANL A, #00000001b
JZ loopl
JNZ loopr[/]
En verder...
OUDE KOE ALERT

If you want to succeed, double your failure rate.

Beste Jochem,dit is mijn code

ik heb juist een paar waarden veranderdt, het probleem is dat hij juist bij even en oneven minuten altijd naar rechts gaat

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 P0,#00000001b
        MOV R0,#0 ; register voor de seconden van de klok
        MOV R1,#0 ; register voor de minuten van de klok
        MOV R2,#0 ; register voor de uren van de klok
        
lus:   	MOV R4,#0 ; nog commentaar zetten

klok:   CLR TR0 ; de timer0 wordt eerst gewist voor de programma begint
        CLR TF0 ; wissen van de overflow vlag van timer0
        MOV TH0,#37h
        MOV TL0,#37h ; startwaarde voor 200µs
        SETB TR0 ; timer0 starten
        MOV A, R1 ; de informatie van R1 wordt uitgegeven aan de accumulator
        ANL A, #00000001b
        JZ links ; sprong naar links 
        JNZ rechts ; sprong naar rechts 

lus2:   JNB TF0,$ ; wachten tot vlag van timer0 omhoog gaat
        DJNZ R4,klok ; -1 bit als R4 is niet 0
        CALL optellen ; seconde bijtellen op klok
        LJMP lus ; volgende seconde afpassen
 
optellen:
        INC R0
        CJNE R0,#60d,weergave ; maximumwaarde = 60 seconden 
        MOV R0,#0
        INC R1 ; verhogen van de minuten
        CJNE R1,#60d,weergave ; maximumwaarde = 60 minuten
        MOV R1,#0
        INC R2 ; verhogen van de uren
        CJNE R2,#24,weergave ; maximumwaarde = 24 uren
        MOV R2,#0
weergave:  
	MOV P1,R0; seconden worden weergegeven op poort0
        MOV P2,R1; minuten worden weergegeven op poort1 
        MOV P3,R2; uren worden weergegeven op poort2 
         
        RET; terugkeren naar het programma

rechts: MOV A,P0 ; de informatie van poort0 wordt uitgegeven op de accumulator
        RR A ; rotate right accu, de looplicht gaat naar rechts bewegen
        MOV P0,A ; de informatie van de accumulator wordt uitgegeven op poort0
        CALL lus2 ; oproepen van lus2
links:  MOV A,P0 ; de informatie van poort0 wordt uitgegeven op de accumulator
        RL A ; rotate left accu, de looplicht gaat naar links bewegen
        MOV P0,A ; de informatie van de accumulator wordt uitgegeven op poort0
        CALL lus2 ; oproepen van lus2
	
        RET; terugkeren naar het programma
        END; einde van het progamma

[Bericht gewijzigd door GJ_ op dinsdag 16 augustus 2016 12:54:21 (0%)

Op 16 augustus 2016 12:12:24 schreef S-man:
Beste Jochem,dit is mijn code

Nou, zeg maar gerust dat dit de code van Davidof is waarin wat labels en commentaar veranderd zijn.

Maargoed... Begrijp je wel wat de code doet?

Ik schreef niet voor niets dat dit stukje bepaalt welke kant er op gescrolld wordt:

code:

        MOV A, R1 ; de informatie van R1 wordt uitgegeven aan de accumulator
        ANL A, #00000001b
        JZ links ; sprong naar links 
        JNZ rechts ; sprong naar rechts 

Jij zult toch echt zelf moeten debuggen.
Als je nu eerst eens probeert te achterhalen wat de waarde van de accumulator is na de ANL bewerking...

If you want to succeed, double your failure rate.

beste Jochem,

Heb geprobeerd, maar het lukt niet. Ik weet enkel als je JZ hebt, dat je een sprong kan maken als A=0 is en bij JNZ dat je sprong maakt als A niet gelijkt is aan nul.

Ik ben maar een beginneling, het is daarom dat ik om hulp vrij. Wil je mij a.u.b helpen met mijn opdracht?

En hoe kan je het simuleren op die programma? Ik kan enkel die led paneel simuleren.

Waar wordt na die JZ/JNZ naar toe gesprongen, en hoe kom je terug in de hoofdlus? Ik zie daar een stack overflow (zoek op: hoe ontstaat een stack overflow).

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com

Ik ben maar een beginneling, het is daarom dat ik om hulp vrij. Wil je mij a.u.b helpen met mijn opdracht?

Het is een school vraag, terecht dat Jochem meer inzet van je verwacht.

Je kan een prima gratis IDE met simulator d/l: http://www.moravia-microsystems.com/mcu-8051-ide/

Dit gaat je vrije tijd kosten idd, heb je daar geen zin in dan kun je beter een andere opleiding zoeken waar je met minimale inspanning een papiertje krijgt.

It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.

Ik heb al een MCU 8051 IDE programma op mijn laptop, het probleem is gewoon dat ik maar half snap hoe die programma werk.

Is het soms verkeer dat je om hulp vraagt als je het echt niet weet.

Op 16 augustus 2016 14:09:37 schreef Fuzzbass:
Waar wordt na die JZ/JNZ naar toe gesprongen, en hoe kom je terug in de hoofdlus? Ik zie daar een stack overflow (zoek op: hoe ontstaat een stack overflow).

Ik wilde hem eerlijk gezegd zelf even het normale debug-proces laten doorlopen. Als je zelf een programma hebt dat niet doet wat je wilt, en je aan de commando's al niet meteen zag dat je uit je stack gaat lopen dan ga je dus aan het debuggen.

Als meneer S-man dat doet, dan zou hij al kunnen beginnen met ons te vertellen dat de waarde van de minuten (R1, weergegeven op P2) al voor geen ene meter klopt. Ik dacht: ik laat hem eerst eens debuggen of die accumulator de verwachte waarde heeft, en daarna vraag ik door naar R1 die in die accumulator ging. Zo had hij er achter kunnen komen.

Op 16 augustus 2016 13:58:36 schreef S-man:
Ik ben maar een beginneling, het is daarom dat ik om hulp vrij. Wil je mij a.u.b helpen met mijn opdracht?

Ik was je aan het helpen. Alleen geef jij geen antwoord op m'n vraag.

Als jij een bepaalde opdracht krijgt omdat je een bepaalde opleiding doet, dan zul je daar toch wat van moeten begrijpen. Anders ben je ofwel te incapabel voor de opleiding in het algemeen (dan stop er maar mee), of je voert niet genoeg uit (theorielessen volgen, boeken lezen, praktijkoefeningen vanaf het simpelste begin ZELF maken). Dit zal vast niet je eerste oefening zijn. Je zult vast al eens een looplichtje hebben moeten maken of iets dergelijks. Dit soort oefeningen bouwt altijd op in moeilijkheidsgraad en als je je dan bij de simpelere oefeningen erdoor hebt gewurmd (zonder genoeg begrip van de materie) loop je uiteindelijk vast.

Wat je nu hebt gedaan is code van een ander kopiëren. En om eerlijk te zijn ben ik blij dat die code uit z'n stack loopt, anders had je helemaal nooit wat geleerd.

Op 16 augustus 2016 14:17:43 schreef S-man:
Ik heb al een MCU 8051 IDE programma op mijn laptop, het probleem is gewoon dat ik maar half snap hoe die programma werk.

http://www.edsim51.com/ is bij kans nog simpeler. Ik heb je programma daar net ingeplakt, en daar kun je prima alles in zien. Ik heb nog nooit met een 8051 of met die simulator gewerkt, het was plakken en 'run' klikken.

Is het soms verkeer dat je om hulp vraagt als je het echt niet weet.

Geen enkel probleem, maar uit niets blijkt je eigen inzet. Je hebt code van een ander gekopieerd die niet werkt. Je hebt nog niet eens gekeken of de minuten op P2 juist worden weergegeven, of wel?

If you want to succeed, double your failure rate.

Wat bedoelt je met die stack? Als ik het simuleer, kan ik enkel zien dat mijn lichten van die led paneel altijd naar rechts gaat bij even en oneven nummers. En als ik iets anders probeert, dan onderbreekt de simulatie van zelf.

En ik weet ook niet wat die instellingen zijn voor een LCD-paneel om het te simuleren.

Ik heb alle oefeningen herbekeken, mijn theorie erbij gehaald. maar ik kan het gewoon niet vinden.

[Bericht gewijzigd door S-man op dinsdag 16 augustus 2016 14:36:33 (12%)

LCD paneel?! Je stuurt toch nergens een LCD paneel??

P0 doet dat looplicht. Die gaat kennelijk alleen naar rechts, zo ver ben je al. Dat klopt niet. Maar nu..

- Wat is de output op P1, waar je de waarde van de seconden zou verwachten? Hoogt die netjes op?
- Wat is de output op P2, waar je de waarde van de minuten zou verwachten? Hoogt die netjes op na elke 60 seconden?

If you want to succeed, double your failure rate.

die output van de seconden gaan toch naar poort1 en de output van de minuten naar poort2.

de simulatie van die leds kan ik doen, maar met welk onderdeel kan ik zien dat de uren, minuten en seconden kan zien

GJ_

Moderator

Het is natuurlijk niet de bedoeling dat je eerst hier de code van een ander komt kopiëren en dan vragen of we even kunnen uitleggen waarom het niet werkt.

Zo leer je niks, en het is ook zeker niet de bedoeling van de sectie schoolvragen.

Probeer eerst wat harder, schrijf desnoods zelf een programma (dat was toch de opdracht?) en als je er dan nog niet uitkomt kom dan terug in een geheel nieuw topic helemaal voor jou alleen in plaats van in dit oude topic.

Dit topic is gesloten