PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RF-ID (Daten in den Atmega 8 bringen)



papuadive
20.04.2013, 12:24
Hallo,
brauche wieder einmal eure Hilfe...
Habe mir RFID-Lesemodul (ID-12) und einige Tags besorgt. Nun möchte ich aber die Daten in einen µP (Atmega 8L) bringen.
1. Gibt schon eine fertige lib
2. Wie sieht die entsprechende Verdrahtung ID-12 --> µP aus?
3. Kann ich direkt vom Modul auf den Computer (RS 232) fahren und über das Hyper-Terminal den Wert des Tags auslesen.

Stehe diesbezüglich komplett auf der Leitung

Danke im Voraus für die Hilfe
Papua

PS: Ich programmiere im AVR-Studio in C!

Kampi
20.04.2013, 14:53
Hey,

wofür brauchst du eine fertige Lib?
Du weißt, dass der Reader 16 Byte Daten ausgibt (ich habe bereits einen Reader an mein Raspberry Pi angeschlossen....zwar nicht den selben aber er funktioniert genau gleich).
Das heißt du überprüfst den UART ob ein 0x02 (Übertragungsstart) am Bus liegt. Wenn ja empfängst du das, verwirfst es und empfängst die weiteren 15 Bytes. Diese speicherst du in einem String, schmeißt die letzten drei Bytes raus (Ende der Übertragung + CR + LF). Und dann musst du nur noch den String auslesen, da du ja weißt das die nächsten 10 Bytes nach dem Übertragungsanfang die Daten sind.

-> Datenblatt: https://www.sparkfun.com/datasheets/Sensors/ID-12-Datasheet.pdf

Laut Datenblatt kann der 5V TTL und RS232 ausgeben. 5V TTL kannst du direkt an den µC klemmen und für RS232 brauchst du einen Pegelwandler.
Wenn du einen Pegelwandler hast, kannst du das Modul natürlich auch am PC auslesen.

PS: Eine Frage noch....wieso hast du dir dieses "unfertige" Modul gekauft? Bei Watterott gibt es für kleines Geld ein fertiges:

http://www.watterott.com/de/Electronic-brick-125Khz-RFID-Card-Reader

Dieses Modul verwende ich auch und ich bin sehr zufrieden damit :)

papuadive
20.04.2013, 19:50
Hallo Daniel, danke für die Info!
Die Frage ist, was kann dein fertiges Modul mehr. Bei meinem ist ja auch alles dabei. Muss nur noch auch eine Lochrasterplatine stecken und das ist es, oder?
Aber zu meiner eigentlichen Frage: wie verbinde ich es mit meinem µP (Mega8)? Brauche das Modul nur auslesen --> eine Richtung, oder?

Modul ID-12 (Pin 9) -> Mega8 (Pin 2 [RXD])
Pin 1 (GND)
Pin 11 (+5V)

und das ist es, oder???


Danke

Kampi
20.04.2013, 19:59
Naja du brauchst auch noch eine Antenne ;)
Mag sein, dass das Modul für 30$ gut ist (habe mich nicht so intensiv mit ihm beschäftigt). Das was ich benutze ist halt eine "Ich bekomme es und kann direkt loslegen"-Lösung :)
Genau, da das Modul nur ein Lesegerät ist, reicht es wenn du Tx vom Modul mit Rx von deiner MCU verbindest. Wenn du das Modul und die MCU mit 5V betreibst geht das ohne weiteres.

