Hallo Sommer
Aber wenn ich ins Datenblatt schaue, sehe ich das der Atmega32
für eine ADC Wandlung im bestenfall 13µS benötigt.
Darüber habe ich mich auch schon gewundert. Allerdings steht das nur oben im Datenblatt. Bei der Beschreibung des ADCs wird dann immer nur von 13,5 "Taktzyklen" gesprochen. Und die verwendet er auch, ich habe keinen Weg gefunden, um das Samplen nach weniger als 10Bit abzubrechen. Mit der Zyklenrechnerei hab ich's nicht so, aber der Ansatz wäre wohl (Bei 8MHZ ATMega und perscaler /2): 1/4000000Hz Clock*14 Zyklen oder 3,5us. Dann würde ich das 4,7us-hsync mindestens einmal treffen. Wenn man genau hinschaut, sieht man im Beitrag oben im Diagramm die Schwarzschultern und die hsyncs. Allerdings ist das blöderweise spiegelverkehrt, weil ich die Werte rückwärts ausgegeben hatte. Hier ein Code der 256 Werte in Zeile 100 einliest und tabellengerecht an den PC sendet:
Code:
// Liest ab der 100. Zeile 256 Werte am Stück ein
// und sendet die Daten als Tabellenvorlage zum PC.
#include "RP6RobotBaseLib.h"
int main(void)
{
uint8_t pixel[256],*pixelzeiger, *endezeiger;
uint8_t vsync, lines;
initRobotBase();
extIntOFF();
//powerON();
// interne Referenz 2,56V, linksbündig, Kanal ADC4
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, einschalten, prescaller /2
ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
// free running aktivieren, altes Flag löschen
ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
ADCSRA |= (1<<ADSC);
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);
pixelzeiger=&pixel[0];
endezeiger=&pixel[255];
lines=100;
cli();
do // vsync abwarten
{
vsync=0;
while (ADCH > 20);
while (ADCH < 30) vsync++;
}while (vsync < 40);
while (lines) // zeile abwarten
{
while (ADCH > 20);
while (ADCH < 30);
lines--;
}
// 256 Werte am Stück einlesen und als Basis für ein Diagramm senden
do *pixelzeiger=ADCH; while (pixelzeiger++ < endezeiger);
sei();
writeString("------------------------\n\r");
lines=0;
do
{
writeInteger(lines, DEC);
writeString_P("; ");
writeInteger(pixel[lines], DEC);
writeString_P("; ");
writeString("\n\r");
}while (++lines);
while (1)
return(0);
}
Damit schafft man mit einem 8MHz-ATMega "nur" knapp 50 Lesungen pro Zeile, weil sich die Formulierung des Einlesebefehls und damit der Code geändert hat. Im Anhang die Ausgabe des Programms mit einem schwarzen Strich vor der Kameralinse.
Wie gut sich meine Kamera an das BAS-Timeing hält, weiß ich allerdings nicht. Ich sollte mal eine alternative Signalquelle testen (oder Abwarten, bis es einer von euch nachgebaut hat).
Das zeilenweise Einlesen des TV-Signals ist inzwischen "Schnee von gestern". Meine aktuellen Programme lesen das Bild spaltenweise ein, mit je einem h_delay zwischen hsync und Lesen des Pixels pro Zeile. Damit schaffe ich nun, wie im Quellcode der Smilieerkennung zu lesen ist, locker 150 unterschiedliche Lesepositionen innerhalb einer BAS-Zeile.
Gruß
mic
[Edit]
Wenn ich das so lese, stelle ich auch fest, dass da was nicht stimmen kann. Wenn eine Zeile (laut Wiki) 64us dauert, kann ich mit 3,5us pro Lesung niemals auf 50 oder gar 60 Werte/Zeile kommen. Da passt etwas noch nicht, aber trotzdem funktioniert es irgendwie.
Lesezeichen