Forum: Mikrocontroller und Digitale Elektronik Compare Match Funktion beim STM32 für Soft-PWM


von Jk M. (h4l9000)


Lesenswert?

Hi,

bisher habe ich Software PWM's mit einem AVR board mit 
"ISR(TIMER1_COMPA_vect)" (Compare Match Funktion) und entsprechend 
setzen/wechseln des DutyCycle durch OCR1x.

Allerdings steige ich nun auf ein STM32 (ARM) Board um. Mit ARM Boards 
habe ich leider keine Erfahrung.
Sind die Register ähnlich dem AVR Board, bzw gibt es sowas wie "Compare 
Match Funktion"?

Hat jemand evtl. sogar ein Beispiel-Code bzw. eine Tutorial wie man 
Software PWM Signale mit STM32 Boards generiert? PWM-Frequenz sollte bei 
~20kHz liegen. Die Compare Match Funktion habe ich verwendet um das PWM 
Signal an und ab zu schalten in definierten Abständen.
Beispiel: |||...: High,  __...:LOW,  ||_||_||: ~20kHz

||||||_||_||_||______||||||_||_||_||_||_||_||||||__||_||_||_||___||||||_ __...


Vielen Dank!

: Bearbeitet durch User
von Michael U. (amiga)


Lesenswert?

Hallo,

der ESP32 ist aber kein ARM-Core sondern ein Tensilika.
Womit willst Du ihn denn Programmieren? Direkt mit dem IDK von Espressif 
oder aus der ArduinoIDE?

Gruß aus Berlin
Michael

von Jk M. (h4l9000)


Lesenswert?

Sorry, ich meine ein STM32 Board.

Eclipse, ArduinoIDE... egal.

von Michael U. (amiga)


Lesenswert?

Hallo,

Jk M. schrieb:
> Sorry, ich meine ein STM32 Board.

ok, da mußt Du auf andere warten, nicht meine Schiene.

Gruß aus Berlin
Michael

von Harry L. (mysth)


Lesenswert?


von Stefan F. (Gast)


Lesenswert?

> Sind die Register ähnlich dem AVR Board, bzw gibt es sowas wie "Compare
> Match Funktion"?

Ja, ähnlich.

Ich kann Dir ein beispiel für Hardware PWM zeigen: 
http://stefanfrings.de/stm32/index.html#pwm

Warum willst du PWM Signale per Software erzeugen? Die STM32 Controller 
haben sehr viel mehr PWM Ausgänge, als die kleinen AVR's.

Abgesehen davon, wenn Du dich geschickt anstellst kannst du die 
Informationen meiner Webseite kombinieren, um deine Soft-PWM zu 
realisieren.

von Jk M. (h4l9000)


Lesenswert?

Ziel ist es 32+ PWM Signale wie oben beschrieben zu generieren. Diese 
müssen aber voneinander unabhängig einstellbar sein. Sprich die Dauer 
der 20kHz PWM, welche sich im "Negativen-Hall"-Zeitfester der 10Hz-100Hz 
einstellbaren PWM befinden.

PWM1 20Khz:        ||_||_||_||
PWM2 zb. 100Hz:    ||||||__________________||||||___________

kombiniert Bsp 1:       ||||||_||_||_||_||______||||||_||_||_||__...

kombiniert Bsp 2:       ||||||_||_||____________||||||_||_||_____...

kombiniert Bsp 2:       ||||||_||_||_||___||||||_||_||_||___||||||_...

Hoffe so ist es verständlicher...

Ich schaue mir deine Webseite mal an. DAnke.

von Jk M. (h4l9000)


Lesenswert?

Der STM32 hat leider "nur" 16 Hardware PWM.

von Jk M. (h4l9000)


Lesenswert?

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
#include <stdbool.h>
5
 
6
// Pin
7
#define PART_DDR (DDRB)  //legt outputs fest
8
#define PART_PORT (PORTB)  // high low der outputs
9
10
#define PART_PORTD (PORTD)
11
#define PART_DDRD (DDRD) 
12
13
//#define PART 0x30//(1<<5)  //bitshifting
14
15
int c=1;
16
volatile long counter = 0; 
17
18
19
byte PART=0x30;
20
byte PART1=0x30;
21
byte PART2=0x10;
22
23
24
volatile long multiDC = 3;
25
volatile long freq = (0x7cff)-0x1f3f-(multiDC*0x320)-1;
26
27
28
29
30
31
32
 
33
void init_application() {
34
// set PART to output and turn it off
35
PART_PORT &= ~PART;
36
PART_DDR |= PART;
37
// reset timer register
38
TCNT1 = 0x0000;
39
// set OCR1A register
40
//OCR1A = 0x1fe;
41
OCR1A = 0x1f3f;
42
// enable output compare match interrupt A
43
TIMSK1 |= (1<<OCIE1A);
44
// set precaler=1, Timerstep @ 16 MHz = 0,0625 us, 65535 Timersteps (2^16); 16000=1ms
45
TCCR1B =  _BV(CS10); 
46
// globally enable interrupts
47
sei();
48
}
49
50
51
52
//void init_application2() {
53
//// set PART to output and turn it off
54
//
55
//PART_PORTD &= ~PART;
56
//PART_DDRD |= PART;
57
//// reset timer register
58
//TCNT1 = 0x0000;
59
//// set OCR1A register
60
////OCR1A = 0x1fe;
61
//OCR1A = 0;
62
//// enable output compare match interrupt A
63
//TIMSK1 |= (1<<OCIE1A);
64
//// set precaler=1, Timerstep @ 16 MHz = 0,0625 us, 65535 Timersteps (2^16); 16000=1ms
65
//// |= (1<<CS10) (1<<CS12);
66
//TCCR1B = _BV(CS10); //_BV(WGM11) |_BV(WGM10) | _BV(CS10); 
67
//// globally enable interrupts
68
//sei();
69
//}
70
71
72
73
74
int main(void) {
75
76
77
init_application();
78
//init_application2();
79
80
for(;;) {
81
82
  }
83
84
  
85
}
86
87
88
89
90
91
// interrupt service routine for timer 1 compare match A
92
ISR(TIMER1_COMPA_vect) {
93
uint16_t current_OCR1A = OCR1A;
94
static bool PART_on = true;
95
96
            switch(c)  {  
97
98
             case 1:
99
                  
100
                  PART=PART1;
101
                  PART_PORT |= PART;   // PORT= PORT OR PART
102
                  PART_PORTD |= PART;
103
                  OCR1A = current_OCR1A+0x1f3f;
104
105
                  c=2;                                  
106
              break;
107
108
109
110
              case 2:
111
112
         
113
                  if(PART_on) {
114
                  PART_PORTD = PART_PORT |= PART;   // PORT= PORT OR PART 
115
                   OCR1A = current_OCR1A+0xc8;        
116
                  }
117
118
                  
119
                  else {
120
                  PART_PORTD =PART_PORT &= ~PART;  //PORT= PORT AND PART
121
122
                   OCR1A = current_OCR1A+0x258;
123
                  counter++;
124
                  
125
                              if(counter==multiDC){ 
126
                              PART = PART2;   
127
                              PART_PORT &= ~PART;  //PORT= PORT AND PART   
128
                               
129
                              }
130
                  }  
131
132
133
                  if(counter==multiDC){  
134
                  c=3;
135
                  }
136
        
137
              break;
138
139
140
141
142
              case 3:
143
             
144
                  PART_PORTD = PART_PORT &= ~PART;  //PORT= PORT AND PART
145
                     
146
                  OCR1A =current_OCR1A+ freq;// 
147
148
                    c=1;
149
                    counter=0;
150
        
151
              break;
152
153
            }
154
155
156
PART_on = !PART_on; // toogle PART on every call of isr
157
}

: Bearbeitet durch Moderator
Beitrag #5388171 wurde von einem Moderator gelöscht.
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.