- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 3 von 3

Thema: video mit avr16 8mhz und winavr-c

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941

    video mit avr16 8mhz und winavr-c

    Anzeige

    E-Bike
    hallo, ich möchte mit dem unteren programm ein videobild (einfache linien) in fbas-format darstellen mit dem AVR16 8mhz. es klappt nicht.
    es hatten schon einige aus diesem forum probiert, es geht aber noch nicht.
    robert, vielleicht weist du weiter. vielleicht könnte man den compare-aufruf mit einem SIGNAL (SIG_OVERFLOW0) ersetzen (64us).
    ich schaffe es nicht.
    mfg pebisoft

    Code:
    // ---------------------------------------------------------------------------
    //PORTC.4 is sync	:1000 ohm to 75 ohm resistor 
    //PORTC.5 is video	:330 ohm to 75 ohm resistor 
    // ---------------------------------------------------------------------------
    
    #include <inttypes.h>
    #include <stdio.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    
    // cycles = 63.625   Also fits for PAL  (8 MHZ) / 1   * 509  no prescaler
    // Frames  1/50 sec  (non overlapped)
    // --------------------------------------------------
    // 		LINES
    // --------------------------------------------------
    //NTSC  PAL		
    //  1	  1		standard sync	normaler Sync (5 uS Puls 0.3V auf 0V) 
    //  ............. black		schwarz
    // 30	 35		
    //  ............. Visible part of Frame	sichtbarer Bereich vertikal 
    //230	274		
    //  ............. black
    //248	295		reverted sync	verkehrter Sync (5 uS Puls 0V auf 0.3V)
    //  .............
    //251	299		standard sync	wieder normal 
    //  .............
    //263	313		Bottom Line -> back to top  1/50 sec 
    // zurück nach oben 
    
    #define lineTime 509	// Timer1 Match Value (8 MHz /1 --> 0.000000125 s/cyc 
    			//  * 509 --->   0,000063625 s 
    			// 8 MHZ ohne PRescale gibt 0.125 uS 
    			// auf 509 raufzählen ergibt ca 64 uS Interrupt
    
    #define ScreenTop  40	// first visible line  
    #define ScreenBot 240	// last visible line    gibt 200 sichtbare Zeilen pro Bild
    
    #define SCREEN_MEM (ScreenBot - ScreenTop) * 8  // dafür brauchen wa 800 Byte 
    
    #define	synONE		0x10	// syn (pin 4)		
    #define	synNUL		0x00	// syn (pin 4)		
    #define	VIDONE		0x20	// VIdeo (pin 5) 
    
    
    
    // --------------------------------------------------
    // TESTING 
    // --------------------------------------------------
    #define BAR_TOP 100	// first BAR line
    #define BAR_BOT 150	// last BAR line
    
    
    
    // --------------------------------------------------
    // Register definition for faster access
    // --------------------------------------------------
    register unsigned char	syncON	asm ("r3");
    register unsigned char	syncOFF	asm ("r4");
    register unsigned char	v1 		asm ("r5");
    register unsigned char	v2 		asm ("r6");
    register unsigned char	v3 		asm ("r7");
    register unsigned char	v4 		asm ("r8");
    register unsigned char	v5 		asm ("r9");
    register unsigned char	v6 		asm ("r10");
    register unsigned char	v7 		asm ("r11");
    register unsigned char	v8 		asm ("r12");
    // --------------------------------------------------
    static int  LineCount;   // Interrupt Linecounter
    static int  LineC; 	       // main()    Linecounter
    // --------------------------------------------------
    unsigned char screen[SCREEN_MEM]; 	// für den TEST überflüssig, egal
    // --------------------------------------------------
    
    
    // ---------------------------------------------------------------------
    // Sync Interrupt every 64 uS   Width ~4.7 uS     40 Cpu-Cycles
    // wird alle 64 uS angesprungen . 
    // der Interrupt muß 5 uS lang den Sync Impuls auf die Leitung zu legen
    // inzwischen zählt er die Bildzeilen und dreht ggf. den Impuls um (Bild Sync)
    // oder schaltet wieder auf Bildanfang
    // diese Zahl 313 kann nicht sinnvoll geändert werden, da ein PAL-Bild nunmal
    // 625 Zeilen hat, ein Halbbild also 313 (komma fünf ist unisant) 
    // alles andere liefert UNFUG
    // ---------------------------------------------------------------------
    SIGNAL (SIG_OUTPUT_COMPARE1A)
    { 
    	PORTC	=syncON;	// Beginn aktueller horz. sync  
    	TCNT0	=0;		// count timer 0 at 1/usec  (eigentlich überflüssig)
    	LineCount++ ;		// nächste Zeile
    	switch (LineCount)
    	{
    	case 295:		// ab hier sync invertiert (Kennz.Bild ende)
    		syncON	= synONE;
    		syncOFF = synNUL;
    		break;
    	case 299:		// wieder zurück auf normal (Kennz.nächstes Bild start)
    		syncON	= synNUL;
    		syncOFF = synONE;
    		break;
    	case 313:		// PAL Zeilen 625 halbe --> 313 
    		LineCount = 1;      // wieder von vorne
    		break;
    	default: 
    		break; 
    	}
    	PORTC = syncOFF;	// Ende aktueller sync pulse
    } 
    
    // ---------------------------------------------------------------------
    // set up the ports and timers  M A I N 
    // ---------------------------------------------------------------------
    int main(void) 
    { 
    //init timer 1 to generate sync 
    	OCR1A	= lineTime;	//One NTSC & PAL line (509) --> 64 uS
    	TCCR1B	= 0x09;		//full speed, no prescale ; clear-on-match
    	TCCR1A= 0x00;		//turn off pwm and oc lines 
    	TIMSK	= 0x10;		//enable interrupt T1 cmp 
    //init port C   Pin 4 u. 5 as Output
    	DDRC	= 0x30;		//video out and switches 
    				// c.4 syn    OUTPUT
    				// c.5 video  OUTPUT	
    				//  der Rest bleibt INPUT
    
    //init timer 0 to 1/uSec	1 MHZ
    	TCCR0	= 2; 		// (eigentlich überflüssig)
    
    //initialize synch constants 
    	syncON	= synNUL;	// initial standard sync anfang  0.3V -> 0V
    	syncOFF= synONE;	// initial standard sync ende    0V -> 0.3V
    	
    	LineCount= 1; 		// anfangswert interruptzähler
    	LineC= 1;		// anfangswert main() zähler
    
    //enable sleep mode 
    	MCUCR	= 0b10000000; 	// nach dem SLEEP geht's bei einem Interrupt 
    				// direkt wieder weiter
    	sei(); 			// enable alle interrupts
    // -----------------------------------------------------------------------
    // 		ONE LINE WORKOUT 
    // -----------------------------------------------------------------------
    	while(1) 	   		// auf immer und ewig
    	{ 
    
    // Sleep, bis ein Interrupt kommt (wir haben nur einen, ev. aufpassen)
    
    asm volatile ("sleep"); 	// wait for Line-Sync Interrupt
    
    
    // START    Black Porch Time (Schwarzschulter & PAL Burst )   ~6 uS   48 Cpu-Cycles
    // der Sync Impuls wurde von der Interrupt routine abgegeben. 
    // jetzt haben wir ~6 uS oder 48 CPU-Zyklen Zeit, entweder die Pixel zu schicken, 
    // oder nix oder auch was anderes zu tun. Auf jeden Fall müssen wir in 50 uS fertig sein
    // und wieder bein SLEEP gelandet sein.
    
    		LineC++;		// nächste Zeile
    		if (LineC >= 313)		// (Halb-)Bildende ? 
    		LineC = 1; 		// dann auf ein neues
    			
    //  TEST: von Zeile 100 bis 150 zeichnen wir ein x-beliebiges Muster
    		if ((LineC < BAR_BOT) && (LineC > BAR_TOP)) 
    		{ 
    			v1 = screen[1];	// get 1st 8 Pixel from screenmemory
    			v2 = screen[1];	// get 2nd 8 Pixel from screenmemory
    			v3 = screen[1];	// get 3rd 8 Pixel from screenmemory
    			v4 = screen[1];	// get 4th 8 Pixel from screenmemory
    			v5 = screen[1];	// get 5th 8 Pixel from screenmemory
    			v6 = screen[1];	// get 6th 8 Pixel from screenmemory
    			v7 = screen[1];	// get 7th 8 Pixel from screenmemory
    			v8 = screen[1];	// get 8th 8 Pixel from screenmemory
    
    // Jetzt sollten seit dem Sleep im Idealfall 6 uS vergangen sein, wir schicken 
    // jetzt die Pixel raus.
    // wie haben ca 50 uS oder ~400 CPU Zyklen zeit, Tupfen auf den Schirm zu zaubern
    // OHne "IF" geht das natürlich viel schneller, is aber nur'n TEST
    
    // PIXEL 1-8  (V1)
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			
    // PIXEL 9-16  (V2)
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			
    // PIXEL 17-24  (V3)
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			PORTC &= ~VIDONE;		// black Pixel
    			
    // PIXEL 25-32  (V4)
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC &= ~VIDONE;		// black		Abwechslung
    			PORTC |= VIDONE;		// white Pixel
    			PORTC &= ~VIDONE;		// black		Abwechslung
    			PORTC |= VIDONE;		// white Pixel
    
    // PIXEL 33-40  (V5)
    			PORTC &= ~VIDONE;		// black		Abwechslung
    			PORTC |= VIDONE;		// white Pixel
    			PORTC &= ~VIDONE;		// black		Abwechslung
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    
    // PIXEL 41-48  (V6)
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    
    // PIXEL 49-56  (V7)
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    
    // PIXEL 57-64  (V8)
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    			PORTC |= VIDONE;		// white Pixel
    // ------------------------------------------------------------------------
    			PORTC &= ~VIDONE;		// Video OFF  that's it
    		}
    		else
    		{
    		// Black lines: Time to do something different
    		// wenn nix zu zeichnen ist, können wir was anderes Tun, es sollt halt
    		// nicht länger als 55 uS dauern, damit wir rechtzeitig wieder beim Sleep sind
    		}
    		
    	} //while   ENDLOS 
    	
    	return(0);    // da kommen wir NIE hin
    } //main

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Hi Pebi. Ich hab ja noch die c-Versionen der Tests, mit denen wir zur Zeit der "Video mit AVR"-Threads herumgewurstelt haben.
    Ich werd' das mal reaktivieren, und da ich zum letzen RNBFRA-Bausatz eh einen Mega16 dazubekommen habe, kann ich mal direkt auf den hinprogrammieren und stell den Code da rein. Gut ?
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo, danke für deine hilfe.
    mfg pebisoft

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress