MezData-Logo Creative Commons License 315 Lösungen Button :AVR: LED-Zeilen-Animation, Musterfolgen ausgeben

Grundprinzip

MusterAn PB eines ATtiny2313 mit 1MHz Systemtakt soll eine Folge von Mustern nacheinander auf der LED-Zeile ausgegeben werden.

Die LED leuchten bei log. 0 (neg. Logik)

Die Zeit zwischen den Mustern (400 ms) soll mit _delay_ms(400) realisiert werden.

 

 

 

 

Einfache Lösung

Quellcode [muster_einfach.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // Delay-Bibliothek laden 

int main(){         // Hauptprogramm 
  PORTB=0xff;       // alle LED aus 
  DDRB=0xff;        // PB als Ausgang 
  while(1){         // Endlosschleife 
    PORTB=PORTB&~0b111 | 0b011;
    _delay_ms(400);  
    PORTB=PORTB&~0b111 | 0b101;
    _delay_ms(400);
    PORTB=PORTB&~0b111 | 0b110;
    _delay_ms(400);
    PORTB=PORTB&~0b111 | 0b101;
    _delay_ms(400);  
  } 
  return 0; 
}

Lösung mit Array

Hier werden die Muster in ein Array geschrieben und ausgeben

Quellcode [muster_array.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen! 

unsigned char muster[]={0b100,0b010,0b001,0b010};
unsigned char musterzaehler=0;
int main(){         // Hauptprogramm 
  PORTB=0xff;       // alle LED aus 
  DDRB=0xff;        // PB als Ausgang 
  while(1){         // Endlosschleife 
    PORTB=(PORTB|0b111) & ~muster[musterzaehler]; // Muster aus Array
    _delay_ms(400);
    musterzaehler++;
    if(musterzaehler>=sizeof(muster)){ // sizeof gibt die Groesse in Bytes an
      musterzaehler=0;
    }
  } 
  return 0; 
}

Zwischen mehreren Mustern umschalten

Zwei MusterMittels Taste an PD0 soll zwischen zwei Musterfolgen umgeschaltet werden können.

Als Lösung könnten zwei Felder muster1[] und muster2[] angelegt werden und mittels switch-Anweisung wird die Ausgabe umgeschaltet. Eleganter und besser erweiterbar ist die Verwendung eines 2-Dimensionalen Arrays, siehe Quelltext.

Da die Muster unterschiedlich lang sind wird zum Erkennen des Musterendes ein geeignetes Verfahren benötigt:

So wird muster[2][6]={{4,0b100,0b010,0b001,0b010},{5,0b000,0b110,0b011,0b010,0b111}} im Speicher abgelegt:

muster [0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [1][0] [1][1] [1][2] [1][3] [1][4] [1][5]
relative Adresse 0 1 2 3 4 5 6 7 8 9 10 11
Dateneingabe 4 0b100 0b010 0b001 0b010   5 0b000 0b110 0b011 0b010 0b111
gespeichert 4 4 2 1 2 0 5 0 6 3 2 7

Es werden 12 Byte im SRAM belegt weil das Muster im SRAM gespeichert wird

Quellcode [muster_multi.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen! 

#define KEYREADER ~PIND & 0b01111111 // Einlesen, invertieren, maskieren zurecht schieben 
#include "keycheck.inc"              // http://mezdata.de/avr/083_c-entprellen/keycheck.inc 

unsigned char muster[2][6]={{4,0b100,0b010,0b001,0b010},{5,0b000,0b110,0b011,0b010,0b111}};
unsigned char musterzaehler=1,musternummer=0;
int main(){         // Hauptprogramm 
  PORTB=0xff;       // alle LED aus 
  DDRB=0xff;        // PB als Ausgang 
  while(1){         // Endlosschleife 
    keyCheck();
    if(keyEnter&1){ // Taste gedrueckt?
      musterzaehler=0;
      musternummer++;
      if(musternummer>=sizeof(muster)/sizeof(muster[0])) musternummer=0;
    }
    PORTB=(PORTB|0b111) & ~muster[musternummer][musterzaehler]; // Muster aus Array
    _delay_ms(400);
    musterzaehler++;
    if(musterzaehler>muster[musternummer][0]){ // 
      musterzaehler=1;
    }
  } 
  return 0; 
}

Mit PROGMEM Daten im Flash-Programmspeicher speichern

Mit PROGMEM können konstante Daten im Flash-Speicher untergebracht werden, im SRAM wird nichts belegt. Gelesen werden die Daten mit besonderen Funktionen, denen die Speicheradresse der Daten mittels des &-Operators übergeben wird.

Quellcode [muster_progmem.c]
#include <avr/io.h>     // Definitionen laden 
#include <util/delay.h> // CPU Frequenz einstellen! 
#include <avr/pgmspace.h>  // Flashzugriffe laden 

#define KEYREADER ~PIND & 0b01111111 // Einlesen, invertieren, maskieren zurecht schieben 
#include "keycheck.inc"              // http://mezdata.de/avr/083_c-entprellen/keycheck.inc 

unsigned char PROGMEM muster[2][6]={{4,0b100,0b010,0b001,0b010},{5,0b000,0b110,0b011,0b010,0b111}};
unsigned char musterzaehler=1,musternummer=0;
int main(){         // Hauptprogramm 
  PORTB=0xff;       // alle LED aus 
  DDRB=0xff;        // PB als Ausgang 
  while(1){         // Endlosschleife 
    keyCheck();
    if(keyEnter&1){ // Taste gedrueckt?
      musterzaehler=0;
      musternummer++;
      if(musternummer>=sizeof(muster)/sizeof(muster[0])) musternummer=0;
    }
    PORTB=(PORTB|0b111) & ~pgm_read_byte(&muster[musternummer][musterzaehler]); // Muster aus Array
    _delay_ms(400);
    musterzaehler++;
    if(musterzaehler>pgm_read_byte(&muster[musternummer][0])){ // 
      musterzaehler=1;
    }
  } 
  return 0; 
}