PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] AVR-GCC kennt OC2B nicht



bjj
19.03.2013, 17:55
Hallo zusammen,
ich möchte bei meinem ATMega168 den PWM Port OC2B bzw. PD3 nutzen. Leider kenn AVR_GCC die entsprechenden Konstanten nicht.
Hier mein Quellcode:

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <util/twi.h> //enthält z.B. die Bezeichnungen für die Statuscodes in TWSR
#include <avr/interrupt.h> //dient zur Behandlung der Interrupts
#include <stdint.h> //definiert den Datentyp uint8_t
#include "twislave.h"
#include <stdlib.h> //nötig für Zahlumwandlung mit itoa
#include <util/delay.h>

void pwm_init() {
DDRD |= (1<<OC2B); // Port OC2B mit angeschlossener LED als Ausgang
TCCR2B = (1<<WGM10) | (1<<COM1A1); // PWM, phase correct, 8 bit.
TCCR2B = (1<<CS11) | (1<<CS10); // Prescaler 64 = Enable counter
OCR2B = 128-1;
}
Die Fehlermeldung:

app.c:28: error: 'OC2B' undeclared (first use in this function)
und der Makefile:


TARGET = app
MCU = atmega168
DEVICE = atmega168
MCU_TARGET = atmega128
CC = avr-gcc

CFLAGS =-mmcu=$(MCU) -Wall
LDFLAGS =-mmcu=$(MCU)

$(TARGET): $(TARGET).o

$(TARGET).hex : $(TARGET)
avr-objcopy -j .data -j .text -O ihex $< $@

load: $(TARGET).hex
avrdude -F -P com6 -p m168 -c stk500v2 -U flash:w:$(TARGET).hex -v

clean:
rm -f *.o *.hex $(TARGET)


Ich vermute es fehlt irgendwo ein include. Leider weiss ich nicht mehr weiter.

vg bjj

Searcher
19.03.2013, 18:09
DDRD |= (1<<OC2B);
Geht es den da mit PD3 statt OC2B oder MUSS das mit OC2B gehen?

Gruß
Searcher

markusj
19.03.2013, 18:14
Es gibt in der avr-libc keine Aliasnamen für Pins, PD3 wäre die korrekte Lösung.

mfG
Markus

bjj
19.03.2013, 19:24
Danke, habe es jetzt für den Port PB1 (bzw. OC1A) hinbekommen. Wie es jedoch für die anderen Ports geht bleibt mir schleierhaft.

Lösung für PB1


DDRB |= (1<<PB1); // Port OC1A mit angeschlossener LED als Ausgang
TCCR1A = (1<<WGM10) | (1<<COM1A1); // PWM, phase correct, 8 bit.
TCCR1B = (1<<CS11) | (1<<CS10); // Prescaler 64 = Enable counter
OCR1A = 128-1; // Duty cycle 50% (Anm. ob 128 oder 127 bitte prüfen)


Welche Werte müsste ich für PD3 ändern?


DDRD |= (1<<PD3);
TCCR?? = (1<<WGM10) | (1<<COM1A1);
TCCR?? = (1<<CS11) | (1<<CS10);
OCR?? = 128-1;

ad°FX
19.03.2013, 20:14
Moin bjj,

so wie Markus sagt kannst Du nicht DDRD |= (1<<OC2B) zuweisen! Du kannst nur DDRD |= (1<<PDn) zuweisen um PortDn als Ausgang zu definieren. Im Grunde bist Du schon auf dem richtigen Weg. Ich habe die Pin's nicht im Kopf vom Mega168, aber wenn Du dir die Pin-Belegung im Datenblatt anschaust, findest Du neben dem (OC2B/.../...) den entpsrechenden PortD den Du als Ausgang definierst. Also genauso wie das am PortB gemacht hast.
Viel Erfolg...

markusj
19.03.2013, 21:01
Im Grunde ist die Sache ganz einfach. Es gibt Register und es gibt Bits in diesen Registern. Die avr-libc übernimmt die Bezeichnungen 1:1 aus dem Datenblatt.
Bei dieser Aufzählung fehlen die Pins. Warum? Die existieren nicht in der virtuellen Welt. "Zufälligerweise" sind die PORTx, PINx und DDRx-Register mit den Pins verdrahtet, wenn du also einen bestimmten Pin manipulieren möchtest, kannst du das über diese Register tun. Im Datenblatt stehen neben den Pins noch andere Bezeichnungen, im Wesentlichen geben die Aufschluss darüber welche Funktionalität noch alles an dem Pin hängt. Konfiguriert wird der Pin aber nach wie vor über die Bits "seiner" Register, und die Namen dieser Bits sind unabhängig von den Zusatzfunktionen.

Das entsprechende Kapitel im Datenblatt des Mega168 ist 13.4, I/O-Ports - Register Description.

mG
Markus

bjj
24.03.2013, 15:07
Herzlichen Danke an alle, ich habs nun hinbekommen. PWM läuft für die Pins B1, D3 und D5

Meine Lösung:


// PWM für PB1
DDRB |= (1<<PB1); // Port OC1A mit angeschlossener LED als Ausgang
TCCR1A = (1<<WGM10) | (1<<COM1A1); // PWM, phase correct, 8 bit.
TCCR1B = (1<<CS11) | (1<<CS10); // Prescaler 64 = Enable counter
OCR1A = 128-1; // Duty cycle 50% (Anm. ob 128 oder 127 bitte prüfen)

// PWM für PD3
DDRD |= (1<<PD3);
TCCR2A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM01) | (1<<WGM00);
TCCR2B = (1<<CS01);
OCR2B = 128-1;
OCR2A = 128-1;

// PWM für PD5
DDRD |= (1<<PD5); // Läuft
TCCR0A = (1<<COM1A1) | (1<<COM1B1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1<<CS01);
OCR0B = 128-1; // D5
OCR0A = 128-1;