Forum: Mikrocontroller und Digitale Elektronik PIC 18F4620 PWM ausschalten


von Daniel B. (bower1988)


Lesenswert?

Hallo,

ich habe vor ein paar Tagen angefangen mich in der µC Programmierung zu 
versuchen. Und jetzt habe ich ein Problem mit der PWM, genauer gesagt 
mit dem Ausschalten dieser.

Ich will mit dem PWM Ausagng einen LED-Strip dimmen, der in Abhängigkeit 
von der Umgebungshelligkeit automatisch angeschalten wird (genauer 
gesagt ist es einer dieser LED-Solarlampen blos in groß^^). Das 
anschalten und dimmen funktioniert auch problemlos blos mit dem 
ausschalten hapert es.

Folgendes Problem:
Es ist dunkel LED Strip und LED1 (Kontroll-led) geht an und ich kann 
dimmen.
Wenn ich jetzt in der höchsten Helligkeitsstufe bin und es "hell" wird 
bleibt der Stripe nach wie vor an aber die Kontroll-led geht aus. Wenn 
ich z.b. in der 50% Duty-Cycle Stufe bin kann es sein, dass der Stripe 
ausgeht wenns "hell" wird...es ist aber wahrscheinlicher, dass der 
Stripe auf 100% Helligkeit springt. Je kleiner der DC desto größer ist 
die Chance, dass der Stripe das macht was er soll. Die Kontroll-led 
reagiert aber immer richtig.

So wahrscheinlich blickt jetzt kein Mensch was ich eigentlich will aber 
ich versuchs trotzdem mal. :D

Hoffe ihr könnt mir helfen :)

P.S. Ich bin wie gesagt sehr frisch dabei und nehme viele Funktionen die 
ich nicht selbst geschrieben haben geschweige denn voll und ganz 
verstehe.  Falls ich hier also kompletten Mist mache..sorry :D

Edit: ich gehe vom PWM Ausgang direkt auf das Gate von einem IRFZ46N der 
mir 12V durchschaltet (vllt ist das ja von Bedeutung). Wenn ich die 
PWM:Init() auskommentiere funktioniert alles wies funktionieren 
soll..natürlich dann ohne Dimmmöglichkeit.
1
//=========================================================================
2
int dc = 1;      //duty_cicle für PWM
3
#include "picus_ge_00.h"
4
5
//=========================================================================
6
#include "helpers.c"
7
8
========================================================================
9
void main(void)
10
{
11
    unsigned char spannung;
12
    unsigned char licht;
13
    int x=1;    //Laufvariable Taster 1
14
    int y=1;      // Laufvariable Taster 2
15
    init();
16
    PWM_Init();
17
      
18
while(1)
19
  {
20
  licht = getRC();
21
  PWM_Frequenz((unsigned int)2000);
22
    spannung = getTemp();
23
    if (spannung >= 134)
24
      {        
25
        if (licht > 120)
26
          {
27
28
            PWM_ON ();
29
            Ton_Out = 1;
30
            LED1 = Ton_Out;  
31
                      
32
          }
33
      }
34
    if (licht < 90)
35
      {
36
37
        PWM_OFF  ();
38
        delay_ms (15);
39
        Ton_Out = 0;
40
        LED1 = Ton_Out;
41
      }
42
43
      
44
    if (spannung <= 130)
45
      {
46
47
        PWM_OFF  ();
48
        delay_ms (15);
49
        Ton_Out = 0;
50
        LED1 = Ton_Out;
51
      }
52
53
54
55
[...]
56
57
    if (Taster2==1) 
58
      {
59
          delay_ms (200);
60
          y++;    
61
      }      
62
63
64
  switch (y)    // Duty-Cycle switchen
65
    {
66
67
    case 1:    {
68
            dc=1;    //duty_cycle = 100%
69
            
70
            break;
71
          }      
72
          
73
    case 2:    {
74
            dc=2;    //duty_cycle = 50%
75
            
76
            break;
77
          }            
78
          
79
    case 3:    {  
80
            dc=5;    //duty_cycle = 20%
81
            
82
            break;
83
          }
84
      
85
    case 4:    {  
86
            dc=20;    //duty_cycle = 5%
87
            
88
            break;
89
          }
90
91
    default:   {
92
            dc=1;    //duty_cycle = 100%
93
            y=1;
94
            
95
            break;
96
          }                
97
}
98
  
99
} 
100
101
} //end main()


