Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Fading van meerdere leds via PWM

Pagina: 1
Acties:
  • 153 views sinds 30-01-2008
  • Reageer

  • Termike
  • Registratie: Juni 2005
  • Laatst online: 21-10 14:23
Hoe zou je het beste met een 16F628A die één pwm kanaal heeft verschillende leds kunnen doen faden? Daarmee bedoel ik dat je je bv 1 led laat infaden, dan de volgende dan de volgende enzovoort en dan in de omgekeerde volgorde alles doet uitfaden. Of door verschillende leds een bepaalde intensiteit geven. Die led brand zo sterk, de andere iets minder en nog een andere iets harder enzovoort. Ik kan me voorstellen dat er toch achterdeurtjes moeten zijn om het probleem van slechts 1pwm kanaal op te lossen. Want nog iets dat ik niet volledig snap is dat die pwm kan lopen tegelijk met een programma. Dus dat je programma iets anders kan doen maar hoe zorg je er dan voor dat de duty cycle toeneemt of afneemt terwijl je programma andere zaken aan het doen is? Moet je dat gewoon inplannen in je programma dan?

Alvast bedankt voor jullie meningen!
Groeten
Robin

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Je kan PWM in software implementeren: laat een timer op, zeg, 200KHz lopen en interrupts afgeven. Je kan dan je PWM-logica in die interrupt gooien en je programma zelf gewoon schrijven alsof de PWM-afhandel-routine niet bestaat.

Ik heb je topic trouwens een iets nettere titel gegeven.

[ Voor 11% gewijzigd door Sprite_tm op 15-11-2006 13:45 ]

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Termike
  • Registratie: Juni 2005
  • Laatst online: 21-10 14:23
Zover ben ik nog niet. Hiermee ben ik begonnen met PWM omdat ik dat wou. Ik weet wel wat interrupts zijn maar de praktische uitvoering zal je iets nader moeten toelichten als je het niet erg vindt?

Alvast bedankt
Groeten
Robin

  • DuDePrOdUcTiOnS
  • Registratie: Augustus 2001
  • Laatst online: 31-10 13:18
Ik zou zeggen ga eens op zoek naar wat programmeer tutorials en pluis de datasheet eens door. :) Zo moeilijk is het allemaal niet maar je moet het gewoon allemaal eens gedaan hebben. En van zelf proberen leer je toch het meest, tenminste zo werkt het bij mij wel.
Succes!

www.teamgenie.nl
You raise the blade, you make the change
You re-arrange me till I'm sane
You lock the door, and throw away the key
There's someone in my head but it's not me


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Pseudo-code, voor 2 pwm-kanalen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SetupTimerInterrupt;
pwmr1=128; //50% aan
pwmr2=255; //100% aan

DoeInteressanteDingenMetPwmr2EnPwmr2;


TimerInterrupt {
 counter++;
 if (counter==0) { //overflow
   SetPinA;
   SetPinB;
   RealPwmr1=pwmr1;
   RealPwmr2=pwmr2;
 }
 if (counter==RealPwmr1) ResetPinA;
 if (counter==RealPwmr2) ResetPinB;
}

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Thijsch
  • Registratie: Februari 2002
  • Laatst online: 19-11 10:47
Ik heb dit precies gebouwd zoals je wilt.. 3 pwm kanalen in software. Ik zal de code even opzoeken!

Dit is de code. Het kan het volgende:

-3 pwm kanalen (voor RGB led)
-4 input knoppen voor faden of vaste kleur.

klik

Als je puur het faden wil hebben heb je alleen deze stukken nodig:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
'Als je de timer steeds laat tellen tot zijn maximale waarde, 
'is de pwm frequentie veel te laag
'Daarom laat de de timer beginnen vanaf een bepaalde waarde, 
'aangezien het een 16 bits timer is
'moeten er 2 prescalers worden weggeschreven


#DEFINE     PRESCALER               0xFF
#DEFINE     PRESCALER2              0xE9
'De code begint altijd hier
ORG       00h
GOTO      INIT



'Iedere keer als er een interrupt komt springt de code naar adres 0x4.
'Dat is een feit, kan je niet instellen oid, dat doet de PIC automagisch

