Hallo Leute,
ich versuche mich schon seit einiger zeit damit meinen Atmaga mit dem PC
kommunizieren zu lassen, was jedoch nur Manuell mit HTERM gelingt.
Jetzt soll dies Automatisch geschehen, von meinem Server aus in
regelmäßigen Abständen. Als idee kam mir ein einfaches script per
chronjob auszuführen, was daten vom Atmega speichert.
Zum test habe ich für meinen Atmega ein Programm geschrieben was per
UART daten empfängt, die Daten binär auf 8 LEDs anzeigt (zur kontrolle)
und die Daten wieder zurück zum PC sendet.
Nun zum Script...
1 | #Name: Write_and_Read
|
2 | #Author: Schmaddy
|
3 | #Version Alpha-zu-Testzwecken Aug. 2011
|
4 |
|
5 | #Befehle Atmega:
|
6 | #0xA1 = Naechsten 8bit auf PA ausgeben
|
7 | #0xB0 = Sende PortB
|
8 | #0xF1 = Naechsten 8bit in Register1 schreiben
|
9 | #unbekannt ausgabe auf 8bit led
|
10 |
|
11 | use Sys::Syslog;
|
12 |
|
13 | $port ="/dev/ttyS0"; # Port festlegen
|
14 | system "stty 1200 ixon < $port"; # Baudrate festlegen mit stopbit
|
15 |
|
16 | #Senden
|
17 | open(COM, "+>$port") or die "Kann $port nicht oeffnen."; # geraetedatei oeffnen
|
18 | printf(COM '0xFF'); # Geraet senden/schreiben
|
19 | close(COM); # Verbindeung schliessen
|
20 |
|
21 | #Lesen
|
22 | sysopen(COM, "$port", O_RDONLY) or die "Kann nicht Lesen";
|
23 | $bytes=sysread(COM, $buffer, 1);
|
24 | print $buffer, "\n" if $bytes ==1;
|
25 | close(COM);
|
Das script sendet Daten zu meinem Atmega, was ich an den Kontroll LEDs
feststellen kann.
Aber es empfängt nichts.
Ausgeführt wird es ohne fehlermeldung, aber das script hat eine
unendliche laufzeit. wenn ich es ohne den #Lesen abschnitt ausführe,
sendet es und das script ist beendet. Aber mit beendet es sich nicht.
Ich denke das
1 | $bytes=sysread(COM, $buffer, 1);
|
irgendwie nicht richtig ist, kann das sein?
Ich habe um fehler am Atmega auszuschließen den code mal gekürzt...
1 | // Created: 05.08.2011 20:56:36
|
2 | //****************************************************************
|
3 | //* AVR Communication *
|
4 | //* (C) [] *
|
5 | //* Für Atmega16 *
|
6 | //* *
|
7 | //* Empfängt daten, zeigt sie auf PORTD an, und sendet sie *
|
8 | //* zurück an Versender. *
|
9 | //* *
|
10 | //* *
|
11 | //* *
|
12 | //* *
|
13 | //* *
|
14 | //* *
|
15 | //****************************************************************
|
16 |
|
17 | .include "m16def.inc"
|
18 |
|
19 | .def temp = R16 //Temponäre Daten
|
20 | .def zeichen = r17 //Daten der Zeichen
|
21 |
|
22 | .equ F_CPU = 1000000 // Systemtakt in Hz
|
23 | .equ BAUD = 1200 // Baudrate
|
24 |
|
25 | // Berechnungen
|
26 | .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) // Runden
|
27 | .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
28 | .equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
|
29 |
|
30 | .if ((BAUD_ERROR>10) || (BAUD_ERROR<-10)) // max. +/-10 Promille Fehler
|
31 | .error "Fehler Baudrate grösser 1 Prozent!"
|
32 | .endif
|
33 |
|
34 | // Stackpointer initialisieren
|
35 |
|
36 | ldi temp, HIGH(RAMEND)
|
37 | out SPH, temp
|
38 | ldi temp, LOW(RAMEND)
|
39 | out SPL, temp
|
40 |
|
41 | // Port D = Ausgang
|
42 |
|
43 | ldi temp, 0xFF
|
44 | out DDRD, temp
|
45 |
|
46 | // Baudrate einstellen
|
47 |
|
48 | ldi temp, HIGH(UBRR_VAL)
|
49 | out UBRRH, temp
|
50 | ldi temp, LOW(UBRR_VAL)
|
51 | out UBRRL, temp
|
52 |
|
53 | // Frame-Format: 8 Bit
|
54 |
|
55 | ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
|
56 | out UCSRC, temp
|
57 |
|
58 | // Uart Einschalten
|
59 | sbi UCSRB, RXEN // RX (Empfang) aktivieren
|
60 | sbi UCSRB,TXEN // TX (Senden) aktivieren
|
61 |
|
62 | // Empfangsschleife
|
63 | receive_loop:
|
64 | sbis UCSRA, RXC // warten bis ein Byte angekommen ist
|
65 | rjmp receive_loop
|
66 | in temp, UDR // empfangenes Byte nach temp kopieren
|
67 | out PORTD, temp // und an Port D ausgeben.
|
68 | rcall seriell_out // Daten zurückschicken
|
69 | rjmp receive_loop // zurück zum Hauptprogramm
|
70 |
|
71 | // Senden
|
72 | seriell_out:
|
73 | sbis UCSRA,UDRE // Warten bis UDR für das nächste
|
74 | // Byte bereit ist
|
75 | rjmp seriell_out
|
76 | out UDR, temp
|
77 | ret // zurück zum Hauptprogramm
|
78 |
|
79 | // Pause zum Synchronisieren des Empfängers
|
80 |
|
81 | // Sub
|
82 | sync:
|
83 | ldi r16,0
|
84 | sync_1:
|
85 | ldi r17,0
|
86 | sync_loop:
|
87 | dec r17
|
88 | brne sync_loop
|
89 | dec r16
|
90 | brne sync_1
|
91 | ret
|
92 |
|
93 | // Ende
|
Mit dem Manuellem auslesem an meinem Windows PC via HTERM habe ich keine
Probleme. Ich sende beispielsweise 0b01010101 an den atmega und die leds
zeigen 01010101 an und auf der konsole empfange ich ebenfalls wieder
0b01010101. Sodass ich den fehler am Perlscript des Servers vermute.
Der Server läuft unter Fedora 14
Kann mir jemand beim Perl script einen guten tipp geben?
Danke und Gruß schmaddy