Forum: Mikrocontroller und Digitale Elektronik Verbindung von Atmega32 zu PC über Infrarot


von Electric S. (electricsheep)


Lesenswert?

Hi,
bei meinem Asuro-Roboter (http://de.wikipedia.org/wiki/ASURO) gibt es 
eine Übertragung vom Atmega8L zum PC über Infrarot (Baudrate 2400) und 
einen USB-Infrarot-Empfänger. Dabei ist die IR-Diode mit einem 
Widerstand an PB3(MOSI/OC2) und an PD1(TXD).
Der Code dazu ist dieser:
1
void SerWrite(unsigned char *data,unsigned char length)
2
{
3
  unsigned char i = 0;
4
  UCSRB = 0x08; // enable transmitter
5
  while (length > 0) {
6
    if (UCSRA & 0x20) { // wait for empty transmit buffer
7
      UDR = data[i++];
8
      length --;
9
    }
10
  }
11
  while (!(UCSRA & 0x40)); 
12
  for (i = 0; i < 0xFE; i++)
13
    for(length = 0; length < 0xFE; length++);
14
}
Jetzt nöchte ich von einem Atmega32 Daten zum PC übertragen, wieder über 
IR-Diode und -empfänger.

Wo muss ich denn nun die IR-Diode am Atmega32 anschließen? Muss ich an 
der Übertragungsmethode etwas ändern?

Bisher habe ich schon versucht, die unveränderte Methode zu benutzen und 
die Diode an PB5(MOSI) und PD1(TXD) anzuschließen, aber so hat der 
IR-Empfänger leider nichts gemeldet.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Electric S. schrieb:
> Dabei ist die IR-Diode mit einem
> Widerstand an PB3(MOSI/OC2) und an PD1(TXD).

Electric S. schrieb:
> die unveränderte Methode zu benutzen und
> die Diode an PB5(MOSI) und PD1(TXD) anzuschließen,

Siehst Du den Unterschied? Der Witz ist, dass das 2. Bein der IR-Diode 
an einen Output-Compare Ausgang eines Timers anzuschließen ist, welcher 
mit 36..40kHz toggelt.

von Electric S. (electricsheep)


Lesenswert?

Ah ok. Leider wusste ich nicht, ob am Atmega8 der MOSI oder der OC2 
genutzt wird.
Also soll ich einfach mal die Diode an PD7(OC2) und an PD1(TXD) 
anschließen?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Electric S. schrieb:
> Also soll ich einfach mal die Diode an PD7(OC2) und an PD1(TXD)
> anschließen?

Genau. Und Timer2 entsprechend konfigurieren, dass 36...40kHz-Pulse mit 
50% Duty-Cycle entstehen. DDRD, 7 auf Ausgang setzen.

von Electric S. (electricsheep)


Lesenswert?

Knut Ballhause schrieb:
> Genau. Und Timer2 entsprechend konfigurieren, dass 36...40kHz-Pulse mit
> 50% Duty-Cycle entstehen. DDRD, 7 auf Ausgang setzen.

Ah ok.
Wie programmiere ich das? Bisher habe ich nur mit fertigen Funktionen 
gearbeitet...
Das funktioniert mit TCCR2?

von Electric S. (electricsheep)


Lesenswert?

Da ich bisher noch nicht mit Timern gearbeitet habe, würde ich mich sehr 
freuen, wenn Sie mir den Code für diese Funktion programmieren könnten.
Das sind vermutlich nur wenige Zeilen.

von Electric S. (electricsheep)


Lesenswert?

Im Code von Asuro habe ich diesen Code für die IR-Übertragung gefunden:
1
  //  prepare 36kHz for IR - Communication
2
  TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
3
  OCR2  = 0x6E; // 36kHz @8MHz
4
  TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
5
  
6
  // prepare RS232 
7
  UCSRA = 0x00;
8
  UCSRB = 0x00;  
9
  UCSRC = 0x86; // No Parity | 1 Stop Bit | 8 Data Bit
10
  UBRRL = 0xCF; // 2400bps @ 8.00MHz
Den Wert für UBRRL habe ich schon an die Frequenz von 32MHz angepasst.
Wie ist der Wert für OCR2 definiert?

von Serieller (Gast)


Lesenswert?

> Frequenz von 32MHz
               ^^^^^
What?

von Electric S. (electricsheep)


Lesenswert?

Oh, da hab ich was verwechselt.
Atmega8 = 8MHz,
Atmega32 = 32Mhz, dachte ich.
Welche Frequenz hat er denn?

von ich (Gast)


Lesenswert?

Steht im Datenblatt:
0-16Mhz, genauso wie der mega8

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Electric S. schrieb:
> Welche Frequenz hat er denn?

Alles zwischen 0...16Mhz. Intern 8, 4, 2 oder 1MHz, extern je nach Quarz 
oder Oszillator. Die Fuses müssen u.U. umgesetzt werden. Fabrikneu läuft 
das Teil mit relativ ungenauen, internen 1Mhz.

von Serieller (Gast)


Lesenswert?

Kenn ich dein Projekt :)