ORG     04h     
        'aangezien een interrupt op ieder moment in het programma kan komen
'kan het zien dat op dat moment het W register in gebruik is,
'en W wordt in de interruptlus ook gebruikt, als de interrupt dan klaar is
'heeft W een andere waarde en zal de uitkomst van de berekening
'in de onderbroken code dus verkeerd zijn.
'om dat op te lossen worden W, STATUS en PCLATH tijdelijk weggeschreven
    MOVWF   W_SAVE          
    MOVF    STATUS,W    
    MOVWF   S_SAVE
    MOVF    PCLATH,W
    MOVWF   P_SAVE  

    GOTO    INT_HANDLER

'Initializatiefunctie
INIT
'spring naar bank1 om de i/o registers goed te zetten
      BSF   STATUS,RP0
      CLRF   TRISA
      BCF   STATUS,RP0

'Initialiseer nu de timer
TIMER_INIT
'Schrijf de offsets weg
    MOVLW   PRESCALER
    MOVWF   TMR1H

    MOVLW   PRESCALER2
    MOVWF   TMR1L

'Timer1 heeft ook nog een eigen prescaler die hem langzamer maakt, 
'de onderstaande 2 regels zetten die uit

    BCF     T1CON,T1CKPS0   ;clear prescaler
    BCF     T1CON,T1CKPS1

'Zet de oscillator modus uit, en set de timer modus.
'Als laatste: zet de timer aan.
    BCF     T1CON,T1OSCEN   ;disable oscilator
    BCF     T1CON,TMR1CS    ;select timer mode
    BSF     T1CON,TMR1ON    ;enable timer 1


'Zet nu de interrupts aan

INTERRUPT_INIT

'Selecteer BANK1, en clear de interrupt registers voor de zekerheid
'Zodoende weet je zeker dat er niet per ongelijk een andere interrupt aanstaat

    BSF     STATUS,RP0
    CLRF    PIE1
    CLRF    INTCON

'Set TMR1IE  ( TIMER1 INTERRUPT ENABLE), zodat er een interrupt komt
'Als timer1 een overlfow geeft.
'Zet daarna GIE (General interrupt enable), en PEIE (perhipel interrupt enable) aan

    BSF     PIE1,TMR1IE     ;enable timer interrupt
    BSF     INTCON,GIE
    BSF     INTCON,PEIE
    BCF     STATUS,RP0


'De main lus, hier kan je je normale code infietsen


ENDLESS
        NOP
        NOP
    GOTO    ENDLESS





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;          INTERRUPT CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


'Deze functie wordt aangeroepen als de interrupt klaar is,
'De timer wordt gereset, W, STATUS en PCLATH teruggezet
'En de interrupt wordt verlaten
RET 

'Timer1 flag clearen, en de prescaler weer schrijven
    BCF     PIR1, TMR1IF
    MOVLW   PRESCALER
    MOVWF   TMR1H

    MOVLW   PRESCALER2
    MOVWF   TMR1L


'Schrijf de registers weer terug, zodat de normale lus verder kan gaan

                        ;Called on normal interrupt return  
    MOVF    P_SAVE,W        ;restore context
    MOVWF   PCLATH
    MOVF    S_SAVE,W
    MOVWF   STATUS
    SWAPF   W_SAVE,F
    SWAPF   W_SAVE,W

'en RETFIE (Return From Interrupt)
                
    RETFIE                  ;and return from interrupt




'Deze functie wordt geroepen als er een interrupt is.


INT_HANDLER

'Vooor de zekerheid controleren of het wel écht timer1 is die een interrupt geeft

    BTFSC   PIR1,TMR1IF
    GOTO    INT_TIMER

'Zo niet stop ermeer
    GOTO    RET


'De timer code zelf

INT_TIMER

'Iedere ronde wordt PWMCOUNTER één verlaagd, zodra die nul is,
'Worden alle LED's uitgezet en begint de PWM cyclus opnieuw


    DECF    PWMCOUNTER      ;decrease
    BTFSC   STATUS,Z
    CLRF     PORTA

'Als PWMCOUNTER gelijk is aan GREEN, zet dan de groene LED aan

    MOVF    PWMCOUNTER,W    
    XORWF   GREEN,W         
    BTFSC   STATUS,Z
    BSF     PORTA,2     

