Forum: Compiler & IDEs ATmega32 PWM + FreeRTOS Multitasking


von maddde (Gast)


Lesenswert?

Einen wunderschönen guten Tag.

habe da ein Problem und komme nicht weiter. Versucht habe ich mit einem 
ATmega32 auf dem STK500 zwei Led's per PWM zu dimmen (task2) und 
nebenher einen zweiten Task (task1) laufen zu lassen, der eine andere 
Led toggelt. Das Problem ist, das nur funktioniert, wenn ich den Ausgang 
OCR1AL benutze (PortD 5).
Sobald ich aber das Vergleichsregister OCR1BL beschreibe (so wie unten 
im Quelltext angegeben) wird der LED-Toggle Task (task1 mit der 
niedrigeren Priorität) nicht mehr ausgeführt. Die Led's werden aber 
gedimmt. Wenn nur eine LED gedimmt werden soll, also OCR1AL gesetzt 
wird, funktioniert das ganze einwandfrei.

Also geschrieben ist das mit AVR-Studio 5, der ATmega32 (16 MHz) sitzt 
auf einem STK500 und FreeRTOS ist Version 7.0.1.

Hat jemand eine Idee woran das liegen könnte?

Vielen Dank und viele Grüße
maddde

[c]
//FreeRTOS include files

#include "FreeRTOS.h"

#include "FreeRTOSConfig.h"

#include "task.h"



void task1(){

  const portTickType freq1 = 150;

  portTickType lastwake1 = xTaskGetTickCount();



  for(;;){

    vTaskDelayUntil(&lastwake1, freq1);

    PORTD |= (1<<PD7);

    vTaskDelay(50);

    PORTD &= ~(1<<PD7);

  }

}



void task2(){

  int i = 0;



  TCCR1A = 0xB1;

  TCCR1B = 0x01;



  OCR1AL = 255;

  OCR1BL = 0;



  const portTickType freq2 = 10;

  portTickType lastwake2 = xTaskGetTickCount();



  for(;;){ //LED blinken

    vTaskDelayUntil(&lastwake2, freq2);



    ++i;



    if(i > 150){

      i = 0;

    }



     OCR1AL = 255-i;

    OCR1BL = i;

  }

}







void main(){



  DDRD = 0B11110000;

  PORTD = 0B00001111;



  xTaskCreate(task1, (signed portCHAR *)"task1", 
configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL);


        xTaskCreate(task2, (signed portCHAR *)"task2", 
configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL);



  vTaskStartScheduler();

}



[\c]

von mattis k. (maddde)


Lesenswert?

Und wie so häufig kommt die Lösung allein, wenn man das jemand anderem 
erzählt.

Nachdem ich die Zeile "  TCCR1B = 0x01;  " auskommentiert habe läufts. 
Allerdings ist mir nicht ganz klar warum. TCCR1B ist laut Datenblatt für 
die Einstellungen des Prescalers verantwortlich. So sollte der Timer 
eigentlich gar nicht laufen. Werd dann nochmal die Datenblätter 
durchwälzen...

Hat trotzdem jemand eine Idee was ich falsch mache?


Viele Grüße,
maddde

von Frank W. (Firma: DB1FW) (frankw) Benutzerseite


Lesenswert?

Keine wirklich Ahnung - aber eine Idee wo Du mal nachschauen könntest.
Ich nehme mal an, dass das RTOS eine Timer benötigt. Insbesondere wenn 
es als pre-emptive konfiguriert ist, aber auch sonst. Wenn Du mit diesem 
Timer nun "rumspielst", könnte es sein dass das ROTS ducheinander kommt 
?

von mattis k. (maddde)


Lesenswert?

Ja danke, das war ein guter Tipp ;)

FreeRTOS hat die "TICKS" über den Timer 1 generiert, den ich dann für 
mein PWM-Signal verwenden wollte. Komischerweise hat sich das aber nicht 
in einem großen Knall geäußert, sondern wäre vermutlich nur bei einer 
genauen Beobachtung mit einem Oszi zu erkennen gewesen.

Hab jetzt Timer0 des Atmega für die Ticks genommen. OCRO auf 124 und 
Prescaler 64 müsste bei einer Takfrequenz von 16MHZ 1000HZ ergeben. 
Diese Änderungen werden in der port.c von Freertos vorgenommen.

Vielen Dank nochmal und viele Grüße,

Mattis

von mattis k. (maddde)


Lesenswert?

sorry, im text hat sich ein fehler eingschlichen...

Prescaler 64
OCRO 249

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.