mikrocontroller.net

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


Autor: Jk M. (h4l9000)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jk M. (h4l9000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, ich meine ein STM32 Board.

Eclipse, ArduinoIDE... egal.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Harry L. (mysth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
-1 lesenswert
nicht 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.

Autor: Jk M. (h4l9000)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jk M. (h4l9000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der STM32 hat leider "nur" 16 Hardware PWM.

Autor: Jk M. (h4l9000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include <stdbool.h>
 
// Pin
#define PART_DDR (DDRB)  //legt outputs fest
#define PART_PORT (PORTB)  // high low der outputs

#define PART_PORTD (PORTD)
#define PART_DDRD (DDRD) 

//#define PART 0x30//(1<<5)  //bitshifting

int c=1;
volatile long counter = 0; 


byte PART=0x30;
byte PART1=0x30;
byte PART2=0x10;


volatile long multiDC = 3;
volatile long freq = (0x7cff)-0x1f3f-(multiDC*0x320)-1;






 
void init_application() {
// set PART to output and turn it off
PART_PORT &= ~PART;
PART_DDR |= PART;
// reset timer register
TCNT1 = 0x0000;
// set OCR1A register
//OCR1A = 0x1fe;
OCR1A = 0x1f3f;
// enable output compare match interrupt A
TIMSK1 |= (1<<OCIE1A);
// set precaler=1, Timerstep @ 16 MHz = 0,0625 us, 65535 Timersteps (2^16); 16000=1ms
TCCR1B =  _BV(CS10); 
// globally enable interrupts
sei();
}



//void init_application2() {
//// set PART to output and turn it off
//
//PART_PORTD &= ~PART;
//PART_DDRD |= PART;
//// reset timer register
//TCNT1 = 0x0000;
//// set OCR1A register
////OCR1A = 0x1fe;
//OCR1A = 0;
//// enable output compare match interrupt A
//TIMSK1 |= (1<<OCIE1A);
//// set precaler=1, Timerstep @ 16 MHz = 0,0625 us, 65535 Timersteps (2^16); 16000=1ms
//// |= (1<<CS10) (1<<CS12);
//TCCR1B = _BV(CS10); //_BV(WGM11) |_BV(WGM10) | _BV(CS10); 
//// globally enable interrupts
//sei();
//}




int main(void) {


init_application();
//init_application2();

for(;;) {

  }

  
}





// interrupt service routine for timer 1 compare match A
ISR(TIMER1_COMPA_vect) {
uint16_t current_OCR1A = OCR1A;
static bool PART_on = true;

            switch(c)  {  

             case 1:
                  
                  PART=PART1;
                  PART_PORT |= PART;   // PORT= PORT OR PART
                  PART_PORTD |= PART;
                  OCR1A = current_OCR1A+0x1f3f;

                  c=2;                                  
              break;



              case 2:

         
                  if(PART_on) {
                  PART_PORTD = PART_PORT |= PART;   // PORT= PORT OR PART 
                   OCR1A = current_OCR1A+0xc8;        
                  }

                  
                  else {
                  PART_PORTD =PART_PORT &= ~PART;  //PORT= PORT AND PART

                   OCR1A = current_OCR1A+0x258;
                  counter++;
                  
                              if(counter==multiDC){ 
                              PART = PART2;   
                              PART_PORT &= ~PART;  //PORT= PORT AND PART   
                               
                              }
                  }  


                  if(counter==multiDC){  
                  c=3;
                  }
        
              break;




              case 3:
             
                  PART_PORTD = PART_PORT &= ~PART;  //PORT= PORT AND PART
                     
                  OCR1A =current_OCR1A+ freq;// 

                    c=1;
                    counter=0;
        
              break;

            }


PART_on = !PART_on; // toogle PART on every call of isr
}

: Bearbeitet durch Moderator
Beitrag #5388171 wurde von einem Moderator gelöscht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.