Forum: Mikrocontroller und Digitale Elektronik hex zahl in binär und dann über einen Pin versenden


von Martin (Gast)


Lesenswert?

Moin leute,

ich habe da ein Problem und weiß leider keine Lösung.
Ich habe einen AtMega16 und programmiere diesen in c++. Ich habe eine 16 
bit hex zahl und möchte diese über einen Pin versenden. Ich habe mir das 
so gedacht, dass ich diese Zahl in eine binär Zahl umwandle und sie dann 
mittels einer Scheleife über den Pin versende. Da dies relativ häufig in 
meinem Programm vorkommt, wollte ich mir eine Funktion dafür basteln.
Jetzt mein Problem: Mir fehlt leider die Erfahrung im Programmieren bzw 
ich bin Neuling. Hätte jemand vielleicht eine Idee wie so etwas aussehen 
könnte?

Danke im Voraus und
Gruß Martin

von Philipp B. (philipp_burch)


Lesenswert?

Hi!

Was hängt denn am anderen Ende des Pins? Das was du vorhast, klingt 
eigentlich ziemlich nach RS232, die Schnittstelle ist recht simpel und 
wird von den meisten AVRs (vom ATmega16 auch) direkt in Hardware 
unterstützt. Guck' mal im Datenblatt nach 'USART', beziehungsweise hier 
im AVR-Tutorial oder im AVR-GCC-Tutorial.

von Peter (Gast)


Lesenswert?

>klingt eigentlich ziemlich nach RS232,

Wohl eher nach SPI, für 16 Bit sendest dann einfach 2 x 8 Bit

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> sie dann mittels einer Scheleife über den Pin versende.
Wie willst du die Datenübertragung synchronisieren?

Am einfachsten ist es, wenn du einen fertigen UART verwendest
oder einen Übernahmetakt mitsendest (wie z.B. bei SPI).

> AtMega16 und programmiere diesen in c++
Mit welchem Compiler?

von Martin (Gast)


Lesenswert?

compiler ist Programmer's Notepad.

ich möchte einen einen DAC (AD7808RZ) ansprechen und hatte mit das so 
gedacht, dass ich einfach zwei pins verbinde (also µC zu DAC) und der 
DAC die h l Signale nacheinander über den jeweiligen Pin einließt. Beim 
DAC ist dafür eben auch nur ein Pin vorgesehen.

unten mal meine Funktion mit der ich den DAC initialisieren wollte. Geht 
leider nicht Fehler meldung ist:

main.c:35: error: lvalue required as left operand of assignment


void DAC_initialisierung(void)
{

  PINB0=0x0060;    //DAC aus Standby holen
  PINB0=0x4110;    //DAC initialisieren
  PINB0=0x4210;
  PINB0=0x4310;
  PINB0=0x4410;
  PINB0=0x4510;
  PINB0=0x4610;
  PINB0=0x4710;
  PINB0=0x4810;    //DAC
}


beste Grüße Martin

von Oliver (Gast)


Lesenswert?

>Ich habe mir das
>so gedacht, dass ich diese Zahl in eine binär Zahl umwandle und sie dann
>mittels einer Scheleife über den Pin versende.

Wie genau soll denn die Kommunikation aussehen? Da muß es ja eine 
Protokollbeschreibung geben: "über einen Pin senden" ist kein genormtes 
Datenformat.

>... und programmiere diesen in c++.

Das glaube ich nicht.

Oliver

von Martin (Gast)


Lesenswert?

Naja ich möchte halt einfach den PINB0 high oder low setzen, was dann 
eine binäre Zahl darstellt.

Dadurch erkennt der DAC was er zu tun hat.

von P. S. (Gast)


Lesenswert?


von Oliver (Gast)


Lesenswert?

Ok, das hattes sich überschnitten. Jetzt wird es etwas klarer.

>unten mal meine Funktion mit der ich den DAC initialisieren wollte. Geht
>leider nicht Fehler meldung ist:

Vielleicht arbeitest du zunächst mal das AVR-gcc-Tutorial (links oben) 
durch. Das erklärt gut, wie das mit I/O's und anderen Dingen im Mega so 
funktioniert.
1
PINB0=0x0060;
geht aus zwei Gründen schief:

PINB0 ist kein Pin, sondern nur die Pin-Nummer. Das steht nichts anderes 
als
1
0=0x0060;
und das verwirrt den Compiler doch etwas.

Und selbst wenn es ein Pin wäre, ginge das nicht, denn der könnte nur 
die Werte 0 oder eins annehmen, aber nicht 0x0060.