PWM config:
1
void PWM_Init(void)
2
{
3
  unsigned int Duty_Cycle = 0;
4
  // set PWM Period
5
  //PWM period = [(PR2) + 1] • 4 • TOSC• (TMR2 prescale value)
6
  //PWM frequency = 1/PWM period
7
  PR2 = 0;
8
  //set PWM duty cycle 
9
  Duty_Cycle = 0;
10
  CCPR2L = Duty_Cycle;
11
  //set Output Pin RB3 
12
  TRISBbits.TRISB3 = 0;
13
  //set Timer2 Prescaler = 16
14
  T2CONbits.T2CKPS0 = 1;
15
  T2CONbits.T2CKPS1 = 1;
16
  //Timer2 OFF
17
  T2CONbits.TMR2ON = 0;
18
  //set CCP2 for PWM operation
19
  CCP2CON = 0b00001100;
20
21
}
22
23
void PWM_ON(void)
24
{
25
  T2CONbits.TMR2ON = 1;  // Timer2 On
26
}
27
28
void PWM_OFF(void)
29
{
30
  T2CONbits.TMR2ON = 0;  // Timer2 Off
31
}
32
33
void PWM_Frequenz(unsigned int i)
34
{
35
  #define a (1/10000000)    //Periode quarz_Takt  
36
  PR2 = (unsigned char)((1/i)/(4*a*16))-1; //PR2 = [ PWM_Periode / (4 x Tocs(CPU Takt periode) x TM2PS) ] -1
37
  CCPR2L =  PR2/dc;    //CCPR2L=PR2/(1/PWM duty cycle)
38
}

von holger (Gast)


Lesenswert?

>  PR2 = (unsigned char)((1/i)/(4*a*16))-1;

Einfachmal alles einsetzen und zu Fuss in integer rechnen
wie der Compiler:

((0) / (0)) - 1

von Daniel B. (bower1988)


Lesenswert?

Hallo,

danke für deine Antwort. Jetzt ist mir auch klar, warum die PWM Frequenz 
nicht das ist was sie hätte sein sollen :D Habs geändert..der Fehler 
besteht aber weiterhin :(

von hans (Gast)


Lesenswert?

Du schaltest nur die Taktquelle vom Timer ab.
Dieser bleibt stehen und damit auch die Ausgabe
am Pin.
Also in PWM_Off deinen Pin gezielt auf aus bringen.

hans

von Daniel B. (bower1988)


Lesenswert?

Habs jetzt mal so
1
void PWM_OFF(void)
2
{
3
  T2CONbits.TMR2ON = 0;  // Timer2 Off
4
  Ton_Out=0;
5
}

geht aber immer noch nicht :/ Oder meinst du was anderes? Ich hab schon 
überlegt den Duty wenn der Stripe aus sein soll auf 0% zu stellen..aber 
das is ja auch irgendwie doof :D

von Klaus (Gast)


Lesenswert?

Daniel Bauer schrieb:
> Ich hab schon
> überlegt den Duty wenn der Stripe aus sein soll auf 0% zu stellen..aber
> das is ja auch irgendwie doof :D

Was ist daran "doof"? So stelle ich mir eigentlich eine PWM vor: 0% ganz 
aus, 100% ganz an, der Rest irgendwo dazwischen.

MfG Klaus

von hans (Gast)


Lesenswert?

Im CCP2CON legst du fest, dass das CCP/PWM-Modul den
Ausgang steuert.
Also must du dir diese Aufsicht zurückholen bevor
du was machen kannst.
Normalerweise reicht es, den Pin beim Konfigurieren
passend einzustellen und zum Ausschalten dann nur die
Aufsicht zu wechseln. Der Timer kann ruhig weiterlaufen.

hans

von Daniel B. (bower1988)


Lesenswert?

@hans

Wunderbar! Das wars :) Ich lass den Timer jetz immer rennen und leere 
einfach das CCP2CON wenn der Output auf Low soll.

Perfekt
Danke!:)

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.