Geschickte Beschleunigung von kritischem Code?
Hallo Leute,
wir haben gestern unsere (PAL-)Kamera zum Laufen gebracht und schaffen es nun tatsächlich, ganze 80 Pixel pro Zeile zu lesen (bei aktuell 16MHz). Das ist mehr als doppelt so viel, wie anfangs ging, und das nur mit Code-Optimierungen.
Nun Frage ich mich, aber bin leider mit meinem Latein bzw. C am Ende, wie man das Einlesen noch schneller ablaufen lassen könnte. Inline-Assembler wäre auch eine gute Möglichkeit, aber ich habe einfach zu wenig Ahnung von Assembler in Kombination mit C.
Das Problem ist, dass die Pixel in ein Array/einen Puffer müssen, damit ich alle Pixel nach dem Einlesen auch verarbeiten kann.
Der aktuelle, stark optimierte Code zum Einlesen einer Zeile sieht nun so aus:
(Falls sich jemand fragt, wie wir das Zeilenende erkennen: Wie messen mit dem Oszi nach, wie lang PD0 high ist, und legen das getriggert über das Signal der Kamera, dann sehen wir, ob PD0 länger high ist, als die Zeile dauert. Dann wird der Wert MAX_X angepasst, bis es knapp vor dem Sync endet.)
Code:
#define MAX_X 80
volatile uint8_t global_cam_pic[MAX_X+1];
static inline void read_cam_line()
{
register uint8_t cnt asm("r3");
PORTD |= _BV(PD0);
cnt = MAX_X;
do
{
global_cam_pic[cnt]=ADCH;
}while (cnt--);
PORTD &= ~_BV(PD0);
}
Ich hatte auch schon ein paar Alternativen probiert, z.B. mit Pointern, aber die sind ja gleich alle 16bit und deshalb dauert es dann wesentlich länger.
Eine andere Idee war es, das Array irgendwie an den Anfang des RAMs legen zu können, um dann einfach von MAX_X auf Null runter zu schreiben, damit dann die while-Schleife wieder auf Null prüfen kann. (was mit einem ASM-Befehl geht, anstatt zweien)
Hat noch jemand Optimierungsideen?
Weitere Frage: Da ich den internen ADC benutze: Weiß jemand, wie man ihn gescheit übertakten kann, so dass man noch 8bit hat, und trotzdem >1.6MHz lesen kann?