Code:
// RP6 sendet eine 64x48-Bitmap über die serielle Schnittstelle 2.4.10 mic
// Der RP6 sendet eine Bitmap über die serielle Schnittstelle zum PC.
// Dort wird es von einem kleinen Tool empfangen und abgespeichert:
// http://www.mikrocontroller.net/topic/74659#616065
// Den Header habe ich von einer echten Bitmap mit passendem Format abgeschrieben.
// Infos zum Aufbau einer BMP-Datei bei Wikipedia:
// http://de.wikipedia.org/wiki/Windows_Bitmap
// Es werden die unveränderten Kameradaten verwendet.
#include "RP6RobotBaseLib.h"
void ADC_Init(void)
{
extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setze free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein Interupt, Wandler einschalten, prescaler /2, ADC läuft nun mit 4MHz!
ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
ADCSRA |= (1<<ADSC);
// und noch die empfohlene Initiallesung
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);
}
int main(void)
{
uint8_t bildspeicher[100], *bildzeiger; // 100 Byte Bildspeicher sollten reichen
uint8_t zeile, sync, c; // und dürfen NICHT global sein!
uint8_t bmp_header_64_48_24bit[54]={ // Header für ein 64x48x24-BMP hat 54 Bytes
0x42, 0x4d, 0x36, 0x24, 00, 00, 00, 00, 00, 00, 0x36, 00, 00, 00, 0x28, 00,
00, 00, 0x40, 00, 00, 00, 0x30, 00, 00, 00, 01, 00, 0x18, 00, 00, 00,
00, 00, 00, 0x24, 00, 00, 0xc4, 0x0e, 00, 00, 0xc4, 0x0e, 00, 00, 00, 00,
00, 00, 00, 00, 00, 00};
initRobotBase();
ADC_Init();
while(1)
{
for(c=0; c<54; c++) writeChar(bmp_header_64_48_24bit[c]); // Header senden
for(c=0; c<48; c++) // 48 Bildzeilen einlesen und als RGB-Pixel senden
{
setLEDs(c); // working
bildzeiger=&bildspeicher[0]; // Zeiger auf Start des Bildspeicherbereich
zeile=c*5+35; // aktuelle Zeile (35 Zeilen sind der Schrott beim Bildstart)
cli();
do // Warten auf langen Syncbereich = Bildstart
{
sync=0;
while (ADCH > 20); // warten solange Bilddaten erkannt werden
while (ADCH < 30) sync++; // Länge des Sync-Signal zählen
}while (sync < 40); // größer 40 bedeutet Bildstart
while(zeile--)
{
while (ADCH > 20); // Bilddaten
while (ADCH < 30); // Sync
}
do *bildzeiger=ADCH; while(*bildzeiger++ > 20); // eine schnelle Zeile einlesen
sei(); // (das sind ca. 70 Werte)
for(zeile=0; zeile<64; zeile++) // 64 Pixel senden
{
if (bildspeicher[zeile] > 20)
{
writeChar(bildspeicher[zeile]); // RGB in Pixelfarbe
writeChar(bildspeicher[zeile]);
writeChar(bildspeicher[zeile]);
}
else
{
writeChar(0); // oder Schwarz
writeChar(0);
writeChar(0);
}
}
}
setLEDs(63); // ready
while(!(getBumperLeft() || getBumperRight())); // Neues Bild senden?
}
return(0);
}
Der Versuchsaufbau:
Lesezeichen