- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 11 bis 20 von 24

Thema: Ping Pong umprogrammieren?

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #13
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Inzwischen kann ich das Teil erfolgreich flashen:

    Bild hier  
    http://www.youtube.com/watch?v=MRRoa1hpnMQ
    http://www.youtube.com/watch?v=JpfsYIkHjlw


    Da wird sich meine Angetraute sicher sehr freuen, wenn ich ihr fünf so Dinger an den Christbaum hänge ;)

    Dieses Beispielprogramm von der elo-Webseite habe ich ausgewählt, weil es zeigt, wie einfach die Daten an die LCD-Matrix ausgegeben werden. Und weil es einen brauchbaren Font mitbringt:

    Code:
    /*
     * laufschrift.c
     *
     * Ein einfache "Laufschrift" auf dem Ping-Pong Board.
     *
     * Kompilierbar mittels AVR Studio 4 oder WinAVR
     *
     * Der Sourcecode und das Hexfile dürfen frei verwendet werden.
     * Nutzung erfolgt auf eigene Gefahr.
     *
     * Ver.     Date         Author           Comments
     * -------  ----------   --------------   ------------------------------
     * 1.00	    07.11.2009   Sascha Bader     initial
     */
    
    
    /* -----------------------------------------
     * Defines (Präprozessor Makros)
     * -----------------------------------------*/
    
    #define F_CPU 8000000UL	                       /* CPU Takt (für delay-Routine) */
    
    #define WIDTH 12                               /* Breite des Displays */
    #define HEIGHT 10                              /* Höhe des Displays */
    #define FONTWIDTH 8                            /* Breite des Zeichensatzes */
    #define FONTHEIGHT 10                          /* Höhe des Zeichensatzes */
    
    #define GetPixel(x,y) leds[y]&(1<<x)           /* Makro: Ein "Pixel" auslesen */
    #define SetPixel(x,y) leds[y]|=1<<x            /* Makro: Ein "Pixel" setzen */
    #define ClearPixel(x,y) leds[y]&=~(1<<x)       /* Makro: Ein "Pixel" löschen */
    
    
    /* -----------------------------------------
     * Includes
     * -----------------------------------------*/
    #include <inttypes.h>		                   /* Definition der Datentypen uint8_t usw. */
    #include <avr/interrupt.h>                     /* Interruptbehandlungsroutinen (für Timerinterrupt) */
    #include <util/delay.h>		                   /* Definition der Verzögerungsfunktionen (_delay_ms) */
    #include <avr/pgmspace.h>                      /* Hilfsfunktionen um Daten aus dem Flash zu lesen */
    #include "font.h"                              /* Definition des Zeichensatzes */
    
    
    /* -----------------------------------------
     * Globale Variablen
     * -----------------------------------------*/
    uint16_t leds[WIDTH];                          /* Inhalt der LED-Matrix */
    prog_uint8_t * fnt = (prog_uint8_t *) font;    /* Zeiger auf den Zeichensatz im Flash */
    volatile uint8_t col = 0;                      /* Aktuelle Spalte (für Interruptroutine)
                                                      "volatile", da durch Interrupt verändert */
    
    /* -----------------------------------------
     * Text der Laufschrift (Globele Variable)
     * -----------------------------------------*/
    prog_uint8_t text[] =
    " Frohes Fest und guten Rutsch :)\
     ~";  /* Ende-Kennzeichen (nicht vergessen) */
    
    /* -----------------------------------------
     * Prototypen der Funktionen
     * -----------------------------------------*/
    void PrintScrollColumn(uint8_t c, int pixelx, int y);
    void ScrollLeft(void);
    
    /* -------------------------------------------------------------------------
     * Main Funktion
     *
     * Initialisiert den Timer Interrupt und
     * behandelt die Laufschrift
     * -------------------------------------------------------------------------*/
    int main(void)
    {
    	uint8_t * tpos;
    	uint8_t softx;
    
    	cli();                              // Interrupts sperren (damit keiner dazwischenfunkt)
    
    	/*---------------------------------------------------
    	 * Ports konfigurieren (Ein-/Ausgänge)
    	 *---------------------------------------------------*/
    	DDRC = 0x0f;   // ( 0x0f PORTC als AD-Eingang)
    	DDRB = 0xff;   //  Portb = Output
    	DDRD = 0xff;   //  Portd = Output
    
    	/*---------------------------------------------------------------------------
    	 * 8-Bit Timer TCCR0 für das Multiplexing der LEDs initialisieren
    	 * Es wird ca. alle 2 Mikrosekunden ein Overflow0 Interrupt ausgelöst
    	 * Berechnung: T = Vorteiler * Wertebereich Zähler / Taktfreuenz
    	 * = 64 * 256 / ( 8000000 Hz ) = 2,048 ms
    	 *---------------------------------------------------------------------------*/
    	TCCR0 |= (1<<CS01) | (1<<CS00);		// 8-bit Timer mit 1/64 Vorteiler
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    
    	sei();							    // Interrupts erlauben
    
    	/*---------------------------------------------------
    	 * Hauptschleife (Laufschrift erzeugen)
    	 *---------------------------------------------------*/
    	while(1)                                              // Endlosschleife
    	{
    		for (tpos=text;pgm_read_byte(tpos)!='~';tpos++)   // Aktuelles Zeichen lesen
    		{
    			  for (softx=0;softx<FONTWIDTH;softx++)       // Pixel des Zeichens abarbeiten
    			  {
    				ScrollLeft();                             // Platz schaffen und Zeilen nach links schieben
    				PrintScrollColumn(pgm_read_byte(tpos),softx,0);  // Ganz rechts eine Spalte des Zeichens ausgeben
    				_delay_ms(35);                            // Ein bischen warten damit es nicht zu schnell wird
    			  }
    		}
    	}
    	return 0;
    }
    
    /* -------------------------------------------------------------------------
     * Funktion PrintScrollColumn
     *
     * Aktualisiert die Spalte ganz rechts mit
     * einem 1 "Pixel" breitem Ausschnitt des
     * Lauftextes.
     *
     * \param c       Auszugebendes Zeichen
     * \param pixelx  Auszugebende Spalte des Zeichens
     * \param y       Vertikale Vverschiebnung
     * -------------------------------------------------------------------------*/
    void PrintScrollColumn(uint8_t c, int pixelx, int y)
    {
      unsigned char fontbyte = 0;
      uint8_t pixelpos;
      uint8_t fonty;
      uint8_t mask;
    
      pixelpos = pixelx & 0x07;                  /* Auf 8 Pixel pro Zeichen limitieren */
    
      for (fonty=0;fonty<FONTHEIGHT;fonty++)
      {
    	fontbyte = pgm_read_byte_near(fnt+c*FONTHEIGHT+fonty);  /* Ein Byte (Zeile) des aktuellen Zeichens lesen */
    
        mask = 1<<pixelpos;                      /* Maske auf die gewünschte Spalte zurechtschieben */
        if ((fontbyte & mask) != 0)              /* Prüfen ob das Bit in der Spalte des Zeichens gesetzt ist */
        {
            leds[WIDTH-1]|=1<<fonty;             /* Setzen eines Pixels im Display ganz rechts */
        }
        else
        {
            leds[WIDTH-1]&=~(1<<fonty);          /* Löschen eines Pixels im Display ganz rechts */
        }
      }
    }
    
    /* -------------------------------------------------------------------------
     * Funktion ScrollLeft
     *
     * Verschiebt den Inhalt LED-Matrix um eine Spalte nach links.
     * Die erste Spalte tritt dabei an die Position der letzten Spalte.
     * -------------------------------------------------------------------------*/
    void ScrollLeft(void)
    {
      uint8_t xcol;                           /* Spaltenzähler */
      uint16_t first;                         /* Zwischenspeicher der ersten Spalte */
    
      first = leds[0];                        /* Erste Spalte sichern */
      for (xcol=0;xcol<WIDTH-1;xcol++)
      {
    	  leds[xcol]=leds[xcol+1];            /* Spalten nach links verschieben */
      }
      leds[WIDTH-1] = first;                  /* Erste Spalte an letzte Spalte kopieren */
    }
    
    /* -------------------------------------------------------------------------
     * Interrupt Routine
     *
     * Gibt nacheinander alle Spalten mit LED-Daten aus.
     * Dazu wird mittels der Schieberegister die aktuelle Spalte
     * ausgewählt und dann das Bitmuster derselben auf die Ports
     * gegeben.
     * Beim nächsten Interrupt ist dann die nächste Spalte dran.
     * -------------------------------------------------------------------------*/
    // interrupt routine
    SIGNAL (SIG_OVERFLOW0)
    {
    	uint16_t ledval;
    	uint8_t portcout;
    	uint8_t portdout;
    
    	cli();							/* Interrupts verbieten */
    
    	/*--------------------------------------------------
    	 * Aktuelle Spalte ermitteln
    	 *--------------------------------------------------*/
    	col++;
    	if (col == 12)
    	{
    		col = 0;
    	}
    
    	/*--------------------------------------------------
    	 * Ports initialisieren
    	 *--------------------------------------------------*/
    	PORTD = 0;
    	PORTB = 0;
    	PORTC = 0;
    
    	/*---------------------------------------------------
    	 * Eine einzelne 0 durch die Schiebergister schieben
    	 *---------------------------------------------------*/
    	if ( col == 0 )
    	{
    		PORTB &= ~(1 << 4);        /* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    		                           /* Diese 0 geht auf die Reise durch die Schieberegister */
    	}
    	else
    	{
    		PORTB |= (1 << 4);         /* Danach Einsen hinterherschicken (PB4 = 1) */
    	}
    
    	/*---------------------------------------------------
    	 * Impulse für die Schieberegister generieren
    	 *---------------------------------------------------*/
    	PORTB |= (1 << 3);             /* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);            /* PB3 = 0 (!cl) */
    
    	PORTB |= (1 << 2);             /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);            /* PB2 = 0 (!str) */
    
    	/*---------------------------------------------------
    	 * Daten der Spalte holen und auf die Ports verteilen
    	 *---------------------------------------------------*/
    	ledval = leds[col];
    	portdout = ledval & 0xff;      /* low byte */
    	portcout = portdout & 0x0f;    /* low nibble */
    	portdout = portdout & 0xf0;    /* high nibble */
    
    	PORTD = portdout & 0xff;
    	PORTC = portcout & 0xff;
    	PORTB = (ledval >> 8) & 0x03;  /* high byte */
    
    	sei();						   /* Interrupts wieder erlauben */
    }
    (Code von http://www.elo-web.de/elo/mikrocontr...ng/laufschrift)

    Gruß

    mic

    [Edit]
    Bild hier  
    http://www.youtube.com/watch?v=tsTk4Un89uA

    Neuer Bildspeicher mit nur 15 Bytes und set()/unset()-Funktionen. Echt ein nettes Spielzeug:

    Code:
    #define F_CPU 8000000UL
    
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    uint8_t bildspeicher[15];
    volatile uint8_t col = 0;
    uint8_t x, y;
    
    void set(uint8_t zeile, uint8_t spalte)
    {
    	uint8_t temp;
    
    	if(zeile < 8)
    	   bildspeicher[spalte] |= (1 << zeile);
    	else
    	{
    		if(spalte<4) temp = 12;
    	   	else if(spalte<8) temp = 13;
    	      	else temp = 14;
    		if(zeile & 1) bildspeicher[temp] |= (1<<((spalte%4)*2+1));  // Zeile 10
    		   else bildspeicher[temp] |= (1<<(spalte%4)*2); // Zeile 9
    	}
    }
    
    void unset(uint8_t zeile, uint8_t spalte)
    {
    	uint8_t temp;
    
    	if(zeile < 8)
    	   bildspeicher[spalte] &= ~(1 << zeile);
    	else
    	{
    		if(spalte<4) temp = 12;
    	   	else if(spalte<8) temp = 13;
    	      	else temp = 14;
    		if(zeile & 1) bildspeicher[temp] &= ~(1<<((spalte%4)*2+1));  // Zeile 10
    		   else bildspeicher[temp] &= ~(1<<(spalte%4)*2); // Zeile 9
    	}
    }
    
    int main(void)
    {
    	cli();
    
    	DDRC = 0x0f;
    	DDRB = 0xff;
    	DDRD = 0xff;
    
    	/*---------------------------------------------------------------------------
    	 * 8-Bit Timer TCCR0 für das Multiplexing der LEDs initialisieren
    	 * Es wird ca. alle 2 Mikrosekunden ein Overflow0 Interrupt ausgelöst
    	 * Berechnung: T = Vorteiler * Wertebereich Zähler / Taktfreuenz
    	 * = 64 * 256 / ( 8000000 Hz ) = 2,048 ms
    	 *---------------------------------------------------------------------------*/
    	TCCR0 |= (1<<CS01) | (1<<CS00);		// 8-bit Timer mit 1/64 Vorteiler
    	TIFR |= (1<<TOV0); 					// Clear overflow flag (TOV0)
    	TIMSK |= (1<<TOIE0); 				// timer0 will create overflow interrupt
    
    	sei();							    // Interrupts erlauben
    
    	while(1)
    	{
          for(x=0; x<15; x++) bildspeicher[x] = 0b10101010;
          _delay_ms(500);
          for(x=0; x<15; x++) bildspeicher[x] = 255; // alle LEDs an
          _delay_ms(1000);
          for(x=0; x<15; x++) bildspeicher[x] = 0; // alle LEDs aus
          _delay_ms(500);
    
    	   for(x=0; x<12; x++)
    	      for(y=0; y<10; y++)
    	      {
    	         set(y, x);
    	         _delay_ms(25);
    			}
          _delay_ms(1000);
    
    	   for(y=10; y; y--)
    			for(x=12; x; x--)
    	      {
    	         unset(y-1, x-1);
    	         _delay_ms(25);
    			}
          _delay_ms(1000);
    	}
    	return (0);
    }
    
    /* -------------------------------------------------------------------------
     * Interrupt Routine
     *
     * Gibt nacheinander alle Spalten mit LED-Daten aus.
     * Dazu wird mittels der Schieberegister die aktuelle Spalte
     * ausgewählt und dann das Bitmuster derselben auf die Ports
     * gegeben.
     * Beim nächsten Interrupt ist dann die nächste Spalte dran.
     * -------------------------------------------------------------------------*/
    // interrupt routine
    SIGNAL (SIG_OVERFLOW0)
    {
    	uint16_t ledval;
    	uint8_t portcout;
    	uint8_t portdout;
    
    	cli();							/* Interrupts verbieten */
    
    	/*--------------------------------------------------
    	 * Aktuelle Spalte ermitteln
    	 *--------------------------------------------------*/
    	col++;
    	if (col == 12)
    	{
    		col = 0;
    	}
    
    	/*--------------------------------------------------
    	 * Ports initialisieren
    	 *--------------------------------------------------*/
    	PORTD = 0;
    	PORTB = 0;
    	PORTC = 0;
    
    	/*---------------------------------------------------
    	 * Eine einzelne 0 durch die Schiebergister schieben
    	 *---------------------------------------------------*/
    	if ( col == 0 )
    	{
    		PORTB &= ~(1 << 4);        /* Bei der ersten Spalte eine 0 ausgeben (PB4 = 0) */
    		                           /* Diese 0 geht auf die Reise durch die Schieberegister */
    	}
    	else
    	{
    		PORTB |= (1 << 4);         /* Danach Einsen hinterherschicken (PB4 = 1) */
    	}
    
    	/*---------------------------------------------------
    	 * Impulse für die Schieberegister generieren
    	 *---------------------------------------------------*/
    	PORTB |= (1 << 3);             /* PB3 = 1 (cl) */
    	PORTB &= ~(1 << 3);            /* PB3 = 0 (!cl) */
    
    	PORTB |= (1 << 2);             /* PB2 = 1 (str) */
    	PORTB &= ~(1 << 2);            /* PB2 = 0 (!str) */
    
    	/*---------------------------------------------------
    	 * Daten der Spalte holen und auf die Ports verteilen
    	 *---------------------------------------------------*/
    	ledval = bildspeicher[col];
    	portdout = ledval & 0xff;      /* low byte */
    	portcout = portdout & 0x0f;    /* low nibble */
    	portdout = portdout & 0xf0;    /* high nibble */
    
    	PORTD = portdout & 0xff;
    	PORTC = portcout & 0xff;
    	if(col<4) ledval=bildspeicher[12];
    		else if(col<8) ledval=bildspeicher[13];
    			else ledval=bildspeicher[14];
    	PORTB = (ledval >> (col%4)*2) & 0x03;  /* high byte */
    
    	sei();						   /* Interrupts wieder erlauben */
    }
    Angehängte Dateien Angehängte Dateien
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

Stichworte

Berechtigungen

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

LiFePO4 Speicher Test