Forum: Compiler & IDEs PC => µC Daten senden um I/0 zu steuern


von whiterose83 (Gast)


Lesenswert?

Hi zusammen

Ich versuche zur zeit gerade über uart daten/werte an den µC zu senden 
um eine LED Matrix von 5x5 anzusteuern. Doch irgend wie bekomme ich das 
einfach nicht gebacken.
Wie schafe ich es die werte für die I/o an den µC zu senden? Einfach 
einen Hex- oder Decimalwert zu senden geht ja leider nicht.

MFG

von holger (Gast)


Lesenswert?

>Einfach einen Hex- oder Decimalwert zu senden geht ja leider nicht.

Wieso nicht ? Das mache ich jeden Tag.

von Hans J. (hjm)


Lesenswert?

Hallo whiterose83,

und so kommen auch die Daten aus dem Internet zu Dir.

Ne Spaß beiseite, wie ist der PC an den µC angeschlossen?

Wenn Du dies mittels COMM-Schnittstelle machst, so ist dies hier was für 
Dich: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

Um Dir nähere Auskunft zu geben, solltest Du Deine Schaltung und die 
genutzten Controller besser beschreiben.

Grüße
Hans-Josef

von whiterose83 (Gast)


Lesenswert?

Dan mach ich irgend was falsch. Den bei mir klappt es einfach nicht.
Hier kurzer auszug aus dem was ich gebastelt habe.
1
while(1)
2
{
3
  while(y < 7)
4
  {
5
    temp=uart_getc_wait();
6
    pic[y] = atoi(temp);
7
    y++;
8
  }
9
10
  while(1)
11
  {
12
    for(y=0; y < 6; y++)
13
    {
14
      PORTB &= ~( 1 << z);
15
      PORTC = pic[y];
16
      wait(10);
17
      PORTC = 0xFF;
18
      PORTB |= ( 1 << z);;
19
      z++;
20
      if(z == 6) 
21
      {
22
      z = 0;
23
      }
24
    }
25
  }
26
27
}

Wen ich jetzt z.B. die ersten 6 Ports einschalten will, also 00111111 
und dafür den Decimalwert 63 senden empfäng er 6 und 3.
Ich versuchte es auch über eine Switch anweisung für jeden der 63 Werte 
ein zeichen einzustellen und beim empfangen eines einzelnen zeichen 
durch die switch anweisung den wert für die Ports zu setzen. Doch auch 
das geht nicht.
Getestet habe ich das senden von Daten über das Dos mit:

echo 63 > com2

oder unter linux mit

echo -n 63 > /dev/ttyS1

Und es geht einfach nicht!

von whiterose83 (Gast)


Angehängte Dateien:

Lesenswert?

Meine Schaltung ist das "myAVR Board LPT" (Im Anhang) und ich versuche 
es über den Com Port.
Das hier über auf der Webseite über UART habe ich gelesen und auch auf 
anderen seiten. Doch nicht wirklich eine antwort gefunden.

von holger (Gast)


Lesenswert?

Du bekommst zwei ASCII Zeichen: '6' (0x36) und '3' (0x33)

Die baust du so zusammen zu einem Bin Wert:

tmp = (('6' - '0') <<4 ) + ('3' - '0');

von holger (Gast)


Lesenswert?

>Die baust du so zusammen zu einem Bin Wert:
>tmp = (('6' - '0') <<4 ) + ('3' - '0');

Ach Quatsch, ist schon so spät ;)
tmp = (('6' - '0') * 10 ) + ('3' - '0');

Gute Nacht !

von Urs K. (Firma: 4you-Studio) (whiterose83)


Lesenswert?

@Holger

Danke, werde das heute gleich mal testen.
Doch wie ist das wen ich dan z.B. nur den wert 1 für 00000001 senden 
möchte, dan funktioniert diese Formel wieder nicht oder?

Das "atoi"in meinem code gehört da nicht hin, das habe ich ausversehen 
mit kopiert weil ich damit versucht habe etwas hin zu bekommen.

von holger (Gast)


Lesenswert?

Wieso nicht ?

echo -n 01 > /dev/ttyS1

Und passt wieder.

von Karl H. (kbuchegg)


Lesenswert?

Urs

Du hast das gleiche Problem, das wir auch umgangssprachlich
im Deutschen haben:
Zu wissen, wann eine Zahl zu Ende ist.

Wenn ich zu dir sage:

  drei     ....

dann kannst du so nicht unmittelbar wissen, ob die Zahl
nun zuende ist oder nicht. Ich könnte ja, nach einer
etwas längeren Pause noch hinzufügen

  ...  und zwanzig

D.h. nur dadurch, dass ich "drei" gesagt habe, weist
du nicht automatisch, welche Zahl ich meine. Erst dadurch,
dass ich dir einen Hinweis gebe, dass die Zahl jetzt zuende
ist, bist du in der Lage auf deinen Zettel
     3
hinzuschreiben und sicher zu gehen, dass das auch korrekt ist.

Nichts anderes ist es ein einem Computer: Du musst dir
irgendwelche Hilfen einfallen lassen, so dass die Gegenstelle
eindeutig erkennen kann, dass hier eine Zahl endet und möglicherweise
eine neue Zahl beginnt.

Wenn du den Datenstrom   65308  (jeweils als Einzelzeichen) hast,
sind das jetzt die Zahlen  6  5  3  0  8, oder sind das
die Zahlen 65 30 8, oder gar 6530 8, oder 65 308 oder ...

