Forum: Mikrocontroller und Digitale Elektronik PIC18F45K22 Software PWM


von Daniel B. (daniel_bach)


Lesenswert?

Hallo zusammen,

ich möchte mit dem o.g. PIC viele LED´s ansteuern. Diese sollen Faden 
und in verschiedenen Helligkeiten leuchten können.
Da es ca. 14 LED´s sind, fällt PWM mit CCP aus und es muss mit Software 
PWM implementiert werden.

Der PIC läuft mit intern 16MHz, Timer 1 wird schon zur dekodierung einer 
kleinen Fernbedienung verwendet.
Ich habe schon viel durchsucht, leider sind einfache Beispiele oft in 
asm ( ich arbeite mit c) oder für den avr.

Wäre jemand so nett und könnte mir einen Denkanstoß geben?
Was klar ist: Ich muss einen Timer einstellen und zwar so das für z.B. 
200 Hz alle 5ms ein Überlauf des Timers stattfindet.

von Teo D. (teoderix)


Lesenswert?


von Volker S. (vloki)


Lesenswert?

Daniel B. schrieb:
> Was klar ist: Ich muss einen Timer einstellen und zwar so das für z.B.
> 200 Hz alle 5ms ein Überlauf des Timers stattfindet.

Warum ist das klar? Ich denke das ist viel zu langsam ;-)
Bei einer Software PWM zählt man die Überläufe dieses Timers und 
schaltet nach bestimmten erreichten Werten die LEDs ein oder aus.

Wenn man so eine einigermaßen vernünftige Auflösung erreichen will, 
müssen die einzelnen Schritte viel kürzer sein als 5ms. Dazu kommt noch, 
dass der Helligkeitseindruck nicht linear mit der Zeit zunimmt.

Vor nicht allzu langer Zeit wollte ich mal etwas ähnliches 
programmieren, wobei die Steuerung für die LEDs in einem Array von 
Steuerworten abgelegt war.
Am Anfang wird das Steuerwort[0] an den Ports ausgegeben, welche die 
LEDs ansteuern. Nach dem ersten Durchlauf des Timers das Steuerwort[1] 
und die Zeit  des Timers wird verdoppelt. So geht das dann weiter, bis 
zur Anzahl der gewünschten Helligkeitsstufen.

Bin mir jetzt leider nicht sicher, wie weit das damals gediehen war. Ich 
schau mal ob ich noch was davon finde...

<edit> das Faden würde dann durch Manipulation des Steuerwortarrays in 
einem weiteren, langsameren Timerinterrupt geschehen.</edit>

: Bearbeitet durch User
von Daniel B. (daniel_bach)


Lesenswert?

okay, also Timer schneller laufen lassen und die Überläufe des Timers 
zählen.