Der hat das was du eventuell an Taktgeber im Schaltplan (Zaunpfahl 1!) 
verbaut und dann in den AVR Fuses (Zaunpfahl 2!) eingestellt hast.

von Electric S. (electricsheep)


Lesenswert?

Woher kennst du mein Projekt? :D

Serieller schrieb:
> Der hat das was du eventuell an Taktgeber im Schaltplan (Zaunpfahl 1!)
> verbaut und dann in den AVR Fuses (Zaunpfahl 2!) eingestellt hast.

Aha. Du meinst die Pins XTAL1/2?
Da hängt nichs dran...
Welche Fuses eingestellt sind, weiß ich nicht, da ich mit einer IDE 
arbeite, nicht mit den AVR-Compilern.

von Electric S. (electricsheep)


Lesenswert?

Hi,

Software-PWM für 36kHz habe ich im Internet gefunden:
1
  TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
2
  OCR2  = 0x91;                         // duty cycle fuer 36kHz
3
  TIMSK |= (1 << TOIE2);
4
  sei();      // enable interrupts

Aber wie bekomme ich eine 36kHz PWM an den Pin OC0?

von Karl H. (kbuchegg)


Lesenswert?

Electric S. schrieb:
> Hi,
>
> Software-PWM für 36kHz habe ich im Internet gefunden:

Wozu willst du dir mehr arbeit machen als notwendig?

> Aber wie bekomme ich eine 36kHz PWM an den Pin OC0?

Fang endlich an, das Datenblatt deines Prozessors zu lesen!
Atmel hat da einen ganzen Abschnitt nur diesem Timer gewidmet.

Und nein: Ohne Datenblatt kommst du nicht weit.

In Ergänzung zum Datenblatt
AVR-Tutorial
AVR-GCC-Tutorial

> Da ich bisher noch nicht mit Timern gearbeitet habe,

das ist keine Ausrede

> würde ich mich sehr
> freuen, wenn Sie mir den Code für diese Funktion programmieren könnten.
> Das sind vermutlich nur wenige Zeilen.

Eben.
Und es ist dir zuzumuten, dass du dir diese aus dem Datenblatt 
zusammensuchst. Beim ersten mal dauert das noch ein wenig, aber mit 
jedem mal diese Datenblattsektion ansehen, wirst du immer schneller beim 
AUffinden der relevanten Information. Nebeneffekt: Du weißt was deine 
Timer noch so alles können.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Guck Dir den CTC-Modus des Timers an. Stelle den OCxx-Pin (die beiden x 
stehen für den betreffenden Timer und das A oder B des betreffenden 
Komparators) auf 'Toggle on Compare', danit hast Du alles, was Du 
brauchst. Das OCRxx-Register lädst Du mit einem Wert, der die 
CPU-Frequenz so dividiert, dass der OCxx-Ausgang mit 36kHz umschaltet.

von Electric S. (electricsheep)


Lesenswert?

Ok, danke euch beiden.
Den Abschnitt im Datenblatt hab ich mir jetzt mehrmals durchgelesen, 
dabei aber relativ wenig verstanden... Egal, ich versuche es weiter.

Auf der Seite rn-wissen.de habe ich diesen Code gefunden:
1
TCCR2 |= (1<<WGM21);
Der Code schaltet anscheinend den CTC-Modus ein. Ist das richtig?

Damit ich einen 50%-Duty Cicle habe, muss ich in OCR2 den Wert 127 
schreiben. Weiterhin muss ich den Pin OC2 als Ausgang schalten:
1
DDRD |= (1<<PD7);
Ist das hier auch richtig?



////EDIT:
Diese Seite ist gemeint:
http://www.rn-wissen.de/index.php/Timer/Counter_%28Avr%29#CTC_Modus_.28Clear_Timer_on_Compare_Match_mode.29
////

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.