Dein AD7808 hat ein SPI-Interface. Das benötigt etwas mehr als nur einen 
Pin. Dafür gibts am Controller eine passede Einheit zur Kommunikation, 
die solltest du nutzen.

Oliver

von Peter (Gast)


Lesenswert?

@Martin
So einfach wird es nicht gehen, woher soll denn dein DAC wissen wenn der 
Pegel LOW ist wieviele 0en dabei übertragne werden.

Wenn du dir mal das Datenblatt für den DAC anschaust wird du ein 
Timingdiagramm finden wo die übertragung abgebildet ist.

Dabei wirst du auch feststellen das du dafür noch ein Clock signal 
brauchst. Du braucht also mindestens 2Pins, ein für die Daten und ein 
für den Takt.

von Karl H. (kbuchegg)


Lesenswert?

Martin schrieb:
> Naja ich möchte halt einfach den PINB0 high oder low setzen, was dann
> eine binäre Zahl darstellt.
>
> Dadurch erkennt der DAC was er zu tun hat.

Du gehst du einiges zu naiv an die Sache ran.
Nur mit einem Pin etwas rumwackeln ist zuwenig.
Der AD7808RZ wird ja ein Datenblatt haben in dem beschrieben ist, wie 
der Chip angesprochen werden möchte. Du musst dich da nach dem Chip 
richten und nicht umgekehrt.

von Martin (Gast)


Lesenswert?

>Naja ich möchte halt einfach den PINB0 high oder low setzen, was dann
>eine binäre Zahl darstellt.

>Dadurch erkennt der DAC was er zu tun hat.

Das stellst du dir so viel zu einfach vor.
Dir fehlt Grundlagenwissen.

von tobi (Gast)


Lesenswert?

Klingt wirklich sehr nach SPI. Einfach 2 mal 8 Bit per SPI rausschicken. 
Das Aufteilen der 16 Bit in 2 mal 8 Bit sollte ja kein Problem sein.
1
uint8_t high = 16_bit_zahl >> 8;
2
uint8_t low = 16_bit_zahl & 0xFF;

In welchem Zahlensystem deine Zahl dargestellt ist sollte dabei egal 
sein.

Wenn du nur Stumpf die Zahl über einen einzelnen Pin raushaun möchtest 
(ohne Synchronisation oder ähnliches) dann geht das ja einfach über eine 
kleine Schleife.
1
// 16 Bit Zahl an PortB Pin1 ausgeben
2
DDRB |= 1 << DDB1;
3
4
uint8_t i;
5
for(i = 0; i < 16; ++i) {
6
    if(16_bit_zahl & 0x8000)
7
        PORTB |= 1 << PB1;
8
    else
9
        PORTB &= ~(1 << PB1);
10
}

Zur Not könntest du auch eine Software-SPI verwenden die direkt 16-Bit 
kann wie z.B.
1
uint16_t rf12_trans(uint16_t wert)
2
{  
3
  uint16_t wert_in = 0;
4
  uint8_t i;
5
6
  cbi(SPI_PORT, NSEL);
7
  cbi(SPI_PORT, SCK);
8
9
  for(i = 0; i < 16; i++) {
10
    if(wert & 0x8000) {
11
      sbi(SPI_PORT, SDI);
12
    } 
13
    else {
14
      cbi(SPI_PORT, SDI);
15
    }
16
    sbi(SPI_PORT, SCK);
17
    wert_in <<= 1;
18
19
    if(SPI_PIN & (1<<SDO)) {
20
      wert_in |= 0x0001;
21
    }
22
    cbi(SPI_PORT, SCK);
23
    wert <<= 1;
24
  }
25
  sbi(SPI_PORT, NSEL);
26
27
  return wert_in;
28
}

von tobi (Gast)


Lesenswert?

Oh da hab ich etwas sehr lange gewartet mit dem Abschicken... mein 
Beitrag oben wird wohl nicht zur Lösung führen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> compiler ist Programmer's Notepad.
Hoppla, das ist doch kein Compiler.
Dieser Editor kann nur einen Compiler aufrufen...

Welchen C-plusplus Compiler verwendest du?

> Dadurch erkennt der DAC was er zu tun hat.
Ja, tut er das? So einen möchte ich auch...

Wie du an den Pins vom DAC herumwackeln solltest, steht im Datenblatt 
beschrieben.

> PINB0=0x4310;
Lies mal den Unterschied ziwchen einem PORT- und einem PIN-Register 
nach. Der Wert im PIN-Register kann nur gelesen werden. Auf einem PORT 
kann abhängig vom Richtungsregister etwas ausgegeben werden. Das sind 
aber wirklich elementarste Grundlagen  :-o

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.