Edit:
Gerade gesehen, dass das Modul anscheinend schon komplett fertig und integriert ist...ok das erklärt den Preis...nicht so klobig wie meines :D
Aber ich sehe gerade, dass es ein 2mm Raster hat :(

papuadive
20.04.2013, 20:25
Bin gerade dabei einen Pegelwandler zwischen Modul und µP installieren.
Anschließend geht's via RS232/USB in den PC. Mal sehen ob's klappt.
Hab keine Ahnung was der ins Hyperterm. schreibt
Papua

Kampi
20.04.2013, 20:47
Hey,

bei meinem Modul war es so ein Datensatz, wie du ihn unter "Datensatz" siehst:

http://img22.imageshack.us/img22/4277/rfidausgabe.jpg

Da dein Modul von der Datenausgabe gleich aussieht, wird er bei dir auch in etwa so aussehen.

papuadive
20.04.2013, 20:59
krieg momentan überhaupt nichts heraus. keine ahnung woran es liegt.
momentan hab ich (ausser die versorgungsspg.) nur den pin 9 (ASCII-Output) mit den Pegelwandler ST232CN Pin 11 verbunden.
und vom Pegelwandler via RS232/USB-Schnittstelle in den PC
benutze win 7 --> Hyperterm Vers. 7.0
geht aber trotzdem nicht
mal sehen ...

Kampi
20.04.2013, 21:10
Hast du auch Tx und Rx gekreuzt, also in der Strecke ST232 -> RS232/USB?

papuadive
21.04.2013, 08:39
hallo,
habe auch den versuch des kreuzens gemacht, geht aber nicht
ich glaube es liegt eher an der hyperterm. einstellung...

Kampi
21.04.2013, 08:55
Zieh mal den Reader ab und versuch herauszufinden wo das Problem liegt, indem du erst Rx und Tx vom RS232/USB Wandler brückst und danach vom ST232 und dann steckst du den Reader wieder dran.

papuadive
21.04.2013, 09:39
ich glaube mein problem ist momentan die hyperterm. konfiguration...
ich hab mit diesem ding noch nie gearbeitet...
ich weiss nämlich nicht einmal, ob ic232 über den adapter seriell/usb-wandler die daten auf den pc kommen.
das größte problem ist die konfiguration dieses hyperterm --> welchen button muss ich drücken --> welche auswahl treffen usw.
bin noch beim googlen

Kampi
21.04.2013, 09:52
Nimm TeraTerm :)
Hyperterminal ist einfach nur grausig....
TeraTerm öffnen, Datei, Neue Verbindung, auswählen, dann Einstellungen, serieller Port und dort die Einstellungen tätigen.

papuadive
21.04.2013, 10:18
Rx und Tx vom RS232/USB gebrückt --> geht nix...

- - - Aktualisiert - - -

so tera term VT ist installiert
die einstellungen:
datei --> neue verbindung --> seriell Com 13: usb/seriell ...

anschließend:

port: com 13 --> auch im gerätemanager ist com seriell/Usb auf 13 konfig
baudrate: 9600
data:8 bit
parity: none
stop: 1
flow control: none

habe anschließend beim adapter Rxd und TxD gebrückt --> nichts zu sehen im tera term window

- - - Aktualisiert - - -

neue situation: wenn ich den tag über das lesemodul ziehe, springt der curser ca. 10 sprünge nach rechts im tera term fenster weiter ohne etwas anzuzeigen, aber immerhin es passiert was ;-)

Kampi
21.04.2013, 11:09
Sicher das die Baudrate stimmt?
Das klingt mir nach einer falschen Baudrate. Hast du auch GND vom USB/RS232 Wandler, ST232 und dem Modul verbunden?

papuadive
21.04.2013, 12:28
neue situation, wenn ich mit dem tag über den reader fahre, gibt es im tera term fenster eine reaktion nämlich der curser springt ca. 10 stellen nach rechts, ohne etwas anzuzeigen

papuadive
21.04.2013, 16:58
habe die Baudraten von oben nach unten durchprobiert, leider ohne erfolg, machmal sind komische zeichen dabei...
die massen sind untereinander verbunden

Kampi
21.04.2013, 17:24
Entfern mal das Modul und guck das du die UART Kommunikation erst mal ohne Modul zum laufen bekommst (Rx und Tx brücken).

papuadive
21.04.2013, 17:32
nachdem ich die brücke RX und TX gelegt habe, kann ich über's Terminal abc usw. eingeben --> anschließend habe ich es am Bildschirm --> dann sollte kommunikation wohl funktionieren, oder?

Kampi
21.04.2013, 17:35
Genau.
Jetzt guck mal ab wo die Kommunikation nicht mehr funktioniert.
Wenn alles funktioniert, liegt der Fehler irgendwo am Modul.

papuadive
21.04.2013, 17:57
stimmt eigentlich meine verdrahtung:
Modul SD232CN RS232
Pin 1 (GND)
Pin 2&11 (+5V)
Pin 9 --> Pin 11
Pin 8 --> Pin 12
Pin 7(GND)

