Hallo zusammen, ich habe mit Eurer Hilfe gerade geschaft, meinen Mega64 zu verbinden und mein erstes Programm hineinzuschreiben: #include <avr/io.h> int main(void) { DDRA = 0xFF; //PortA: alles als Ausgäng DDRB = 0xFF; //PortB: alles als Ausgang PORTA = 0xFF; PORTB = 0xFF; } Ich würde nun gerne eine LED über PWM ansteuern, also langsam ein/-ausfaden lassen. Kann mir bitte jemand helfen, der sich mit dem Mega64 auskennt. Es wäre echt nett, wenn ihr mir ein paar Programmzeilen schreiben könntet, aus denen ich dann lernen kann. (wenn es nicht zuviel verlagt ist, dann bitte mit Kommentar, damit ich durchsteige und aus Eurer Vorgehensweise lernen kann) Danke schonmal im voraus und Grüße popi
seh mal ins wiki/tutorial.... dort ist das alles beschrieben.
... daher hier die Frage: Laut dem empfohlenem Tutorial soll ich den PWM Modus aktivieren. Eigentlich steht im Datenblatt vom Mega64, das dieser einen 16-Bit Counter hat, aber ich kann laut TCCR1A nur 8,9 oder 10 Bit-Counter wählen (Datenblatt Mega64 Seite 135), je nachdem was ich am Bit 0 und 1 einstelle. Wie auch immer, vielleicht muss das ein Anfänger auch noch nicht verstehen, so gebe ich mich auch mit 8-Bit PWM zum testen zufrieden. Also, das TCCR1A Register besteht aus 8 Bits. Wie setzt man nun die Bits 0 und 1 auf 01, um einen 8-Bit-PWM zu aktivieren, erhalten, was auch immer. Muss man eine Oder Verknüpfung mit der Register machen: Sowas wie TCCR1A | 01; oder wie geht das ??? Ich will ja die anderen Pins nicht verstellen? Danke und Grüße popi
Hier die Beispiele von Peter Fleury. Musst Du Dir nur noch auf den Mega64 umschreiben. /*********************************************************************** ******* Title: Pulse Width Modulation (PWM) example Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury Date: December 2003 Software: AVR-GCC 3.3 Hardware: AT90S8515 at 4 Mhz, ATmega8 with 1 Mhz Description: This example shows how to generate voltages between VCC and GND using Pulse Width Modulation (PWM). A LED with a series resistor should be connected from PD5 to GND. See also Atmel AVR Application Note AVR130 ************************************************************************ *******/ #include <inttypes.h> #include <avr/io.h> /* * constants */ #if _AVR_AT90S8515_ #define XTAL 4000000L // Crystal frequency in Hz #define OC1A_PIN PD5 // OC1A pin (for AT90S8515 use PD5, for ATmega8 use PB1) #define OC1A_DDR DDRD // OC1A DDR (for AT90S8515 use DDRD, for ATmega8 use DDRB) #define WGM12 CTC1 // for compatibility with AT90S8515 #define WGM10 PWM10 // for compatibility with AT90S8515 #elif _AVR_ATmega8_ #define XTAL 1000000L // Crystal frequency in Hz #define OC1A_PIN PB1 // OC1A pin (for AT90S8515 use PD5, for ATmega8 use PB1) #define OC1A_DDR DDRB // OC1A DDR (for AT90S8515 use DDRD, for ATmega8 use DDRB) #else #error "Adapt pin definitions to your MCU" #endif /* * function prototypes */ static void delay(uint16_t us); /* * function definitions */ static void delay(uint16_t us) /* delay for a minimum of <us> microseconds */ /* with a 4Mhz crystal, the resolution is 1 us */ { while ( us ) us--; } int main(void) { uint8_t i = 0; DDRB = 0xff; // use all pins on PortB for output PORTB = 0xff; // set output high -> turn all LEDs off // set OC1A pin as output, required for output toggling OC1A_DDR |= _BV(OC1A_PIN); // enable 8 bit PWM, select inverted PWM TCCR1A = _BV(WGM10) | _BV(COM1A1) | _BV(COM1A0); // timer1 running on 1/8 MCU clock with clear timer/counter1 on Compare Match // PWM frequency will be MCU clock 8 512, e.g. with 4Mhz Crystal 977 Hz. TCCR1B = _BV(CS11) | _BV(WGM12); /* * Dimm LED on and off in interval of 2.5 seconds */ for (;;) { /* dimm LED on */ for (i=0; i<255; i++) { OCR1AL = i; delay(XTAL/400); // delay 10 ms } /* dimm LED off */ for( i=255; i>0; i--) { OCR1AL = i; delay(XTAL/400); // delay 10 ms } } }
Sollte so funktionieren: in temp,tccr1a ;TCCR1A nach temp kopieren ori temp,0b00000001 ;Bit setzten out tccr1a,temp ;temp nach TCCR1A kopieren
TCCR1A = _BV(WGM10) | _BV(COM1A1) | _BV(COM1A0); Also eigentlich nur das _BV ??? Ist bestimmt das gleiche wie 1<<WGM10 aber warum _BV und wofür steht es ? Grüße popi
_BV() steht für Bit-Value - - 1<<WGM10 ist gleichbedeutend mit _BV(WGM10). Viele Grüße, Stefan
Es wird mit _BV also nur gesetzt! Wenn ich ein Bit löschen möchte, dann benuzte ich 0<<WGM10 Geht das löschen auch mit _BV oder ähnlichem ? Danke und Grüße popi
Kommt drauf an. Bits loescht man in der Regel nicht mit diesen Konstrukten, dafuer braucht es eine logische Und-Operation mit einer invertierten Maske. _BV() ist aber praktisch zum setzen von Bits durch logische Oder-Operationen.
Beispiel: MY_BIT = 3: Bits setzen: ------------ my_data |= _BV(MY_BIT); MY_BIT == 3 _BV(MY_BIT) == 00001000 binär // 1 binär um 3 Stellen links geschoben Beim VerODERn mit der entstehenden Maske 00001000b wird nur das Bit MY_BIT gesetzt, alle anderen bleiben unverändert. Bits löschen: ------------- my_data &= ~_BV(MY_BIT); MY_BIT == 3 _BV(MY_BIT) == 00001000 binär // 1 binär um 3 Stellen links geschoben ~_BV(MY_BIT) == 11110111 binär // negieren Beim VerUNDen mit der entstehenden Maske 11110111b wird nur das Bit MY_BIT gelöscht, alle anderen bleiben unverändert. Stefan
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.