Hallo beste mensen, mijn sterrenhemel project vordert nog steeds. Ik heb alles aangeschaft en ben nu aan het programmeren.

Ik wil een PWM-routine maken in ASM, basic gezien zou het zoiets moeten worden :


teller = 0
Zet led aan
while teller <= 255

if teller > dimwaarde then
Zet led uit
end if

teller = teller + 1
wend

Maar ik wilde het toch in ASM proberen omdat dat wat ruimte/snelheid bespaard. Ik heb alleen weinig idee hoe ik in ASM een tellertje maak. Iemand suggesties?

van belang is dat je aangeeft welk type µC je gebruikt...

Gezien de vorige post over de sterrenhemel, gok ik op een PIC.
Dus zoiets (cyclus en pwm zijn twee variabelen):


Loopje00:
	movlw	.200			; Loopje tot 200
	movwf	cyclus
	movlw	.100			; pwm tot 100, dus 50/50 verhouding
	movwf	pwm
	call	LedUit

Loopje10:
	decfsz	pwm,F			; 
	goto	Loopje20
	call	LedAan			; pwm = 0; dus LEDje aan
Loopje20:
	decfsz	cyclus,F
	goto	Loopje10
	; Einde cyclus. Start overnieuw
	goto	Loopje00

LedUit:
	; Doe LED uit stuff...
	return

LedAan:
	; Doe LED aan stuff...
	return	

Ik gebruik nu de PIC16F627A,

Maar die code ziet er inderdaad leuk uit, ik zal hem is bestuderen!

decfsz pwm,F

Dit betekend toch ; trek F van PWM af, en als PWM 0 is, dan sla je de volgende instructie over.

Maar wat is F? Moet daar niet 1 staan ofzo?

F is destination.

F = Result naar File Register
W = Result naar W register

Je kunt ook 0 of 1 gebruiken, maar vanwege de duidelijkheid kun je beter W/F gebruiken

Bijna goed: verlaag het register 'pwm' met 1, sla het resultaat terug op in ditzelfde register (de F achter de komma), en sla inderdaad de volgende instructie over als dit 0 (nul) oplevert.

De F en W zijn symbolische namen om het lezen te vergemakkelijken.
Dus je hebt gelijk: er mag ook 1 staan. Maar een F vind ik zelf duidelijker.
Overigens is hierover in de de datasheet veel info te vinden.

[edit]
sneller typen, net te laat :-)

Dat kan korter...


PWMloop 
 bsf LED ;led aan
loop
 movf PWM,w 
 subwf counter,w ;vergelijk met pwm waarde
 btfsc status,z ;gelijk?
 bcf LED        ;zet dan led uit 
 incfsz counter ;verhoog teller en ga door tot deze 
 goto loop      ;volgelopen is
 goto PWMloop   ;terug naar het begin

Dat kan korter...

Maar waar geef je dan de PWM-waarde aan?

in PWM;


PWMloop 
 bsf LED ;led aan
loop
 movf PWM,w       <------ de pwm waarde, deze gaat van 0 tot 255
 subwf counter,w ;vergelijk met pwm waarde
 btfsc status,z ;gelijk?
 bcf LED        ;zet dan led uit 
 incfsz counter ;verhoog teller en ga door tot deze 
 goto loop      ;volgelopen is
 goto PWMloop   ;terug naar het begin

Voor LED moet je een pin opgeven, bijvoorbeeld PORTA,1

Op 4 september 2007 19:40:01 schreef infrarood:
Dat kan korter...

Doet me denken aan die wedstrijdjes van het schrijven van één-regelige C-programma's.

ir laat hier perfect zien wat de kracht van PICs zijn, en waarom ik (nog steeds) vindt dat je die dingen niet in C moet programmeren. Al is dat persoonlijk ook.
Super simpel, met een minimum aantal instructies bereik je veel. Krachtige instructieset ook. Die decfsz/incfsz zijn erg mooi.

Nice :)

Maar wat betekend dat -status- commando eigelijk? Ik zie dat dat ook gebruikt wordt om een bank te kiezen:

; define your pin direction (1nput/0utput) 