Kampi
21.04.2013, 18:05
Die Verdrahtung muss in etwa so aussehen (dein Reader ersetzt in dem Fall den FT232):

http://www.b-redemann.de/images/dmm-usb-Bild05.gif

papuadive
21.04.2013, 18:27
nach diesem schaltblan bin ich vorgegangen...

von Pin 9 des moduls --> auf den RS232 Pin 11
von Pin 8 des moduls --> auf den RS232 Pin 12

verstehe nicht, warum es nicht funktioniert



25177

- - - Aktualisiert - - -

braucht man den DTR-Anschluss, wenn ja muss ich ihn erst anlöten

Kampi
21.04.2013, 18:49
Nein die brauchst du nicht.
Das Modul gibt an Pin 9 die Daten aus, sprich vom Modul ist dies der Tx Pin.
Hast du diesen angeschlossen?

papuadive
21.04.2013, 19:02
ja pin 9 vom modul geht auf den SN232CN auf Pin 11

Kampi
21.04.2013, 19:21
Mach mal bitte einen genauen Schaltplan von deiner Schaltung.

papuadive
21.04.2013, 19:22
eigentlich kann es nur am Modul selbst liegen:
keine ahnung warum das modul am pin 9 nichts brauchbares rausgibt.
die kommunikation sollte ok sein, denn wenn ich eine brücke am SN232CN zwischen 11 und 12 lege und über's terminal daten eingebe kommen diese zurück. --> dann sollte der loop eigentlich passen.
das modul gibt (Pin 9 = ASCII OUT) etwas aus, denn der curser springt ca 10 zeichen nach rechts - ohne zeichenausgabe.
vielleicht ist die darstellungsart falsch eingestellt im tera term. nur wo stellt man dies ein?

Kampi
21.04.2013, 19:50
Ach ich Esel....du sagtest der Cursor springt bei Annäherung eines Tags etwa 10 Positionen nach links?
Es wird auch was empfangen, nur das was empfangen wird sind keine ASCII Zeichen, sondern Zahlenwerte und diese werden vom Terminal wahrscheinlich als Steuerbefehle interpretiert und dem entsprechend nicht als Buchstaben dargestellt.
Lad dir mal bitte eben HexTerminal von meinem Dropbox Link runter (finde den Original Downloadlink nimmer):

https://www.dropbox.com/s/9i0wfznw6cjjlad/Hexterminal%202.exe

Damit siehst du was am COM-Port empfangen wurde (wichtig, das Terminal kann nur die COM-Ports 1-3 verwenden. Du musst den USB Wandler also auf einen der Ports legen).
Poste dann mal einen Screenshot von den Bytes.

papuadive
21.04.2013, 19:53
hier meine schaltung...
danke für deine hilfe
papua


25183

Kampi
21.04.2013, 20:31
Probier das mal bitte mit dem HexTerminal.

papuadive
22.04.2013, 17:19
hallo, hast du zufällig den link dieses "hex termianl" programms. klingt irgendwie alles gleich...
danke

papuadive
28.04.2013, 10:29
Hallo Kampi,
bin erst wieder zurückgekommen...
Nun möchte ich diese Daten auf meinem µP Bord bringen bzw. auslesen.
Mein µP-Board hat einen Mega 32 und ein LCD-Display 4x20 Zeichen.
Was mir allerdings Probleme bereitet, ist die serielle Komm. zum µP.

--> Ich verwende am µP den Pin (D0) RxD --> hier hängt mein Pin 9 des RF-ID Lesegerät drauf
--> weiters habe ich die 2 lib. (von Peter Fleury), ins AVR-Studio geladen (uart.c und uart.h)


Leider weiss ich nicht, wie die einzelnen Befehle im Hauptprogramm aneinander gereiht werden müssen, damit ich die ankommenden Daten aufs LCD-Display bekomme.

Die Ausgabe auf das Display ist für mich kein Problem - nur das Lesen der Daten und das Zwischenspeichern, davon habe ich 0-Ahnung! Sorry.
Auch Beischreibungen im Internet brachten keine Lösung.
Danke

Kampi
28.04.2013, 11:31
Hey,