Angenommen ich möchte eine oder mehrere LEDs faden, sprich blinken 
lassen (z.B. um den Warnblinker eines Fahrzeuges.

--> Timer3 initialisieren
--> Timer3 einschalten
--> jeden Überlauf zählen -> if(PIR2bits.TMR3IF) var++;
--> danach Test, ob var größer als bestimmter wert
--> Test erfolgreich PIN an, Test n.i.o. PIN aus und var auf 0 setzen

ich würde es gern erstmal für eine led hin bekommen und dann schaeu ich 
weiter.

Das Tutorial hier hab ich mir natürlich angeschaut, auch wenn das 
prinzip immer gleich ist kann ich es iwie nicht auf den pic anwenden

von Maik W. (werner01)


Lesenswert?

8bit auflösung = 256 * Herzzahl 100 Hz sollte reichen = 25600 
Überläufe/s.
Betreibe den Controller mit maximalen Takt. Soft.-PWM ist so ne Sache...

Grüße

von Volker S. (vloki)


Lesenswert?

Daniel B. schrieb:
> --> danach Test, ob var größer als bestimmter wert
> --> Test erfolgreich PIN an, Test n.i.o. PIN aus und var auf 0 setzen

Wenn var = 0 dann LED an. Wenn var = bestimmter Wert dann LED aus.

Schau mal da: 
http://www.hs-ulm.de/users/vschilli/Mikrocontroller/uCQ/_downloads/uCquick-X_20180413.pdf

 7.1 LED - Ein/Aus oder doch unterschiedlich hell?
 7.3 Mehrere PWM Signale über einen Timer (special Event)

Die oben angedeutete Geschichte mit dem Steuerwortarray ist da leider 
nicht drin :-(

von Daniel B. (daniel_bach)


Lesenswert?

Hallo, eine LED mit pwm zu betreiben funktioniert soweit, und zwar mit 
Timer Interrupt und dem Timer 0. Der Chip läuft mit 16 MHz, der Timer 
ist so eingestellt dass alle 30 µs ein Überlauf und somit ein 
Timer-Interrupt ausgelöst wird. In der ISR wird nun eine Variable 
hochgezählt(time), und mit einem voreingestellten Wert pwm_val 
verglichen. Ist der Zählerwert kleiner als der PWM-Wert (time<pwm_val) 
wird der Pin an dem die LEd angeschlossen isr auf 1 gestellt, ansosnten 
0. Somit kann ich mit unterschiedlichen Werten von pwm_val die 
Helligkeit der LED einstellen.

Nun zu meinem Anliegen: wie kann ich damit ein sanftes ein/aus faden 
machen? Es soll damit einmal ein Blinken mit ein/ausfaden von 4 LEDs 
verwirklicht werden.
Ansatz: Ich würde einen 2. Timer nehmen (ca. alle 50ms ein Interrupt, 
und da bei jedem Interrupt die Variable pwm_val ändern welche wiederum 
die Helligkeit der LED beeinflusst.

Ich würde gerne das hier auf der Seite gezeigte Verfahren mit Soft-PWM 
benutzen, leider bekomme ich es einfach nicht hin das für den Atmega32 
gedachte Beispiel auf meine PIC18F45K22 umzumünzen.

Init:
1
  
2
  /* Timer 0 */
3
  T0CON  = 0x88;
4
  TMR0H = 0xFF;
5
  TMR0L = 0x88;
6
  INTCONbits.GIE = 1;
7
  T0CONbits.TMR0ON = 1;

PWM Funktion:
1
U16_T time = 0;
2
const U8_T pwm_val = 1;
3
 /*************************** main function *********************/
4
void main(void)
5
{
6
  Pmd_Init();
7
  Ports_Init();
8
  Config_Init();
9
  Timer_Init();
10
  Irq_Init();
11
 
12
  __delay_ms(1000);   // wait 1 second
13
 
14
    while(1)
15
    {
16
        if (INTCONbits.T0IF)
17
        { 
18
            INTCONbits.T0IF = 0;
19
            TMR0H   = 0xFF;
20
            TMR0L   = 0x88;
21
            
22
            time++;
23
            
24
            if (time>20) 
25
            {
26
                time=0;
27
            }
28
29
            if (time<pwm_val)
30
            {
31
                 LATCbits.LATC7 = 1;
32
            }
33
            else
34
            {
35
                 LATCbits.LATC7 = 0;
36
            }
37
        }
38
    
39
 
40
    }
41
}
42
/*************************** end main function ********************************/

von Volker S. (vloki)


Lesenswert?

Daniel B. schrieb:
> Ich würde gerne das hier auf der Seite gezeigte Verfahren mit Soft-PWM
> benutzen...

Link?

von Daniel Bach (Gast)


Lesenswert?

Das hier von mikrocontroller.net

https://www.mikrocontroller.net/articles/Soft-PWM

von Volker S. (vloki)


Lesenswert?

Wo da genau?

1. Timer 0 mit manuellem Reaload scheint mir die umständlichste aller 
Möglichkeiten zu sein.

2. Warum die LED wiederholt ein- bzw. aus-schalten?
Einmal ein bei time == 0 und einmal aus bei time == pwm_val reicht doch.

3. Zum Faden einfach eine zweite Variable (fade_time) mitlaufen lassen, 
welche die Perioden zählt und nach einer gewissen Anzahl die erste 
Variable pwm_val inkrementiert oder dekrementiert?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.