Die übliche Vorgehensweise ist es, sich irgendwelche Sonderzeichen
zu definieren, die diese Aufgabe übernehmen. Das könnte zb. ein
simples ',' oder ein ';' sein. Auch das Sonderzeichen 'Return'
ist sehr beliebt, weil zumindest Command Line Benutzer daran gewöhnt
sind, Eingaben mit einem 'Return' (das ist die Taster mit dem
Haken) abzuschliessen.

Der Zeichenstrom  65;308; ist damit eindeutig in die beiden
Zahlen 65 und 308 zerlegbar.
Aber wie kriegt man die Zahlen? Man hat ja nur die einzelnen
Zeichen!
Das ist aber einfach: Aus den einzelnen Ziffern (also '6', '8', etc)
bekommt man die zugehörige Ziffer indem man den ASCII Code für '0'
abzieht

   '6' - '0'  ->  6
   '8' - '0'  ->  8

(aus der UART kriegst du immer nur den ASCII Code heraus. Wenn
du deine Zahl so wie du das gezeigt hast, wegschickst, dann wird
vom PC der Text "65" übertragen, also die ASCII Codes für '6' und
danach der ASCII Code für '5')

Aus den einzelnen Ziffern danach wieder die Zahl zu generieren
ist einfach: Um aus der (bisherigen) Zahl 12 die Zahl 123 zu
machen, werden die 12 mit 10 multipliziert und 3 dazu addiert.
Das geht immer so weiter: Wenn an eine Zahl rechts eine Stelle
'angehängt' werden soll, wird die Zahl einfach mit 10 multipliziert
und die zusätzliche Stelle addiert.

Um also einen eingehenden 'Text', von dem wir wissen, dass es sich
um eine 'Zahl' handelt wieder in eine tatsächliche Zahl zu
überführen, genügt es:
1
    zahl = 0;
2
    zeichen = get_next_character_from_uart();
3
    while( zeichen != ';' ) {    // war es das spezielle Endezeichen ?
4
      zahl = 10 * zahl + ( zeichen - '0' );
5
      zeichen = get_next_character_from_uart();
6
    }

von Urs K. (Firma: 4you-Studio) (whiterose83)


Lesenswert?

Hallo Karlheinz

Wen ich dich nun richtig verstanden habe war das mit dem

   '6' - '0'  ->  6
   '8' - '0'  ->  8

das mir gefehlt hat um es hinzubekommen.
Was ich weis ist das der Wert 68 bei

   PORTC = 68;

nicht das gleiche ist wie wen ich den wert als char, sprich ASCII 
übergebe.
Doch alle rechen die ich versucht hatte gingen ins leere.

Werte das jetzt  zusammen nehmen was ihr mir gesagt hab und das Programm 
nochmals überarbeitne und testen ob es dan klappt.

Auf alle Fälle vielen dank an euch schon mal und hoffen das ich sonst 
noch mals auf euch zurück kommen darf.


MFG

von Urs K. (Firma: 4you-Studio) (whiterose83)


Lesenswert?

So, hat super funktioniert! Dank viel mal!
Jetzt muss ich nur noch auf der Linux Kiste ein Tool schreiben das die 
animation aus einer file liest und an den µC sendet.

Hier mal das Fertige Programm wie ich es jetzt habe, für die, die es 
intressiert und euch damit ihr nun wisst für was ich es gebraucht habe.
Evtl findet jemand auch noch einen Fehler oder Verbesserungsvorschläge!
1
//----------------------------------------------------------------------
2
// Titel     : Ansteuerung von 6x6 LED-Matrix
3
//----------------------------------------------------------------------
4
// Sprache   : C
5
// Datum     : 02.10.2007
6
// Version   : 1.0
7
// Autor     : Kobald Urs
8
//----------------------------------------------------------------------
9
10
#define   F_CPU 3686400L  
11
12
#include  <avr\io.h>    
13
#include  <uart\uart.c>
14
#include  <util\delay.h>
15
16
int main(void)
17
{
18
  DDRB = 0xFF;   
19
  DDRC = 0xFF;   
20
  PORTB = 0xFF;  
21
  PORTC = 0xFF; 
22
23
  uart_init();
24
25
  unsigned char zeichen;
26
  int temp,time,picTime,pic[60][7],x,y,z;
27
28
  while(1)
29
  {
30
    x = 0;
31
    y = 0;
32
    z = 0;
33
    time = 0;
34
35
    zeichen=uart_getc_wait();
36
37
    while(zeichen == '{' && z < 60 && zeichen != '#')
38
    {
39
      while(y < 7)
40
      {
41
        temp = 0;
42
        zeichen=uart_getc_wait();
43
        while(zeichen != ';' && zeichen != '}')
44
        {
45
          temp = 10 * temp + (zeichen - '0');
46
          zeichen=uart_getc_wait();
47
        }
48
        pic[z][y] = temp;
49
        if(z == 6)
50
        {
51
        }
52
        y++;
53
      }
54
      zeichen=uart_getc_wait();
55
      y=0;
56
      z++;
57
    }
58
59
    while(x < z)
60
    {
61
      while(time < pic[x][6])
62
      {
63
        for(y=0; y < 6; y++)
64
        {
65
          PORTB &= ~( 1 << y);
66
          PORTC = pic[x][y];
67
          _delay_ms(1);
68
          PORTC = 0xFF;
69
          PORTB |= ( 1 << y);
70
        }
71
        time++;
72
      }
73
      x++;
74
      time = 0;
75
    }
76
  }
77
  return 0;
78
}

Ein Datenpacket für ein Bild ist

{row1, row2, row3, row4, row5, row6, time}#

Das Zeichen # am Schluss gibt an das die Animation fertig ist und er es 
ausgeben soll!


Und Danke nochmals an dieser Stelle an euch!

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.