da ich die Lib selber nicht nutze, kann ich dir nicht garantieren das es funktioniert!
Zu allererst musst du den UART initialisieren

uart_init(UART_BAUD_SELECT(9600,-Takt deines Prozessors z.B. 16000000 für 16MHz-) ); // Falls die Baudrate deines Moduls nicht 9600 ist, musst du den Wert anpassen
sei(); // Interrupts aktivieren
c = uart_getc(); // Ein Zeichen einlesen

Jetzt musst du nur noch prüfen ob das eingelesene Zeichen das Startbyte der Übertragung ist. Wenn ja musst du alle anderen Zeichen empfangen und in einem String speichern.

papuadive
28.04.2013, 20:04
hallo,
bin leider noch immer nicht weitergekommen...
mein problem ist:

1. an welchen Pin des Mega 32 muss ich das Lesegeärt anschließen
2. wenn ich den Schlüssel über das Lesegrät ziehe, kommen 15 od. mehr Zeichen auf einmal herein. Wie muss ich diese speichern
3. wenn ich es schaffe diese zu speichern, erst dann kann ich sie aufs LCD-Display ausgeben.

habe momentan keine Ahnung wie es weiter geht

Gruß Papua




Mein momentaner Code:

//************************************************** **
// RF-ID-Daten seriell auslesen über die UART
//************************************************** **
#include "definition.h"
#include "uart.h" //Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury

int main()
{
//**************************
// Konfiguration
//**************************
lcd_init(); // LCD initialisieren
uart_init(9600); // UART init. und Baudrate einstellen
sei(); // Interrupt freischalten
lcd_clear();

unsigned char zeichen;

while (1)
{
zeichen = uart_getc();
LCD(zeichen); // Empfangens Zeichen auf LCD schreiben
}
}

Kampi
28.04.2013, 20:47
Du musst den Tx Pin des Lesemoduls an den Rx Pin vom UART 0 ansschließen.
Die Zeichen musst du dann nacheinander empfangen und in einem String speichern.

papuadive
29.04.2013, 09:04
geht leider noch immer nicht...
keine Ahnung ob mein code so stimmt
danke
gruß papua


//************************************************** **
// RF-ID-Daten seriell auslesen über die UART
//************************************************** **
#include "definition.h"
#include "uart.h" //Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
int zeichen[15];
char Value[18]; // Für die LCD Ausgabe (AD-Wandler-Wert)
//
uint8_t LCD_aufrufen(uint16_t ms) {
static uint16_t i_zaehler = 0;

if (i_zaehler >= ms)
{
LCD(zeichen);
i_zaehler = 0;
}
i_zaehler ++;
return 0;
}

// LCD-Ausgabe
void LCD(int wert[])
{
lcd_clear();
itoa(*wert,Value,10); // umwandeln einer dez.-Zahl (WERT zB 11) in ASCII-Zeichen 11 (LCD kann nur ASCII-Zeichen ausgeben!!!)
lcd_pos(2,0);
lcd_text("ID-Nummer:");
lcd_pos(3,0);
lcd_text(Value);
}
int main()
{
//**************************
// Konfiguration
//**************************
lcd_init(); // LCD initialisieren
uart_init(9600); // UART init. und Baudrate einstellen
sei(); // Interrupt freischalten

lcd_clear();
while (1)
{

for(int i = 0; i <= 13; i++)
{
zeichen[i] = uart_getc();
LCD(zeichen); // Empfangens Zeichen auf LCD schreiben
}
LCD_aufrufen(60000);
}
}

sternst
29.04.2013, 09:47
void LCD(int wert[])
...
itoa(*wert,Value,10); // umwandeln einer dez.-Zahl (WERT zB 11) in ASCII-Zeichen 11 (LCD kann nur ASCII-Zeichen ausgeben!!!)


