Forum: Mikrocontroller und Digitale Elektronik ADC s auslesen, LED Matrix


von matthias asselborn (Gast)


Lesenswert?

Hallo

spiele nun schon lange mit dem Gedanken
von einem 8535 er Mega Atmel alle 8 analog digital Wandler auszulesen
und die Werte dann in einer LED matrix auszugeben

z.b. 1. ADC lesen dann 1. Spalte der 12x8 er Matrix aktivieren
und die Werte wie ein Vu meter über die 12 Leds ausgeben
usw...

habe mir schon mal ein VU Meter programmiert
aber ich komme mit der Multiplex nicht zurecht
zudem habe ich noch nie eine Multiplex in C programmiert
wäre für eure Hilfe echt dankbar

Gruß Matthias

von Profi (Gast)


Lesenswert?

Sollte recht einfach sein.
sag mal, wie Deine LED-Matrix geschaltet ist, hast Du einen Controller
dafuer (z.B. MAX69xx) oder haengen sie direkt am uC?

Willst Du die LEDs linear oder logarithmisch ansteuern?

linear: 8-bit ADC: den gelesenen Wert um 5 nach rechts schieben,
bleiben 3 Bits uebrig, dann diese 3 Bits als Loop-Counter nehmen und
ein Bit um diesen Wert schieben (oder eine 8 Byte lange Lookup-Table 00
01 03 07 0f 1f 3f 7f ff oder 00 01 02 04 08 10 20 40 80), dieses
Bitmuster auf die Led-Spalte ausgeben, fertig.

z.B. ADC=0xc0 um 5 nach rechts =0x06 Lookup: 0x3f ausgebgen, die
unteren 6 LEDs brennen.

gerade faellt mir auf, es gibt ja 9 Moeglichkeiten, also statt um 5
nach rechts lieber durch 28 dividieren und eine 9 Byte lange Table (wie
oben angegeben).

Bei log. wuerde ich direkt eine 256 Byte lange Lookup nehmen.

das wars  Profi

von matthias asselborn (Gast)


Lesenswert?

anbei n code schnipsel von mir

ich progge gerade und probiere
hab die leds direkt am atmel mit transistoren halt noch und
wiederstanden



#include <mega8535.h>
#include <stdio.h>
#define ADC_VREF_TYPE 0x40
#define DEF_ADC_MASK  0x07


inline unsigned int start_adc(unsigned char adc_input)
{
  ADMUX=(adc_input & DEF_ADC_MASK)|ADC_VREF_TYPE;
  ADCSRA|=0x40;
}


inline unsigned int read_adc(unsigned char adc_input)
{
    while ((ADCSRA & 0x10)==0);
    ADCSRA |= 0x10;
    start_adc(adc_input);
    return ADCW;
}


inline void Ausgabe(unsigned int Wert)
{
  if (Wert>=455)
      PORTD = 0x00;
  else if (Wert>=403)
      PORTD = 0x80;
  else if (Wert>=363)
      PORTD = 0xC0;
  else if (Wert>=321)
      PORTD = 0xE0;
  else if (Wert>=286)
      PORTD = 0xF0;
  else if (Wert>=256)
      PORTD = 0xF8;
  else if (Wert>=229)
      PORTD = 0xFC;
  else if (Wert>=204)
      PORTD = 0xFE;
  else
      PORTD = 0xFF;
  if (Wert>=721)
      PORTC = 0xF0;
  else if (Wert>=644)
      PORTC = 0xF8;
  else if (Wert>=572)
      PORTC = 0xFC;
  else if (Wert>=511)
      PORTC = 0xFE;
  else
      PORTC = 0xFF;
}


void main(void)
{

DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
ACSR=0x80;

ADMUX=ADC_VREF_TYPE;
ADCSRA=0x88;
SFIOR&=0xEF;


start_adc(0);

while (1)
      {
        Ausgabe(read_adc(0));
      };
}


und hier unten im hauptprogramm dachte ich mir

ich setze den adc auf 0 ( 1. port ) dann auf 1 usw..
setze zusätzlich die 8 spalten ports nacheinander auf 1
und die ausgebae dazu sollte doch funktionieren oder ?

von matthias asselborn (Gast)


Lesenswert?

müsste doch so klappen oder ?


#include <mega8535.h>
#include <stdio.h>
#define ADC_VREF_TYPE 0x40
#define DEF_ADC_MASK  0x07


inline unsigned int start_adc(unsigned char adc_input)
{
  ADMUX=(adc_input & DEF_ADC_MASK)|ADC_VREF_TYPE;
  ADCSRA|=0x40;
}


inline unsigned int read_adc(unsigned char adc_input)
{
    while ((ADCSRA & 0x10)==0);
    ADCSRA |= 0x10;
    start_adc(adc_input);
    return ADCW;
}


inline void Ausgabe(unsigned int Wert)
{
  if (Wert>=455)
      PORTD = 0x00;
  else if (Wert>=403)
      PORTD = 0x80;
  else if (Wert>=363)
      PORTD = 0xC0;
  else if (Wert>=321)
      PORTD = 0xE0;
  else if (Wert>=286)
      PORTD = 0xF0;
  else if (Wert>=256)
      PORTD = 0xF8;
  else if (Wert>=229)
      PORTD = 0xFC;
  else if (Wert>=204)
      PORTD = 0xFE;
  else
      PORTD = 0xFF;
  if (Wert>=721)
      PORTC = 0xF0;
  else if (Wert>=644)
      PORTC = 0xF8;
  else if (Wert>=572)
      PORTC = 0xFC;
  else if (Wert>=511)
      PORTC = 0xFE;
  else
      PORTC = 0xFF;
}


void main(void)
{

DDRB=0xFF;
DDRC=0xFF;
DDRD=0xFF;
ACSR=0x80;

ADMUX=ADC_VREF_TYPE;
ADCSRA=0x88;
SFIOR&=0xEF;


start_adc(0);
while (1)
      {
        PORTB.0=1;
        Ausgabe(read_adc(0));
      };

start_adc(1);
while (1)
      {
        PORTB.0=0;
        PORTB.1=1;
        Ausgabe(read_adc(1));
      };

start_adc(2);
while (1)
      {
        PORTB.1=0;
        PORTB.2=1;
        Ausgabe(read_adc(2));
      };

start_adc(3);
while (1)
      {
        PORTB.2=0;
        PORTB.3=1;
        Ausgabe(read_adc(3));
      };

start_adc(4);
while (1)
      {
        PORTB.3=0;
        PORTB.4=1;
        Ausgabe(read_adc(4));
      };

start_adc(5);
while (1)
      {
        PORTB.4=0;
        PORTB.5=1;
        Ausgabe(read_adc(5));
      };

start_adc(6);
while (1)
      {
        PORTB.5=0;
        PORTB.6=1;
        Ausgabe(read_adc(6));
      };

start_adc(7);
while (1)
      {
        PORTB.6=0;
        PORTB.7=1;
        Ausgabe(read_adc(7));
      };
}

von matthias asselborn (Gast)


Lesenswert?

ich glaube so darf ich das nicht machen .......
wie wähle ich denn zwischen den adc s ??

grüßles

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.