Compare Match Funktion beim STM32 für Soft-PWM

OP #5388038
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!
Gast #5388125
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.
OP #5388151
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.
OP #5388164
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
}
Beitrag #5388171 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren