Pin-Konfiguration des Atmega8:
Bitnummern für I/O-Register:
/* PORTC */ #define PC7 7 #define PC6 6 #define PC5 5 #define PC4 4 #define PC3 3 #define PC2 2 #define PC1 1 #define PC0 0 /* DDRC */ #define DDC7 7 #define DDC6 6 #define DDC5 5 #define DDC4 4 #define DDC3 3 #define DDC2 2 #define DDC1 1 #define DDC0 0 /* PINC */ #define PINC7 7 #define PINC6 6 #define PINC5 5 #define PINC4 4 #define PINC3 3 #define PINC2 2 #define PINC1 1 #define PINC0 0 DDRB = (1 << PB1 ) | (1<<PB2); //PB1 und PB2 auf Ausgang PORTB = 1<<PIN2; //PB2 ein PORTB &= ~(1<<PIN2); //PB2 aus
Die AVR-Mikrocontroller besitzen 3 verschiedene Arten von Speicher:
| Flash | EEPROM | RAM | |
|---|---|---|---|
| Schreibzyklen | >10.000 | >100.000 | unbegrenzt |
| Lesezyklen | unbegrenzt | unbegrenzt | unbegrenzt |
| flüchtig | nein | nein | ja |
| Größe beim ATtiny2313 | 2 KB | 128 Byte | 128 Byte |
| Größe beim ATmega8 | 8 KB | 512 Byte | 1 KB |
| Größe beim ATmega32 | 32 KB | 1 KB | 2 KB |
Quelle: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Speicher
Quelle: Datenblatt des ATmega8
Code und Daten sind im Flashspeicher des Mikrokontrollers abgelegt. Zur Laufzeit werden die benötigten Daten in den RAM kopiert und dann verarbeitet. Der RAM ist ein flüchtiger Speicher.
Beispiel:
lcd_puts("SRAM ");
Daten können auch direkt aus dem Flash-Speicher verarbeitet werden.
Beispiel:
char *ps1=PSTR("FLASH ");
lcd_puts_p(ps1);
Auch mit dem internen EEPROM kann man mit Hilfe der Makros leicht arbeiten. Er eignet sich besonders für nicht-flüchtige kleine Daten, die häufig geändert werden müssen.
Beispiel:
const char* PROGMEM pBuf = PSTR("EEPROM ");
unsigned char zaehler;
eeprom_write_byte(&pBuf,'A');
while (!eeprom_is_ready());
eeprom_write_byte(&pBuf+1,'B');
while (!eeprom_is_ready());
eeprom_write_byte(&pBuf+2,0);
while (!eeprom_is_ready());
for(zaehler=0;eeprom_read_byte(&pBuf+zaehler)!=0;zaehler++) {
while (!eeprom_is_ready());
lcd_putc(eeprom_read_byte(&pBuf+zaehler));
}
Interrupts durch Timer0 und Taster auf INT0:
//Timer0 8 Bit TCCR0 = 1<<CS00 | 1<<CS02; //101: Taktfrequenz/1024 TCNT0 = 0; //256er Zaehler auf 0 setzen TIMSK = 1<<TOIE0; //Timer Interrupt Maskregister, Int bei Ueberlauf Timer0 //ISR durch Taster GIMSK = 1<<INT0; //Externer INT0 eingeschaltet MCUCR = 1<<ISC01; //low pegel loest interrupt aus sei(); //Iterrupts aktivieren
wenn man Interruptquellen pollt und sie manuell zurücksetzen will:
GIFR = 1<<INTF1;
löscht INT1
Die Fast PWM gibt es beim Mega8 mit mehreren unterschiedlichen Bit-Zahlen. Bei den Bit-Zahlen geht es immer darum, wie weit der Timer zählt, bevor ein Rücksetzen des Timers auf 0 erfolgt
Grundsätzlich funktioniert der Fast-PWM Modus so, dass der Timer bei 0 anfängt zu zählen, wobei natürlich der eingestellte Vorteiler des Timers berücksichtigt wird. Erreicht der Timer einen bestimmten Zählerstand (festgelegt durch die Register OCR1A und OCR1B) wird eine Aktion ausgelöst. Je nach Festlegung kann der entsprechende µC Pin (OC1A und OC1B) entweder
Quelle: http://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM
Tabellen mit entsprechenden Registern und Werten siehe Website von Prof. Beck:
TCCR1A=(1<<COM1A1); //auf 1 gesetzt TCCR1A|=(1<<WGM10); //8-Bit PWM
Beispiel:
#include <avr/io.h>
int main(void)
{
DDRB = (1 << PB1 ); // OC1A auf Ausgang
TCCR1A = (1<<COM1A1) | (1<<WGM11); // 9-Bit PWM ; OC1A/B auf Null setzen -> nicht invertierende PWM
TCCR1B=(1<<CS12)|(1<<CS10); // Start timer1 with CK/1024, 8MHz
OCR1A = 11; //Vergleichswert, ueber VG= aus
for(;;); // loop "forewer", wait for signal
return 0;
}
Mit Hilfe der twi-Bibliothek von Peter Fleury ist es sehr einfach mit dem I2C-Bus Daten zwischen Atmega8 und externen EEPROM transportieren:
Initialisierung:
i2c_init();
In EEPROM schreiben:
// write 0x75 to EEPROM address 5 (Byte Write)
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x31); // write value to EEPROM
i2c_stop();
Aus EEPROM lesen:
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode i2c_write(0x05); // write address = 5 i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode ret = i2c_readNak(); // read one byte from EEPROM i2c_stop();