38      BSF STATUS, RP0          ;Bank 1 
39      MOVLW B'11111111'    
40      MOVWF TRISA 
41      MOVLW B'00000000'    
42      MOVWF TRISB 
43      BCF STATUS, RP0           ;Bank 0 

En waarom precies moet je die bank heen en weer gooien om de poorten te benoemen tot in- output?

:) Vergeef mijn vele vragen, maar ik wil graag precies weten waar ik mee bezig ben en niet blind codes overnemen.

Sommige registers zitten in de ene bank, en andere weer in een andere. Voordat je zo'n register aanspreekt, moet je dus eerst de juiste bank setten.
Voor dit soort dingen moet je dus de datasheet lezen. En de instructieset ook (die moet je uit het hoofd leren :) )

Heb je het datasheet al eens goed doorgenomen van de toegepaste PIC?
Heb het idee van niet, want de vragen die je stelt staan keurig netjes in het datasheet uitgewerkt voor wat en wie is.

Daarom ben ik ook een groot voorstander van proggen in ASM, niet altijd even eenvoudig, maar als je er eenmaal los in bent dan heeft het echt voordelen.

Flip je was me voor ;-)

En vergeet niet dat de 16F627A hardware PWM heeft. Dat staat stap voor stap in de datasheet uitgelegd.

Ik zal die datasheet is beter bekijken dan :) Maar die PWM die er op zit kan denk geen 14 LEDs ofzo aansturen neem ik aan?

Wil je nauwkeurige PWM met meerdere kanalen, zul je denk ik al gauw richting het gebruik van interrupts gaan.

en wat zijn interrupts?

Stel je bent aan het werk en de telefoon gaat... da's een interrupt :-p

Nee serieus: in de datasheet staat hier ook weer het nodige over uitgelegd (bijv de TMR0 interrupt).

In het kort komt het erop neer dat de PIC periodiek (of ad hoc, afhankelijk van het soort interrupt) even het lopende programma onderbreekt om 'even iets anders te doen': de interrupt afhandelen.
Je kunt de PIC zo instellen dat 'ie nauwkeurig om de zoveel us of ms 'iets' moet gaan doen.
En dat iets kan bijvoorbeeld de afhandeling van je PWM zijn.

mag ik er even tussen komen
vind niet echt de moeite voor nieuwe topic

ik ben nu dmx aan het ontvangen maar dit is me nog onduidelijk

ontvangt de pic zelf de byts met data
of moet ik deze ergens synchronizeren
voor dat de uart weet dat die dit moet binne halen

dus eigenlijk ontvangt hij altijd de juiste byte
en niet in de helft van een byte en het ander kanaal

Ok das duidelijk.

Hoe zit het btw met het RETURN command van een CALL subroutine.

onthoud ie waar de CALL vandaan komt en gaat ie dan pas terug waar CALL stond, wanneer er een RETURN gegeven wordt?

Dus ook als het een routine verder is?


		BTFSC SWITCH1				;Alleen naar lager dimlevel als
		GOTO dimmer8				;SWITCH1 ingedrukt wordt
		BTFSC SWITCH2				;Alleen naar lager dimlevel als
		GOTO main					;SWITCH2 ingedrukt wordt
		
		MOVLW .200
		MOVWF teller
		MOVLW .180
		MOVWF pwm
		CALL uit
		CALL pwm_duty
		GOTO dimmer9a				;repeat
		

pwm_duty_off
		DECFSZ pwm,F
		goto pwm_duty_on
		CALL aan
pwm_duty_on
		DECFSZ teller,F
		goto pwm_duty_off
		RETURN

Op deze manier..

Op 6 september 2007 19:00:14 schreef Dickoso: onthoud ie waar de CALL vandaan komt en gaat ie dan pas terug waar CALL stond, wanneer er een RETURN gegeven wordt?

Dat klopt.
Houd er rekening mee dat je maximaal 8 niveaus kunt nesten.

dus je zou zo kunnen doen:

----------
Call Sub1

Sub1
Call Sub2
RETURN

Sub2
Call Sub3
RETURN
------------

Dan gaat ie ze alle drie langs, tot aan Sub8?