Forum: Mikrocontroller und Digitale Elektronik PIC24 PWM Erzeugen


von C_Programm (Gast)


Lesenswert?

Hi ich verwende gerade einen PIC24 aus der PIC24FJ256GB110 Famalie!!!
Durch verstellen von dem OC1RS Register müsste sich am Ausgang doch was 
machen!!! Aber es Passiert nichts!
Könnt ihr mir bitte weiterhelfen!
1
  void InitializeTimer2For_PWM(void)
2
{
3
    T2CONbits.TON = 0;      /*  Timer2 is used for generating PWM frequency */
4
    T2CONbits.TCS = 0;
5
    T2CONbits.TGATE = 0;
6
    T2CONbits.TCKPS = 0b00;
7
    TMR2 = 0x00;
8
    PR2 = 0x7FFF;           // FOR 488 Hz
9
    T2CONbits.TON = 1;      // TIMER 2 ON
10
11
}
12
13
void Initialize_PWM(void)
14
{
15
    #define OC1_IO    18
16
17
    __builtin_write_OSCCONL(OSCCON & 0xBF);
18
19
    RPOR7bits.RP15R   = OC1_IO;  // RP15
20
21
    __builtin_write_OSCCONL(OSCCON | 0x40);
22
23
    OC1CON1bits.OCM = 0b000; /*  clearing OCM bits   */
24
    OC1R = 0x0F;
25
    OC1RS = 0x0F;           /*  starting module with min PWM    */
26
    OC1CON1bits.OCTSEL = 0;
27
    OC1R = 0x0F;
28
    OC1CON1bits.OCM = 0b110;
29
30
}

MFG

von Frank M. (frank_m35)


Lesenswert?

Sorry, ich habe keine Zeit deinen Code genau anzuschauen, daher gebe ich 
dir mal ein Beispielcode von mir, mit dem es bei mir funktioniert. 
Theoretisch sollte die LED gedimmt blinken:
(er ist zusammengestückelt aus einem Projekt, ich hoffe ich habe nichts 
vergessen oder falsch zusammengesetzt)

Vielleicht siehst du damit auch selbst, was bei deinem Code anders, bzw. 
falsch ist.

Falls es nicht klappt, versuche mal die Pin Umlegung ganz am Anfang des 
Codes zu machen, bzw. das Flag IOL1WAY_OFF zu setzen, um mehrmals die 
Pinbelegung ändern zu dürfen, sofern du es benötigst.
1
int SineTable[] __attribute__((far));
2
3
void blub ( void ) {
4
5
// init the timebase
6
T2CON = 0x0020;    // configure TMR2, prescale 1:64, internal clock
7
PR2 = 400;         // set the period for the given bitrate
8
IEC0bits.T2IE = 0; // disable TMR2 interrupt
9
10
// set the initial duty cycles
11
OC3R = 200;
12
OC3RS = 399;
13
14
// disable the PWM module
15
OC3CON1 = 0x0;
16
17
// set PWM Module part 1 of 2
18
OC3CON2 = 0x000C;
19
20
// switch the PWM module
21
__builtin_write_OSCCONL(OSCCON & 0xBF);
22
RPOR11bits.RP23R  = 20;
23
__builtin_write_OSCCONL(OSCCON | 0x40);
24
25
// enable TMR2
26
T2CONbits.TON = 1;              // enable TMR2
27
IFS0bits.T2IF = 0;              // clear interrupt flag
28
IEC0bits.T2IE = 1;              // enable TMR2 interrupt flag
29
30
// activate the PWM modules 
31
OC3CON1 = 0x000E;
32
}
33
34
35
void __attribute__((interrupt, shadow, auto_psv)) _T2Interrupt(void)
36
{
37
  static WORD wCount1 = 0; 
38
  static BYTE bCount = 0;
39
  
40
  wCount1++;
41
  if ( wCount1 > 300 ) // 3 seconds: 10kHz / 100 Sine steps
42
  {
43
    wCount1 = 0;
44
45
    bCount=bCount+1;
46
    if ( bCount > 99) bCount = 0;
47
    OC3R = SineTable[bCount];
48
  }  
49
50
  // clear interrupt flag and exit
51
  IFS0bits.T2IF = 0;
52
}
53
54
int SineTable[100] __attribute__((far)) = {
55
200,
56
212,
57
225,
58
237,
59
249,
60
261,
61
273,
62
285,
63
296,
64
307,
65
317,
66
327,
67
336,
68
345,
69
354,
70
361,
71
368,
72
375,
73
380,
74
385,
75
390,
76
393,
77
396,
78
398,
79
399,
80
399,
81
399,
82
398,
83
396,
84
393,
85
390,
86
386,
87
381,
88
375,
89
368,
90
361,
91
354,
92
345,
93
337,
94
327,
95
317,
96
307,
97
296,
98
285,
99
273,
100
262,
101
250,
102
237,
103
225,
104
212,
105
200,
106
187,
107
175,
108
162,
109
150,
110
138,
111
126,
112
115,
113
103,
114
93,
115
82,
116
72,
117
63,
118
54,
119
46,
120
38,
121
31,
122
24,
123
19,
124
14,
125
9,
126
6,
127
3,
128
1,
129
0,
130
0,
131
0,
132
1,
133
3,
134
6,
135
9,
136
13,
137
18,
138
24,
139
30,
140
37,
141
45,
142
53,
143
62,
144
72,
145
81,
146
92,
147
103,
148
114,
149
125,
150
137,
151
149,
152
161,
153
174,
154
186,
155
};

von Daniel W. (danielwohlmuth)


Lesenswert?

Falls es noch aktuell ist, es scheint als hat auch der PIC24 Peripheral 
Pin Select, heißt du musst die OC1 Funktion erst auf den Ausgangspin 
legen.
Datenblatt S. 138. steht wie und wo. Davor sollte sich auch nix tun am 
Pin.

Und, mit den zwei register OC1R OC1RS stellt man den pulse ein.
Jenach konfiguration des OC (high->low / low->high) schaltet er beim 
OCxR high(low) und beim OCxRS wieder low(high).

mit XC32 Compiler ist das ein zweizeiler (16 bit pwm, 50% duty):
1
//Port remapping
2
PPSUnLock;
3
        OUT_PIN_PPS1_RPB15 = OUT_FN_PPS1_OC1; // -> remap output pin
4
PPSLock;
5
6
//Set Digital Out
7
PORTSetPinsDigitalOut(IOPORT_B, BIT_15);
8
9
//PWM
10
OpenTimer2(T2_ON | T2_PS_1_2,0xffff);
11
    OpenOC1(OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_CONTINUE_PULSE | OC_LOW_HIGH, 0xffff,0x7fff);

Der Code ist allerdings für nen PIC32, das Mapping ist vermutlich beim 
24 etwas anders in der Bezeichnung.
Ach ja, und je nach verwendetem Debugging Tool kann die Zeile mit dem 
SetDigitalOut notwendig werden, weil der Pin per default als Analog Pin 
beim Debugging läuft. Einfach mal testen..

Viel Erfolg:)

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.