Hallo
Mit diesem kleinen Update beende ich mal den Ausflug in die Welt der HiRes-Bilder:
Da spalte und i nun 8Bit-Variablen sind, dauert while(i--) nur noch drei Takte (bei i != 0). Um die Auflösung noch weiter zu steigern lese ich nun zweimal dieselbe Spalte, allerdings beim zweiten Durchgang mit zusätzlichen zwei NOPs vor der while(i--)-Schleife.Code:// RP6 sendet eine 48X64-HiRes-Bitmap über die serielle Schnittstelle 5.4.10 mic // Das Bild ist um 90° nach links gedreht, oben links im TV ist unten links im BMP // Es werden nur ca. 3/4 des Bildes erfasst. Um das ganze Bild einlesen zu können, // muss man die Bildgröße des BMP ändern, also den Header anpassen. // Das ist mir im Moment zuviel Aufwand ;) #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, spalte, sync, c, i; // und dürfen NICHT global sein! uint8_t bmp_header_48_64_24bit[54]={ 0x42, 0x4d, 0x36, 0x24, 00, 00, 00, 00, 00, 00, 0x36, 00, 00, 00, 0x28, 00, 00, 00, 0x30, 00, 00, 00, 0x40, 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_48_64_24bit[c]); // Header senden for(spalte=0; spalte<64; spalte+=2) { bildzeiger=&bildspeicher[0]; // Zeiger auf Start des Bildspeicherbereich zeile=30; // aktuelle Zeile (35 Zeilen sind der Schrott beim Bildstart) setLEDs(63-spalte); // working cli(); do {sync=0; while (ADCH > 20); while (ADCH < 30) sync++;}while (sync < 40); while(zeile--) {while (ADCH > 20); while (ADCH < 30);} for(c=0; c<48; c++) { i=spalte; zeile=5; // Zeilensprung für 48 Zeilen while(zeile--) {while (ADCH > 20); while (ADCH < 30);} ADCSRA = (1<<ADATE)|(0<<ADEN)|(1<<ADIF)|(0<<ADSC)|(1<<ADPS0); // ADC stoppen while(i--); // Pixel ansteuern ADCSRA = (1<<ADATE)|(1<<ADEN)|(1<<ADIF)|(1<<ADSC)|(1<<ADPS0); // ADC wieder starten while (!(ADCSRA & (1<<ADIF))); // 26 ADC-Takte warten bis Wandlung fertig *bildzeiger++=ADCH; // das sind ca. 6,5µs ADCSRA |= (1<<ADIF); } zeile=30; setLEDs(62-spalte); // working do {sync=0; while (ADCH > 20); while (ADCH < 30) sync++;}while (sync < 40); while(zeile--) {while (ADCH > 20); while (ADCH < 30);} for(c=0; c<48; c++) { i=spalte; zeile=5; // Zeilensprung für 48 Zeilen while(zeile--) {while (ADCH > 20); while (ADCH < 30);} ADCSRA = (1<<ADATE)|(0<<ADEN)|(1<<ADIF)|(0<<ADSC)|(1<<ADPS0); // ADC stoppen nop(); nop(); // nächste Spalte zwei NOPs später einlesen while(i--); // Pixel ansteuern ADCSRA = (1<<ADATE)|(1<<ADEN)|(1<<ADIF)|(1<<ADSC)|(1<<ADPS0); // ADC wieder starten while (!(ADCSRA & (1<<ADIF))); // 26 ADC-Takte warten bis Wandlung fertig *bildzeiger++=ADCH; // das sind ca. 6,5µs ADCSRA |= (1<<ADIF); } sei(); for(zeile=0; zeile<96; zeile++) // 96 Pixel senden { if (bildspeicher[zeile] > 20) { writeChar((bildspeicher[zeile]-20)*2); // RGB in Pixelfarbe writeChar((bildspeicher[zeile]-20)*2); writeChar((bildspeicher[zeile]-20)*2); } else { writeChar(0); // oder Schwarz writeChar(0); writeChar(0); } } } setLEDs(63); // ready while(!(getBumperLeft() || getBumperRight())); // Neues Bild senden? } return(0); }
Beim Stoppen/Starten des ADC wird das ADCSRA-Register nur noch geschrieben und nicht mehr zuvor eingelesen (= anstelle von &= bzw. |=)
Einer der wenigen Buchstaben mit eindeutiger Orientierung ist das R:
Bild hier
Gruß
mic
[Edit]
64X96:
Bild hier Bild hier Bild hierCode:// RP6 sendet eine 64x96-HiRes-Bitmap über die serielle Schnittstelle 5.4.10 mic #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[150], *bildzeiger; // 150 Byte Bildspeicher sollten reichen uint8_t zeile, spalte, sync, c, i; // und dürfen NICHT global sein! uint8_t bmp_header_64_96_24bit[54]={ 0x42, 0x4d, 0x36, 0x48, 00, 00, 00, 00, 00, 00, 0x36, 00, 00, 00, 0x28, 00, 00, 00, 0x40, 00, 00, 00, 0x60, 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_96_24bit[c]); // Header senden for(spalte=0; spalte<96; spalte+=2) { bildzeiger=&bildspeicher[0]; // Zeiger auf Start des Bildspeicherbereich zeile=30; // aktuelle Zeile (35 Zeilen sind der Schrott beim Bildstart) setLEDs(95-spalte); // working cli(); do {sync=0; while (ADCH > 20); while (ADCH < 30) sync++;}while (sync < 40); while(zeile--) {while (ADCH > 20); while (ADCH < 30);} for(c=0; c<64; c++) { i=spalte; zeile=3; // Zeilensprung für 64 Zeilen while(zeile--) {while (ADCH > 20); while (ADCH < 30);} ADCSRA = (1<<ADATE)|(0<<ADEN)|(1<<ADIF)|(0<<ADSC)|(1<<ADPS0); // ADC stoppen while(i--); // Pixel ansteuern ADCSRA = (1<<ADATE)|(1<<ADEN)|(1<<ADIF)|(1<<ADSC)|(1<<ADPS0); // ADC wieder starten while (!(ADCSRA & (1<<ADIF))); // 26 ADC-Takte warten bis Wandlung fertig *bildzeiger++=ADCH; // das sind ca. 6,5µs ADCSRA |= (1<<ADIF); } zeile=30; setLEDs(94-spalte); // working do {sync=0; while (ADCH > 20); while (ADCH < 30) sync++;}while (sync < 40); while(zeile--) {while (ADCH > 20); while (ADCH < 30);} for(c=0; c<64; c++) { i=spalte; zeile=3; // Zeilensprung für 64 Zeilen while(zeile--) {while (ADCH > 20); while (ADCH < 30);} ADCSRA = (1<<ADATE)|(0<<ADEN)|(1<<ADIF)|(0<<ADSC)|(1<<ADPS0); // ADC stoppen nop(); nop(); // nächste Spalte zwei NOPs später einlesen while(i--); // Pixel ansteuern ADCSRA = (1<<ADATE)|(1<<ADEN)|(1<<ADIF)|(1<<ADSC)|(1<<ADPS0); // ADC wieder starten while (!(ADCSRA & (1<<ADIF))); // 26 ADC-Takte warten bis Wandlung fertig *bildzeiger++=ADCH; // das sind ca. 6,5µs ADCSRA |= (1<<ADIF); } sei(); for(zeile=0; zeile<128; zeile++) // 2*64 Pixel senden { if (bildspeicher[zeile] > 20) { writeChar((bildspeicher[zeile]-20)*2); // RGB in Pixelfarbe writeChar((bildspeicher[zeile]-20)*2); writeChar((bildspeicher[zeile]-20)*2); } else { writeChar(0); // oder Schwarz writeChar(0); writeChar(0); } } } setLEDs(63); // ready while(!(getBumperLeft() || getBumperRight())); // Neues Bild senden? } return(0); }







Zitieren

Lesezeichen