Hallo Zusammen, stehe schon seit Tagen an einen Problem. Und zwar ist folgendes, habe einen Master (zur Zeit noch ein PC)! Ca. 7-8 Slave's sollen später dann (wenn ich endlich mal die richtigen Teile bekomme)über RS485 kommunizieren. Zur Zeit hab ich nur einen Master und einen Slave mittels RS232 verbunden. Bei den Slaves soll dann immer die gleiche Software kommen und die Adresse soll über ein Port mittels Lötbrücken adressiert werden. Zur Programm-Info: Mein Master schickt eine Adresse die Slaves sollen dies mit dem Adress-Port vergleichen und wenn diese stimmt dem Master antworten (temperatur schicken) Meine Frage nun wie kann ich das Port in eine Variable umwandeln - irgendwie schaff ich dass nicht. Hat jemand von euch ein paar Vorschläge? mfg Newby
In dem du deinen Port als Eingang definierst und wenn du etwas vergleichen willst einfach ausliest. Erklärt ist es hier: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Eing.C3.A4nge_.28Wie_kommen_Signale_in_den_.C2.B5C.29
Statt Lötbrücken könntest Du die Adressen im EEPROM des Mikrocontrollers speichern. Dann kann auch überall die gleiche Software drauf.
uint8_t Adresse_Nr; Adresse_Nr = (!(PINC)); if (Adresse_Nr == Adresse_UART) { Adresse_OK = '1'; } hab dies so probiert aber irgendwass mach ich da ordenlich falsch ;) Bei Adresse_UART werden zahlen geschickt. wenn ich z bsp. 1 schicke kommt auch eins wieder zurück wenn ich eine Schleife zum hypter terminal schicke was der prozessor bekommt. @Fabian wie soll das denn funktionieren sorry warscheinlich blöde frage aber ich bin relativ neu in C. weil woher sollen die Slaves denn wissen das z bsp. Raum 1 die 1 hat dann der raum 2 die 2 usw.
Newby schrieb: > hab dies so probiert aber irgendwass mach ich da ordenlich falsch ;) > Bei Adresse_UART werden zahlen geschickt. wenn ich z bsp. 1 schicke > kommt auch eins wieder zurück wenn ich eine Schleife zum hypter terminal > schicke was der prozessor bekommt. Vorschlag: - Poste den ganzen Programmcode als C-Datei im Anhang. - Schreib in verständlichen Sätzen: - Was Du machst (was schickst Du für Zeichen?). - Was das Programm machen soll (was soll es antworten?). - Was das Programm tatsächlich macht (was antwortet es?). - Wie sieht die Hardware aus? Was ist an welchem Pin angeschlossen, welche Spannungen sind an den Pins? Denk daran, wir wissen das alles nicht. Nur wenn Du es verständlich beschreibst, haben wir eine Chance, Dir zu helfen. Zum EEPROM: Du schreibst einmalig beim Programmieren die Adresse in das EEPROM. Bei dem Slave, der in Raum 1 kommt, schreibst Du die Zahl 1 rein. Bei dem Slave, der in Raum 2 kommt, die Zahl 2. Und so weiter. Der Slave vergleicht die per UART empfangene Adresse, mit der in seinem EEPROM. Wenn sie gleich sind, antwortet er, ansonsten nicht. Wenn Du das Programm später mal aktualisieren willst, musst Du beim Flashen auswählen, dass das EEPROM nicht neu beschrieben werden soll. Dann behält jedes Exemplar seine eingespeicherte Adresse. Dafür musst Du die EESAVE-Fuse setzen. Aber stellt das mal hinten an, erstmal musst Du ein paar Programmiergrundlagen lernen ...
Ok Hardware is ein bischen schwierig hab zur zeit einen LM75 extern auf meinen MYAVR Board mit Atmega8 (später dann Atemga168) Daran hängt noch ein Display über I2C was aber zur Zeit nichts zur Sache tut. Meine Eingänge ich glaube man sagt low aktiv sprich sie sind immer '1' wenn man sie Schaltet '0'. Was es macht: es wird später mal in ferner Zukunft eine Heizungssteuerung. Zur Zeit ist es ein PC über RS232 auf den Atmega8. Will aktuell nur eine Zahl (die später dann vom Master gesendet wird) vom PC senden und dass mir der Richtige Slave antwortet (zur Zeit auch nur einer angeschlossen) Als Beispiel: PC sendet 1 => Slave antwortet 20°C Zur Zeit geht es soweit dass ich die Adresse sende (1) und er mir dann die Temperatur zurück zum PC sendet. Was er aber zur Zeit noch nicht macht ist eben dass mit dem Port Vergleichen ob es wirklich der richtige Slave ist. Sprich bevor mein Atmega die Temperatur zurück sendet, sollte er schauen ob er auch wirklich gemeint ist. while (1) // Mainloop { Adresse_OK = Adressabfrage(Adresse); if (Adresse_OK == '1') //wenn Adresse_OK richtig - Temp senden { uart_senden (); //Temp senden } else { //sonst nicht beachten //putChar (0b11110000); } } //////////////////////////////////////////////////////////////////////// // //ab hier Funktion für kontrolle Adresse #include <avr/io.h> char Adressabfrage (uint8_t Adresse) { char Adresse_OK; uint8_t Adresse_Nr; Adresse_Nr = PINB; if (Adresse_Nr == Adresse) //Achtung Port invertiert PortD vergleich mit Adresse UART { Adresse_OK = '1'; } else { Adresse_OK = '0'; } // Port D auslesen welche Adresse return (Adresse_OK); } Hoffe es ist soweit verständlich es fehlen natürlich die LM75 auswertung und div Init's aber die passt ja eh
OK. Da kann man schon mal mehr mit anfangen. Bitte beim nächsten mal die Formatierungstags für C-Code (siehe Hinweis über den Antwortkasten) nutzen oder noch besser: KOMPLETT als Anhang anhängen. Hier der Code erstmal lesbarer formatiert:
1 | while (1) // Mainloop |
2 | {
|
3 | Adresse_OK = Adressabfrage(Adresse); |
4 | if (Adresse_OK == '1') //wenn Adresse_OK richtig - Temp senden |
5 | {
|
6 | uart_senden (); //Temp senden |
7 | }
|
8 | else
|
9 | { //sonst nicht beachten |
10 | //putChar (0b11110000);
|
11 | }
|
12 | }
|
13 | |
14 | // ab hier Funktion für kontrolle Adresse
|
15 | #include <avr/io.h> |
16 | |
17 | char Adressabfrage (uint8_t Adresse) |
18 | {
|
19 | char Adresse_OK; |
20 | uint8_t Adresse_Nr; |
21 | Adresse_Nr = PINB; |
22 | |
23 | if (Adresse_Nr == Adresse) //Achtung Port invertiert PortD vergleich mit Adresse UART |
24 | {
|
25 | Adresse_OK = '1'; |
26 | }
|
27 | else
|
28 | {
|
29 | Adresse_OK = '0'; |
30 | }
|
31 | // Port D auslesen welche Adresse
|
32 | return (Adresse_OK); |
33 | }
|
Da Du ihn nicht komplett gepostet hast, ist unklar, ob die Reihenfolge der Funktionen überhaupt stimmt. Adressabfrage() muss auf jeden Fall vor der main-Funktion deklariert werden:
1 | #include <avr/io.h> |
2 | |
3 | char Adressabfrage (uint8_t Adresse) |
4 | {
|
5 | char Adresse_OK; |
6 | uint8_t Adresse_Nr; |
7 | Adresse_Nr = PINB; |
8 | |
9 | if (Adresse_Nr == Adresse) //Achtung Port invertiert PortD vergleich mit Adresse UART |
10 | {
|
11 | Adresse_OK = '1'; |
12 | }
|
13 | else
|
14 | {
|
15 | Adresse_OK = '0'; |
16 | }
|
17 | // Port D auslesen welche Adresse
|
18 | return (Adresse_OK); |
19 | }
|
20 | |
21 | while (1) // Mainloop |
22 | {
|
23 | Adresse_OK = Adressabfrage(Adresse); |
24 | if (Adresse_OK == '1') //wenn Adresse_OK richtig - Temp senden |
25 | {
|
26 | uart_senden (); //Temp senden |
27 | }
|
28 | else
|
29 | { //sonst nicht beachten |
30 | //putChar (0b11110000);
|
31 | }
|
32 | }
|
Die ganze Adressabfrage-Funktion ist kann man zusammenfassen als:
1 | char Adressabfrage (uint8_t Adresse) |
2 | {
|
3 | return (Adresse == PINB); |
4 | }
|
Wenn die Adresse gleich PINB ist, wird 1 (wahr) zurückgegeben. Wenn nicht, dann 0 (falsch). Dann die Hauptschleife:
1 | while (1) // Mainloop |
2 | {
|
3 | Adresse_OK = Adressabfrage(Adresse); |
4 | if (Adresse_OK == '1') //wenn Adresse_OK richtig - Temp senden |
5 | {
|
6 | uart_senden (); //Temp senden |
7 | }
|
8 | else
|
9 | { //sonst nicht beachten |
10 | //putChar (0b11110000);
|
11 | }
|
12 | }
|
Du darfst nicht mit '1' vergleichen. '1' ist das ASCII-Zeichen der Ziffer 1. Genau wie 'A' das ASCII-Zeichen für den Buchstaben A ist. Die Zahl 1 musst Du ohne ohne Anführungszeichen schreiben:
1 | while (1) // Mainloop |
2 | {
|
3 | Adresse_OK = Adressabfrage(Adresse); |
4 | if (Adresse_OK == 1) //wenn Adresse_OK richtig - Temp senden |
5 | {
|
6 | uart_senden (); //Temp senden |
7 | }
|
8 | else
|
9 | { //sonst nicht beachten |
10 | //putChar (0b11110000);
|
11 | }
|
12 | }
|
Das ist aber auch kein guter Stil, weil in C auch alle anderen Werte (außer 0) "wahr" bedeuten, nicht nur 1. Deshalb besser:
1 | while (1) // Mainloop |
2 | {
|
3 | Adresse_OK = Adressabfrage(Adresse); |
4 | if (Adresse_OK != 0) //wenn Adresse_OK richtig - Temp senden |
5 | {
|
6 | uart_senden (); //Temp senden |
7 | }
|
8 | else
|
9 | { //sonst nicht beachten |
10 | //putChar (0b11110000);
|
11 | }
|
12 | }
|
Oder kürzer:
1 | while (1) // Mainloop |
2 | {
|
3 | Adresse_OK = Adressabfrage(Adresse); |
4 | if (Adresse_OK) //wenn Adresse_OK richtig - Temp senden |
5 | {
|
6 | uart_senden (); //Temp senden |
7 | }
|
8 | else
|
9 | { //sonst nicht beachten |
10 | //putChar (0b11110000);
|
11 | }
|
12 | }
|
Und da die Funktion Adressabfrage() so trivial kurz ist, kann man das ganze auch einfach zusammenfassen als:
1 | while (1) // Mainloop |
2 | {
|
3 | if (Adresse == PINB) |
4 | {
|
5 | uart_senden (); //Temp senden |
6 | }
|
7 | }
|
danke soweit einmal - die main und die Adressabfrage sind in der richtigen reihenfolge dass passt soweit ein Frage wieso funktioniert dies nicht Adresse_Nr = (!(PINB)); //PortB sollt in die Variable gehen oder? putChar (Adresse_Nr); //senden der Variable über UART zum PC mein PC macht aber nichts hab dies direkt in der main schleife zum testen eingebaut oder hab ich das mit dem Port übernehmen falsch verstanden. Aber soweit ich das von Fabian gesehen hab sollte dies doch funktionieren wenn ich Adresse_Nr = PINB; funktioniert es
Wenn alls acht Bits der Ports invertiert werden sollen (aus 1 wird 0, aus 0 wird 1) musst Du den Operator zum bitweisen invertieren nehmen:
1 | Adresse_Nr = ~PINB; |
Der !-Operator ist eine logische Negation: Wenn alle Bits der Ports 0 sind, gibt er 1 zurück. Wenn irgendein Bit des Ports 1 ist, gibt er 0 zurück. Ist wahrscheinlich nicht, was Du haben wolltest ...
ja genau das ist das was ich gesucht habe gibt es auch einen Trick wie man das mit nur einen halben Port macht?? z bsp PD0,PD1,PD2,PD4 nochmal tausend Dank
bzw hab ich jetzt ein bischen falsch ausgedrückt möchte einfach die letzten 4 bits immer auf 1 und die anderen variabel über das Port schalten
Newby schrieb: > möchte einfach die letzten 4 bits immer auf 1 und die anderen variabel > über das Port schalten Na dann mach das doch. Ist alles hier beschrieben: http://www.mikrocontroller.net/articles/Bitmanipulation
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.