Forum: Compiler & IDEs PWM mit Tiny26


von Stefan G. (steg13)


Lesenswert?

ich versuche verzeifelt auf GCC umzusteigen, aber selbst einfachste 
Programme machen Probleme. Z.B.:
---------------------
//PWM in Pascal -> läuft
begin
  //Ports
  DDRB :=  %11111111;    //Port B - alles Ausgang
  //Timer
  TCCR1A:= %01111110;    // enable TimerA
  TCCR1B:= %00000011;    // Vorteiler Timer A
  OCR1A:= $64;           // Vergleichsregister
  OCR1C:= $C8;

  Loop
  endloop;
end pwm.
----------------------
//umgeschrieben in GCC -> Ausgang immer 0
int main()
{
//Ports
DDRB  = 0xFF; // PORTB als Ausgang schalten
//Timer
TCCR1A=(0<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<FOC1A)|(1<<FO 
C1B)|(1<<PWM1A)|(0<<PWM1B);
TCCR1B=(0<<CTC1)|(0<<PSR1)|(0<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10);
OCR1A=0x64;
OCR1C=0xC8;

for(;;);
}
--------------------------
kann jemand einen Fehler entdecken?
ich sitze jetzt schon seit Stunden vor dem Code :-(

Gruß
Stefan

von NiSchü (Gast)


Lesenswert?

Ich sehe keine Stelle in dem Quelltext, dass irgendein Ausgang auf 1 
gesetzt wird. Welche STelle soll das auch tun?

von Stefan G. (steg13)


Lesenswert?

NiSchü wrote:
> Ich sehe keine Stelle in dem Quelltext, dass irgendein Ausgang auf 1
> gesetzt wird. Welche STelle soll das auch tun?

Laut Beschreibung :
(0<<COM1A1)|(1<<COM1A0) -> Toggle the OC1A output line
ich verstehe das so, dass der Pin ständig von 0 auf 1 wechselt.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Sowas:
>(0<<CS13)

Ist total sinnlos. (Guck dir mal in einem C-Buch die Funktion des 
Bit-Schiebens an).

Hast du den Tiny auch im Makefile richtig angegeben?
Wie sieht das komplette Programm aus? Wo sind die Include-File?
Sagt der Compiler irgendwas?

Bis auf sinnlose Schiebeaktionen sehe ich auch keinen Fehler (im 
Vergleich zum Pascal-Code).

von MarkusW (Gast)


Lesenswert?

Morgen!

Probier statt

TCCR1A=(0<<COM1A1)|...

mal

TCCR1A |= (0<<COM1A1)|...

Könnte, muß aber nicht.

Gruß
Markus

von Peter D. (peda)


Lesenswert?

inoffizieller WM-Rahul wrote:
> Sowas:
>>(0<<CS13)
>
> Ist total sinnlos.


Stimmt zwar, aber wenn jemand aus Lesbarkeitsgründen es so machen will, 
ist es durchaus erlaubt.

Man weiß dann ja immer welche Bits in dem Register überhaupt definiert 
sind.


Peter

von Joe D. (kosmonaut_pirx)


Lesenswert?

hallo,
wie auch immer die bits geshiftet und gesetzt werden .. den einzigen 
Unterschied sehe ich im setzen der TCCR. dort benutzt du die macros der 
avr-libc, was zunächst sehr löblich ist. aber um fehler auszuschliessen, 
probiere einmal die entsprechung deiner pascal-notation, wie du es mit 
den anderen werten auch getan hast:

  TCCR1A:= %01111110;    // enable TimerA
  TCCR1B:= %00000011;    // Vorteiler Timer A

entsprechend

TCCR1A = 0x7E;
TCCR1B = 0x03;

vll hilfts,
bye kosmo

von Stefan G. (steg13)


Lesenswert?

erster Fehler war der:
falsch: TCCR1A  = (0<<COM1A1)|...
richtig:TCCR1A |= (0<<COM1A1)|...
(da gabe ich falsch abgeschrieben :-)

hatte aber keine Auswirkung

Der Fehler lag im MAKEFILE. Ich benutze das ARV-STUDIO4 das automatisch 
ein Makefile generiert. Ich hatte aber vergessen von Mega auf Tiny 
umzustellen.

Vielen Dank für die schnelle Hilfe.

Gruß
Stefan

Hier noch das komplette lauffähige Programm:

/*
;PWM Test
;
; ================================================
;                   TINY26
; ================================================
;                 __   __
;            PB0 |1  |_| 28| PA0 (ADC0)
;   (OC1A)   PB1 |2   A  27| PA1 (ADC1)
;            PB2 |3   T  26| PA2 (ADC2)
;            PB3 |4   M  25| PA3 (AREF)
;            VCC |5   E  24| GND
;            GND |6   L  23| AVCC
;   (ADC0)   PB4 |7      22| PA4 (ADC3)
;   (ADC0)   PB5 |8   A  21| PA5 (ADC4)
;   (ADC0)   PB6 |9   T  20| PA6 (ADC5/AIN0)
;   (ADC0)   PB7 |10  m  19| PA7 (ADC6/AIN1)
;                |_________|
;
;
*/

#define F_CPU    3600000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define TCCR1A  _SFR_IO8(0x30)
#define PWM1B   0
#define PWM1A   1
#define FOC1B   2
#define FOC1A   3
#define COM1B0  4
#define COM1B1  5
#define COM1A0  6
#define COM1A1  7

#define TCCR1B  _SFR_IO8(0x2F)
#define CS10    0
#define CS11    1
#define CS12    2
#define CS13    3
#define PSR1    6
#define CTC1    7

void Pause(void) //etwa 0,5s
{ uint8_t i;
  uint8_t j;
  for(i=0;i<178;i++)
  {
    for(j=0;j<250;j++) {}
}}

int main()
{

DDRB  = 0xFF; // PORTB als Ausgang schalten
PORTB = 0x80;

TCCR1A|=(0<<COM1A1)|(1<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<FOC1A)|(0<<F 
OC1B)|(1<<PWM1A)|(1<<PWM1B);
TCCR1B|=(0<<CTC1)|(0<<PSR1)|(0<<CS13)|(1<<CS12)|(1<<CS11)|(1<<CS10);

OCR1A=0x30; // Vergleichsregister
OCR1B=0x60;
OCR1C=0xFF; // Max Zählwert


for(;;) //LED an PORTB5 blinkt
  {
  PORTB |= (1 << 5);  // Bit 5 setzen
  Pause();
  PORTB &= ~(1 << 5); // Bit 5 löschen
  Pause();
  }
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan Gemmel wrote:

> erster Fehler war der:
> falsch: TCCR1A  = (0<<COM1A1)|...
> richtig:TCCR1A |= (0<<COM1A1)|...

Nein, das war kein Fehler.  Was soll das Verodern denn bringen?

von Stefan G. (steg13)


Lesenswert?

Jörg Wunsch wrote:
> Stefan Gemmel wrote:
>
>> erster Fehler war der:
>> falsch: TCCR1A  = (0<<COM1A1)|...
>> richtig:TCCR1A |= (0<<COM1A1)|...
>
> Nein, das war kein Fehler.  Was soll das Verodern denn bringen?

In diesem Fall nichts aber:

A = B ist nicht das Gleiche wie A = A oder B
Beispiel: 10=01 (ergibt 01)  10=10 oder 01 (ergibt 11)

In meinem Programm war es kein Fehler weil ich alle Bits angegeben habe.
Ich möchte mir aber trotzdem die richtige Schreibweise angewöhnen :-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Stefan Gemmel wrote:

> In meinem Programm war es kein Fehler weil ich alle Bits angegeben habe.
> Ich möchte mir aber trotzdem die richtige Schreibweise angewöhnen :-)

Für eine komplette Initialisierung eines Registers (anstatt nur einer
Veränderung eines bestehenden Wertes) finde ich aber die absolute
Zuweisung ,,richtiger'' als das Verodern.  Das Verodern löscht dir
eben nicht die Bits, die du so umständlich als (0 << Bitname)
angegeben hast.

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Höhö: Gewonnen!

@Peter: Übersichtlicher wird der Code dadurch nicht. Aber wie die 
kürzlich verstorbene Annemarie Wendl so schön sagte: "Wenn's sche' 
macht!?"

>Für eine komplette Initialisierung eines Registers (anstatt nur einer
>Veränderung eines bestehenden Wertes) finde ich aber die absolute
>Zuweisung ,,richtiger'' als das Verodern.

Volle Zustimmung.

von Stefan G. (steg13)


Lesenswert?

OK ich ihr habt mich überzeugt.

Schade dass man nicht ein paar Kontrollkästchen zum Ankreuzen der Bits 
hat :-) (Visual-Basic für AVAR)

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.