'Als PWMCOUNTER gelijk is aan BLUE, zet dan de blauwe LED aan


    MOVF    PWMCOUNTER,W    
    XORWF   BLUE,W          
    BTFSC   STATUS,Z
    BSF     PORTA,1         

'Als PWMCOUNTER gelijk is aan RED, zet dan de rode LED aan

    MOVF    PWMCOUNTER,W
    XORWF   RED,W
    BTFSC   STATUS,Z
    BSF     PORTA,3

'En er is weer één stap voltooid (een PWM cyclus bestaat uit 256 stappen)
'Zodoende: hou er mee op

    GOTO    RET

'Deze END wordt nooit bereikt door de code, maar als je die niet neerzet,
'dan gaat MPLAB raar doen.

END


De oplettende lezer zal opmerken dat ik hier timer1 heb gebruikt waar ik ook de 8 bits timer0 kon gebruiken... waarom ik dit heb? geen idee...


Dit fade dus 3 kanalen en is simpel uit te breiden..

roep het maar als je uitleg wilt.

[ Voor 133% gewijzigd door Thijsch op 15-11-2006 20:24 ]


  • Termike
  • Registratie: Juni 2005
  • Laatst online: 21-10 14:23
Wat uitleg zou mooi zijn. Ben eigelijk begonnen met programmeren in proton ide omdat dit in de basic taal is en vrij eenvoudig is zo.
In assembler ben ik nog niet begonnen te programmeren dus wat uitleg zou mooi zijn. Ik ken wel iets van assembler dus de uitleg hoeft niet te gedetaileerd te zijn.

Alvast bedankt!!
mvg
Robin

  • Thijsch
  • Registratie: Februari 2002
  • Laatst online: 19-11 10:47
Ik heb mijn bovenstaande bericht aangepast met uitgebreid commentaar. Als je vragen hebt hoor ik het wel...

  • naftebakje
  • Registratie: Februari 2002
  • Laatst online: 08:44
Ik heb een tijdje geleden een heel topic volgezet met uitleg over PWM genereren met interrupts in ASM, ik ga niet alles opnieuw intikken, lees het topic eens door en stel dan je vragen.
Voor Basic komt het trouwens op hetzelfde neer, je kan het alleen vaak wat gemakkelijker schrijven (niet meer rommelen met BTFSC/BTFSS, maar gewoon if..then..else).

Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.


  • Termike
  • Registratie: Juni 2005
  • Laatst online: 21-10 14:23
Weet je wat ik me nu afvraag na wat verder te liggen 'spelen' met die pic. Hij krijgt 5V op zijn voedingsklemmen. Maar als ik een uitgang constant hoog maak geeft hij maar 3,8V op zijn uitgangen. Hoe komt dit?

device 16F628A
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE
porta = %11111111
portB = %11111111
trisA = %00000000
trisB = %00000000


while 1 = 1
delayms 5000
wend
end

  • naftebakje
  • Registratie: Februari 2002
  • Laatst online: 08:44
Je doet iets verkeerd als je maar 3.8V krijgt, controleer volgende zaken:
- voeding is netjes 5V, met ontstoringscondensator (100nF) vlakbij de PIC
- reset is niet rechtstreeks aangesloten, maar via een 10KOhm weerstand (waarde steekt niet zo nauw)
- hoeveel stroom trek je uit de uitgangen van de PIC? Maximaal kan je er 20mA uit trekken, maar het totaal van stroom die door alle uitgangen gaat is ook beperkt, ik gok erop dat hier de fout zit bij jou.

Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.


  • Termike
  • Registratie: Juni 2005
  • Laatst online: 21-10 14:23
Dat kan niet het probleem zijn. De uitgangsspanning heb ik gemeten zonder belasting en met belasting. Allebei dezelfde voedingsspanning. Ze stijgt gewoon niet naar 5V. Ook die 100nF en ook nog een 47µF zijn aanwezig om de zaak te doen ontstooren. En als ik de led erop aansloot bleef de spanning dus constant en dan was er trouwens een led(3,8V ~ 20mA) en een weerstand in serie van 60 ohm. dus dat kan het probleem toch niet zijn?
Pagina: 1