Hallo
Jetzt habe ich erstmal ein blockierendes Lesen fertig:
Code:
#include "RP6RobotBaseLib.h"
#define BAUD_2400 2400 //IR speed - 2400 Baud
#define UBRR_BAUD_2400 (((F_CPU/16)/BAUD_2400)-1)
uint8_t i; // Hilfsvariable
void IRwriteChar(uint8_t zeichen)
{
UBRRH = UBRR_BAUD_2400 >> 8; // Baudrate auf 2400 setzen
UBRRL = (uint8_t) UBRR_BAUD_2400;
if (UCSRA & (1<<TXC)) UCSRA=1<<TXC; // TXC-Flag löschen falls gesetzt
UDR = (uint8_t)zeichen; // Zeichen ins Senderegister des UARTs
while (!(UCSRA & (1<<TXC))) // Solange das Schieberegister nicht leer ist,
{
if (PIND & TX) // lauschen wir am TX-Pin
{
TCCR2 &= ~(1 << COM20); // und schalten OC2 und IRCOMM-LEDs aus
PORTD &= ~IRCOMM;
}
else
{
TCCR2 |= (1 << COM20); // oder toggeln mit 36kHz ;)
}
}
UCSRA=1<<TXC; // TXC-Flag setzen bedeutet löschen!!!
TCCR2 &= ~(1 << COM20); // toggeln ausschalten
PORTD &= ~IRCOMM; // IRCOMM-LEDs ausschalten
UBRRH = UBRR_BAUD_LOW >> 8; // RP6Loaderbaudrate setzen
UBRRL = (uint8_t) UBRR_BAUD_LOW;
}
uint8_t IRreadChar(void)
{
uint8_t zeichen=0; // Speicher für die einzelnen Bits
uint8_t bitnr; // Nummer des aktuellen Bits
uint8_t bitwert[8]={1,2,4,8,16,32,64,128};// Die Werte der Bits (lsb kommt zuerst)
/*
Baudrate Bitlänge
300 Baud 3,33 ms
2400 Baud 417 µs // sleep(4) dauert etwa 400us
9600 Baud 104 µs // mit sleep(3) beim Startbit wird der
38400 Baud 26,04 µs // Fehler kompensiert ;)
*/
while(PINB & ACS); // Blockierend auf Startbit warten
sleep(3); // Lesemoment ca. auf Mitte Startbit
for (bitnr=0; bitnr<8; bitnr++) // Die Bits in einer Schleife einlesen
{
sleep(4); // ca. in der Mitte des Bits lesen
if (PINB & ACS) zeichen+=bitwert[bitnr];
}
sleep(8); // es kommen noch 2 Stopbits
return zeichen;
}
int main(void)
{
initRobotBase();
setLEDs(0b111111);
powerON();
mSleep(300);
setLEDs(0);
while(1)
{
i=IRreadChar(); // Zeichen einlesen
IRwriteChar(i+1); // und als ascii+1 zurücksenden
}
return 0;
}
Eine Timeout-Erweiterung und eine vernüftige Einbindung in die Library wären nun die nächsten Schritte.
Beim Senden wird nun zuerst das TXC-Flag gelöscht, falls es gesetzt war. Nach dem Senden wird nun auch das Toggeln ausgeschaltet, dann sollten die IRCOMM-LEDs auch ausbleiben.
Gruß
mic
[Edit]
Nicht sehr elegant, aber es funktioniert nun auch mit Timeout:
Code:
#include "RP6RobotBaseLib.h"
#define BAUD_2400 2400 //IR speed - 2400 Baud
#define UBRR_BAUD_2400 (((F_CPU/16)/BAUD_2400)-1)
uint8_t i; // Hilfsvariable
void IRwriteChar(uint8_t zeichen)
{
UBRRH = UBRR_BAUD_2400 >> 8; // Baudrate auf 2400 setzen
UBRRL = (uint8_t) UBRR_BAUD_2400;
if (UCSRA & (1<<TXC)) UCSRA=1<<TXC; // TXC-Flag löschen falls gesetzt
UDR = (uint8_t)zeichen; // Zeichen ins Senderegister des UARTs
while (!(UCSRA & (1<<TXC))) // Solange das Schieberegister nicht leer ist,
{
if (PIND & TX) // lauschen wir am TX-Pin
{
TCCR2 &= ~(1 << COM20); // und schalten OC2 und IRCOMM-LEDs aus
PORTD &= ~IRCOMM;
}
else
{
TCCR2 |= (1 << COM20); // oder toggeln mit 36kHz ;)
}
}
UCSRA=1<<TXC; // TXC-Flag setzen bedeutet löschen!!!
TCCR2 &= ~(1 << COM20); // toggeln ausschalten
PORTD &= ~IRCOMM; // IRCOMM-LEDs ausschalten
UBRRH = UBRR_BAUD_LOW >> 8; // RP6Loaderbaudrate setzen
UBRRL = (uint8_t) UBRR_BAUD_LOW;
}
uint8_t IRreadChar(uint16_t timeout)
{
uint8_t zeichen=0; // Speicher für die einzelnen Bits
uint8_t bitnr; // Nummer des aktuellen Bits
uint8_t bitwert[8]={1,2,4,8,16,32,64,128};// Die Werte der Bits (lsb kommt zuerst)
/*
Baudrate Bitlänge
300 Baud 3,33 ms
2400 Baud 417 µs // sleep(4) dauert etwa 400us
9600 Baud 104 µs // mit sleep(3) beim Startbit wird der
38400 Baud 26,04 µs // Fehler kompensiert ;)
*/
if (timeout)
{
startStopwatch1(); // Stopuhr starten
setStopwatch1(0); // vorsichtshalber zurücksetzen
while(PINB & ACS)
if (getStopwatch1() >= timeout) // bei Timeout Zeichen null zurückgeben
return 0;
}
else while(PINB & ACS); // Blockierend auf Startbit warten
sleep(3); // Lesemoment ca. auf Mitte Startbit
for (bitnr=0; bitnr<8; bitnr++) // Die Bits in einer Schleife einlesen
{
sleep(4); // ca. in der Mitte des Bits lesen
if (PINB & ACS) zeichen+=bitwert[bitnr];
}
sleep(10); // es kommen noch 2 Stopbits
return zeichen;
}
int main(void)
{
initRobotBase();
setLEDs(0b111111);
powerON();
mSleep(300);
setLEDs(0);
while(1)
{
i=IRreadChar(500);
if (i) IRwriteChar(i+1);
}
return 0;
}
Lesezeichen