int main()
...
for(int i = 0; i <= 13; i++)
{
zeichen[i] = uart_getc();
LCD(zeichen); // Empfangens Zeichen auf LCD schreibenDu gibst 14 mal das gleiche (das erste) Byte aus. Das Interface von LCD() macht so allgemein wenig Sinn.
Und wozu überhaupt der itoa-Schritt? Das was vom Reader kommt sind doch schon ASCII-Zeichen.



#include "uart.h" //Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury


for(int i = 0; i <= 13; i++)
{
zeichen[i] = uart_getc();
Kann so nicht funktionieren. Lies dir mal die Doku zum Fleury uart_getc() durch.


PS: Der Sinn von LCD_aufrufen() erschließt sich mir auch nicht.

papuadive
05.05.2013, 07:38
habe den Code geändert und benutze jetzt eine andere Lib für mein LCD-Display.

Den Code (inkl. Lib) habe ich fertig bekommen. Eigentlich müsste es funktionieren, nur bei mir geht's leider nichts.
Ich verwende ein 4x20 Zeichen Lcd-Display (DEM 20468). Habe es entsprechend der lib. angeschlossen.
Leider zeigt das lcd-display nichts an!
Was mache ich wieder falsch, oder ist dies Lib. für die LCD-Controller unbrauchbar?
Danke Papua


/* LCD Include-Datei
*
* Spezielle Version für 4x20 LCD
*
* LCD_CTRL stellt ein, welcher Controllertyp (wichtig für DD-RAM-Adressen)
* Einige Routinen sind für ein EA DIP204-4 mit KS0073 Controller notwendig, aber auskommentiert
*
* Das LCD ist folgendermaßen angeschlossen:
* PC4 = RS
* PC5 = Enable
* PC0-PC3 = D4-D7
* R/W ist n.c.
*
*
*/
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_tools.h"
#define LCD_CTRL 0 // (0 = HD44780, 1= KS0073)
#define delay(us) _delay_loop_2 (((F_CPU/4000)*us)/1000) // wartet µs
/**
@brief wartet Millisekunden
@param Zeit in Millisekunden
@return none
*/
void delay_ms(uint16_t ms)
{
for(uint16_t t=0; t<=ms; t++)
_delay_ms(1);
}
/**
@brief Enable Leitung togglen
@param none
@return none
*/
void lcd_flash_e ()
{
PORTC = PORTC | ( 1<<DDC5 ) ; // Enable = HIGH
delay(100); // kurz warten, damit Flanke entsteht
PORTC = PORTC & ~( 1<<DDC5 ) ; // Enable = LOW
delay(100); // Warten, bis der durch Enable angelegte Befehl hoffentlich verarbeitet wurde
}
/**
@brief Kommando oder Zeichen an Display senden:
@param rs=0 => Kommando, rs=1 => Zeichen
@return none
*/
void lcd_write (uint8_t data, uint8_t rs)
{
uint8_t dataBits ;

if (rs) // write data (RS=1, RW=0)
dataBits=0x10; // RS liegt an Pin 4 = B 0001 0000 = H 10
else // write instruction (RS=0, RW=0)
dataBits=0;

PORTC = dataBits | (data>>4); // output high nibble first, zzgl. Zustand für RS-Leitung
lcd_flash_e ();
PORTC = dataBits | (data&0x0F); // output low nibble, zzgl. RS-Leitung
lcd_flash_e ();
}
/**
@brief Display loeschen
@param none
@return none
*/
void lcd_cls ()
{
lcd_write(0x00,0); // B 0000 0000 => Clear
delay(4000); // dauert eine Weile
lcd_write(0x01,0); // B 0000 0001 => Cursor Home
delay(4000); // dauert eine Weile, Wert ausprobiert
}
/**
@brief Zeichenausgabe
@param none
@return none
*/
void lcd_writechar ( char zeichen)
{
lcd_write (zeichen, 1);
}
/**
@brief gibt eine Zeichenkette auf dem LCD aus
@param none
@return none
*/
void lcd_writetext ( char *text)
{
uint8_t i = 0;
while (text[i]!=0)
{
lcd_writechar(text[i]);
i++;
}
}
/**
@brief Zeilenwechsel
@param none
@return none
*/
void lcd_gotoline (uint8_t zeile)
{
if (LCD_CTRL == 0)
{
if (zeile == 1) lcd_write(0x80,0); // B 1000 0000 => DD-RAM Adress Set 1. Zeile/1.Spalte
if (zeile == 2) lcd_write(0x80+0x40,0); // B 1010 0000 => DD-RAM Adress Set 2. Zeile/1.Spalte
if (zeile == 3) lcd_write(0x80+0x14,0); // B 1010 0000 => DD-RAM Adress Set 3. Zeile/1.Spalte
if (zeile == 4) lcd_write(0x80+0x54,0); // B 1010 0000 => DD-RAM Adress Set 4. Zeile/1.Spalte
}
else
{
if (zeile == 1) lcd_write(0x80,0); // B 1000 0000 => DD-RAM Adress Set 1. Zeile/1.Spalte
if (zeile == 2) lcd_write(0x80+0x20,0); // B 1010 0000 => DD-RAM Adress Set 2. Zeile/1.Spalte
if (zeile == 3) lcd_write(0x80+0x40,0); // B 1010 0000 => DD-RAM Adress Set 3. Zeile/1.Spalte
if (zeile == 4) lcd_write(0x80+0x60,0); // B 1010 0000 => DD-RAM Adress Set 4. Zeile/1.Spalte
}
}
/**
@brief Cursorpositionieren
@param Zeile, Spalte
@return none
*/
void lcd_gotopos (uint8_t zeile, uint8_t spalte)
{
if (LCD_CTRL == 0)
{
if (zeile == 1) lcd_write(0x80+0x00+spalte-1,0); // DD-RAM Adress 1. Zeile + Spalte
if (zeile == 2) lcd_write(0x80+0x40+spalte-1,0); // DD-RAM Adress 2. Zeile + Spalte
if (zeile == 3) lcd_write(0x80+0x14+spalte-1,0); // DD-RAM Adress 3. Zeile + Spalte
if (zeile == 4) lcd_write(0x80+0x54+spalte-1,0); // DD-RAM Adress 4. Zeile + Spalte
}
else
{
if (zeile == 1) lcd_write(0x80+0x00+spalte-1,0); // DD-RAM Adress 1. Zeile + Spalte
if (zeile == 2) lcd_write(0x80+0x20+spalte-1,0); // DD-RAM Adress 2. Zeile + Spalte
if (zeile == 3) lcd_write(0x80+0x40+spalte-1,0); // DD-RAM Adress 3. Zeile + Spalte
if (zeile == 4) lcd_write(0x80+0x60+spalte-1,0); // DD-RAM Adress 4. Zeile + Spalte
}
}
/**
@brief gibt eine int-Zahl auf dem Display aus. Integriert, damit auf string.h verzichtet werden kann
@param Zahl
Anzahl der Stellen (führende Leerzeichen)
space=0 => führende Nullen, 1 => führende Leerzeichen
@return none
*/
void lcd_writezahl (int32_t zahl, uint8_t pos, uint8_t spacer)
{
int32_t output;
char sign = '0';

pos--; // Korrektur des Parameters für Benutzerfreundlichkeit

if (spacer) sign=' ';
// negatives Vorzeichen oder Leerzeichen
if (zahl < 0)
{
lcd_writechar ('-');
zahl *= -1; // positive Zahl
}
output = zahl;

// Hunderttausender-Dezimalstelle oder Leerzeichen (Ausblenden fuehrender Nullen)
if (zahl >= 100000) lcd_writechar (0x30 + output/100000); else if (pos >= 5) lcd_writechar (sign);
output = output % 100000;
// Zehntausender-Dezimalstelle oder Leerzeichen (Ausblenden fuehrender Nullen)
if (zahl >= 10000) lcd_writechar (0x30 + output/10000); else if (pos >= 4) lcd_writechar (sign);
output = output % 10000;
// Tausender-Dezimalstelle oder Leerzeichen
if (zahl >= 1000) lcd_writechar (0x30 + output/1000); else if (pos >= 3) lcd_writechar (sign);
output = output % 1000;
// Hunderter-Dezimalstelle oder Leerzeichen
if (zahl >= 100) lcd_writechar (0x30 + output/100); else if (pos >= 2) lcd_writechar (sign);
output = output % 100;
// Zehner-Dezimalstelle oder Leerzeichen
if (zahl >= 10) lcd_writechar (0x30 + output/10); else if (pos >= 1) lcd_writechar (sign);
// einer Dezimalstelle oder Leerzeichen
lcd_writechar (0x30 + output % 10);
}
/**
@brief Zuerst den 8-Bit-Modus aktivieren, Ist wichtig, falls LCD schon im 4-Bit Modus war und dann
nach einem Programm-Reset vergeblich versucht würde, den 4-Bit Modus erneut zu aktivieren.
Dann in 4-Bit Modus umschalten.
@param none
@return none
*/
void lcd_set4bit ()
{
PORTC = 0x03; // 8-Bit Modus aktivieren (B 0011 0000 = H 30, High Nibble => B 0011 = H 03
lcd_flash_e (); // Datenübernahme
delay_ms(5); // sicherheitshalber warten da wir BUSY nicht überprüfen können
// Das ganze 2x wiederholen:
PORTC = 0x03;
lcd_flash_e ();
delay(200);

PORTC = 0x03;
lcd_flash_e ();
delay(200);
lcd_write(0x2,0); // B 0000 0010 => in 4-Bit-Modus umschalten
delay(200);
}
/**
@brief Portrichtung einstellen. Extern, damit man dies separat aufrufen kann, wenn bspw. LCD schon initialisiert ist und
per Watchdog ein Reset ausgelöst wurde, man dann aber nicht das Display neu initialisieren möchte, damit es schneller weiter geht
@param none
@return none
*/
void lcd_port_ini ()
{
DDRC = 0x3F; // setze Portrichtung (1 = Ausgang): 0011 1111
}
/**
@brief Display initialisieren. Einmal als erstes aufrufen
@param none
@return none
*/
void lcd_ini ()
{
lcd_port_ini();
DDRC = 0x3F; // setze Portrichtung (1 = Ausgang): 0011 1111
delay_ms(100); // 40ms warten bis LCD wirklich bereit! Wir können nicht BUSY auswerten.
// Es gibt Displays die so lange brauchen (z. B. Optrex DMC20481)
lcd_set4bit(); // ab jetzt 4-Bit-Modus

// lcd_write(0x2C,0); // 4x20 Spezial: Function Set (0010 1100): 4-Bit, 2 Line, RE-Bit, Dot Scroll, Normal Mode
// lcd_write(0x09,0); // 4x20: Extended Function Set (0000 1001): 5 dot font, Normal Cursor, 4 Line Display
lcd_write(0x28,0); // B 0010 1000 => Function Set: 4Bit (kein 8-Bit Bus), zweizeiliges Display, 5x7 Dots/Zeichen (kein 5x10), RE-Bit aus
// lcd_write(0x0F,0); // B 0000 1000 => Display On/Off: Display ein, Cursor an, Blinken an
lcd_write(0x0C,0); // B 0000 1000 => Display On/Off: Display ein, Cursor aus, Blinken aus
lcd_write(0x06,0); // B 0000 0110 => Entry Mode Set: DD-RAM autom. inkr., Cursor bewegen

lcd_cls(); // Display löschen
}

sternst
05.05.2013, 19:43
Was mache ich wieder falschGanz grundsätzlich könntest du mal damit anfangen, Code auch als "Code" zu posten, und nicht als "Zitat". So ist das ja kaum lesbar.

papuadive
06.05.2013, 08:55
ja, stimmt, hab nicht aufgepasst - sorry...

Nun kann ich die RF-ID-Schlüssel via RF-ID-Lesegerät auslesen und am Display zur Anzeige bringen lassen.
Was mir allerdings noch fehlt ist: Wie muss ich die Lib. abändern, damit der µP auch noch andere Dinge erledigen kann und nicht nur warten, bis ein Zeichen kommt.
Danke Papua


Mein Main-Code:


/* RF-ID-Key (12-Zeichen) in µP (Mega 32) einlesen und auf dem 4x20 Zeichen LCD ausgegeben
*
* 9600Bd, 8N1
*
*/
#include "uart.h"
#include "definition.h"
uint8_t Led_blinken_gn(uint16_t ms) {
static uint16_t i_zaehler;


if (i_zaehler >= ms)
{
PORTC ^= (1<<PC7);
i_zaehler = 0;
}

i_zaehler ++;
return 0;
}
//********************************************
int main()
{
DDRC |= (1 << DDC7);
PORTC |= (1 << PC7);

volatile unsigned char zeichen = 0;
volatile char text[20] = "";
int i = 0;

uart_ini();
lcd_init();

vWillkommen(); // Auf LCD
while (1)
{

zeichen = ser_getc(); // Zeichen einlesen
if(zeichen){ // wenn 0, LCD löschen
if(i == 0)
lcd_clear();
text[0] = zeichen - 0; //
lcd_text(&text[0]); //gibt Zahlen/Zeichen aus
i++;

if(i >= 16) //wenn 16 Zeichen eingelangt sind --> i wieder zurücksetzen
i = 0;
}


// LED-blinken lassen, damit ich sehe, ob noch etwas passiert
Led_blinken_gn(10000);

}

}






Meine Lib:

/* Eingaben über ein Hyperterminal werden als ECHO zurückgesendet oder auf dem LCD ausgegeben
*
*/
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "uart.h"
#define UART_BAUD_RATE 9600L
#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
#define RBUFFLEN 40 //Pufferlänge für seriellen Empfang
volatile unsigned char rbuff[RBUFFLEN]; // Ringpuffer
volatile uint8_t rbuffpos, // Position, die als nächstes gelesen werden muß im Ringpuffer
rbuffcnt, // Anzahl zu lesender Zeichen im Puffer
udr_data; // Daten aus dem UART (volatile, damit nicht wegoptimiert wird vom Präprozessor)
// Interruptroutine, die Zeichen aus dem UART sofort ausliest, wenn empfangen
SIGNAL (SIG_UART_RECV)
{
udr_data= UDR; //Byte auf jeden Fall abholen, sonst Endlosinterrupt

if(rbuffcnt < RBUFFLEN) // keinen Zeichen in einem vollen Ringpuffer überschreiben
rbuff[(rbuffpos+rbuffcnt++) % RBUFFLEN] = udr_data; // welche Position? Gelesene Zeichenpos + Anzahl Zeichen MODULO Pufferlänge
// (von 0 wieder anfangen, wenn Ende erreicht)
}
// Nächstes zu lesendes Zeichen aus Ringpuffer zurückgeben
unsigned char ser_getc (void)
{
unsigned char c;
while(!rbuffcnt); // Warte bis ein Zeichen vorhanden ist

cli(); // Interruptbehandlung kurz aussetzen. Ab jetzt muß es schnell gehen (wenig Befehle), damit Zeichen, die
// ab jetzt eintreffen nicht verloren gehen.
rbuffcnt--; // anschl. ein Zeichen weniger zum ausgeben
c = rbuff [rbuffpos++]; // Zeichen holen, was nach dem bereits gelesenen liegt
if (rbuffpos >= RBUFFLEN) rbuffpos = 0; // wenn hinterstes Zeichen (rechts im Puffer) gelesen wurde, dann wieder vorne anfangen
sei(); // Interruptbehandlung wieder aktivieren
return (c); // Zeichen zurückgeben
}
// Ein Zeichen senden
void uart_putc(unsigned char c)
{
while(!(UCSRA & (1 << UDRE))); // warte, bis UDR bereit
UDR = c; // sende Zeichen
}
// Einen String senden
void uart_puts (char *s)
{
while (*s)
{ // so lange *s != NULL
uart_putc(*s);
s++;
}
}
// USART initialisieren
void uart_ini ()
{
sei(); // Interruptbehandlung aktivieren
UCSRB |= (1 << TXEN); // UART TX (senden) einschalten
UCSRB |= (1 << RXEN ); // UART RX (empfangen) einschalten
UCSRB |= (1 << RXCIE); // Interruptauslösung für eingehende Daten aktivieren
UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1); // Asynchron, 8N1
UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CP U)>>8); // Baudrate wählen
UBRRL=(uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_CPU );
}

Kampi
06.05.2013, 10:35
Hey,

ich weiß nicht ob die Lib das her gibt.
An für sich muss alles was in deiner Main steht in die UART Rx ISR, damit der Controller die Verarbeitung nur durchführt wenn was empfangen wurde.
Jetzt "wartet" er nur darauf das was passiert....du willst aber das er eigenständig darauf reagiert.
Unter Umständen solltest du vielleicht einfach was eigenes schreiben....UART auslesen ist nicht sehr schwer :)