mal eine kurze frage zum Empfang auf der oder die UART,
ich sende vom slave seine adresse zum Master wie volgt:
Slave sendet;
uart_putc(40);
Master empfang:
i=0;
while ( ( c2 = uart1_getc() ) != 0x28 && i < Len2 - 1 )
in[ i++ ] = c2;
in[i] = '\0';
muss ich in der While != 0x28 das so abfragen oder While == 40
mfg
ingo schrieb:> muss ich in der While != 0x28 das so abfragen oder While == 40> mfg
Die Zahlendarstellung ist egal.
Was soll die While-Schleife machen?
Soll sie solange durchlaufen werden, bis 40 gesendet wurde und die Daten
bis dahin ins Array geschrieben werden? Oder soll sie solange warten,
bis nicht mehr 40 empfangen wird?
Ich vermute das erste. Dann ist die Schreibweise richtig.
> ingo schrieb:> Die Zahlendarstellung ist egal.> Was soll die While-Schleife machen?> Soll sie solange durchlaufen werden, bis 40 gesendet wurde und die Daten> bis dahin ins Array geschrieben werden?
ja genau
also währe es so auch richtig,
while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 )
in[ i++ ] = c2;
in[i] = '\0';
ich habe 2 Slave jeweils adresse 40 und 41,
wenn ich die slaves nacheinander anspreche zB.
uart_putc(40);
while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 )
in[ i++ ] = c2;
in[i] = '\0';
..... Ausgabe auf mein lcd
uart_putc(41);
while ( ( c2 = uart1_getc() ) == 41 && i < Len2 - 1 )
in[ i++ ] = c2;
in[i] = '\0';
..... Ausgabe auf mein lcd
bekomme ich nur die daten von adresse 41 angezeigt.
spreche ich die svlaves nur einzeln an gehts.
ingo schrieb:> also währe es so auch richtig,> while ( ( c2 = uart1_getc() ) == 40 && i < Len2 - 1 )> in[ i++ ] = c2;> in[i] = '\0';
Nein. es muss "!= 40" heissen.
ingo schrieb:> bekomme ich nur die daten von adresse 41 angezeigt.>> spreche ich die svlaves nur einzeln an gehts.
Dann hast du wohl einen Fehler im Programm...
>>>>>//SLAVE_1> for (;;)> {> c = uart_getc(); //Hole Daten vom UART ab>>> if (c==0xA4) //> {> c1=uart_getc();> if (c1==41) // Stimt die Geräte adresse>
Hier sollte es wohl 40 heissen und nicht 41!
> {> adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4
Messungen
> setTransmitMode();>> uart_putc(*((char*)&adcval+1)); //High-Byte?> uart_putc(*((char*)&adcval)); //Low-Byte>> uart_putc(40);> setReceiveMode();> }> }> }>}
tu dir selbst einen Gefallen und modularisiere deinen Code ein wenig.
So Dinge wie zb die Slave Adressen gehören nicht im Code versteckt,
sondern werden zentral an EINER Stelle mit einem #define vereinbart
#define SLAVE_1_ADDR 40
...
c1 = uart_getc();
if (c1 == SLAVE_1_ADDR ) // Stimt die Geräte adresse
....
uart_putc( SLAVE_1_ADDR );
Dann hast du die Sicherheit, dass die beiden Zahlen auf jeden Fall
zusammenstimmen! Derartige 'magische Zahlen' gehören nicht in den Code.
Das ist viel zu fehleranfällig, dass man bei einer Änderung eine Stelle
übersieht.
Mit einem #define kann dir aber genau dieses Versehen nicht passieren.
Du änderst an EINER Stelle die 40 zur 41 (eben beim #define) und der
Compiler sorgt dafür, dass diese Änderung überall durchgezogen wird. Und
der macht dabei keine Fehler.
Genauso dein Master-Code:
Das ist im Prinzip immer die gleiche FUnktionalität! Mach dir EINE
Funktion, die das Prozedere der Datenübertragung abhandelt und der
übergibst du die gewünschte Slave-Adresse. Es gibt keinen Grund, das
ganze per Copy&Paste zu lösen. Du läufst wieder nur Gefahr, dass du die
beiden Slaves unterschiedlich behandelst, weil du in einem Codeteil
einen Bugfix machst und im anderen vergisst du ihn.
Codeorganisation ist ein wesentlicher und vitaler Bestandteil, um
möglichst fehlerfreien Code zu produzieren.
Dazu gehören zb auch eigene Ausgabefunktionen, in denen du gleichartige
Funktionalität zusammenfassen kannst.
Deine get_show_all könnte zb so aussehen
1
#define SLAVE_1_ADDR 40
2
#define SLAVE_2_ADDR 41
3
4
5
voidget_show_all(uint8_ts)
6
{
7
uint16_tVolt=0,Ampere=0,Watt=0;
8
uint8_tOutputColumn=3;
9
10
if(s==1)
11
{
12
GetValues(SLAVE_1_ADDR,&Volt,&Ampere,&Watt);
13
OutputColumn=3;
14
}
15
elseif(s==2)
16
{
17
GetValues(SLAVE_2_ADDR,&Volt,&Ampere,&Watt);
18
OutputColumn=171;
19
}
20
21
ShowValue(OutputColumn,252,"A: %1d.%02d",Ampere);
22
ShowValue(OutputColumn,316,"V: %1d.%02d",Volt);
23
ShowValue(OutputColumn,376,"W: %1d.%02d",Watt);
24
}
Siehst du um wieviel einfacher es hier ist, den Programmfluss zu
verfolgen und nachzuvollziehen, was an welcher Stelle ausgegeben wird?
Und das alles für den 'Preis' von ein paar (trivialen)
Spezialfunktionen, die jeweils einen Teilaspekt der kompletten Arbeit
erledigen.
ps
"W: %1d.%02d ", watt2/ 1000, watt2 % 1000 );
Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du
3 "Nachkommastellen".
Mit "%1d.%02d" wird eine Zahl 1005 bei dir als
1.05
ausgegeben. Die korrekte Anzeige wäre aber
1.005
und das ist dann schon ein gewisser Unterschied.
>Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du>3 "Nachkommastellen".
ja stimmt ich hab das vielzu umständlich,
aber mein problem ist ich sende zum slave1 0xA4,40 zeige die empfangenen
daten an,dann slave2 0xA4,41 ,
bekomm ich an erster Augabestelle immer die daten von slave2.
spreche ich nur slave1 oder slave2 an dann gehts.
die slaves sollen dann den internen ADC auslesen und zum Master senden
der adc läuft im 10bit mode.
ingo schrieb:>>Tausendstel und %02d passen nicht zusammen. Für Tausendstel brauchst du>>3 "Nachkommastellen".>> ja stimmt ich hab das vielzu umständlich,
Tja. Dein Problem wird eher genau hier liegen.
Dadurch das das alles viel zu umständlich ist, siehst du den
eigentlichen Fehler vor lauter umständlich nicht mehr.
> aber mein problem ist ich sende zum slave1 0xA4,40 zeige die empfangenen> daten an,dann slave2 0xA4,41 ,> bekomm ich an erster Augabestelle immer die daten von slave2.>> spreche ich nur slave1 oder slave2 an dann gehts.
Was heißt nur?
Deine Funktion kann sowieso immer nur entweder den einen oder den
anderen Slave ansprechen.
Hast du kontrolliert, ob du get_show_all auch tatsächlich abwechselnd
mit 1 oder 2 aufrufst?
(Trotzdem solltest du die Funktion vereinfachen. Massiv vereinfachen.
Mann kann sich auch in der selbst geschaffenen Komplexität verirren)
ingo schrieb:> get_show_all wird abwechslnd aufgerufen>> get_show_all (1);> Delay1ms(100);> get_show_all (2);>>> aber meinproblem bleibt halt der empfang der daten auf dem master,
Aus dem was du gepostet hast, kann ich nur den Schluss ziehen, das du
einen riesen Durcheinander auf der UART veranstaltest, weil dein einer
Slave auf die falsche Adresse reagiert.
Du suchst an der falschen Stelle und dein unübersichtlicher Code tut
sein übriges.
Sorry. Aber genau so sieht die Sache aus.
ich sende doch die slave adresse zb40 der slave sendet seine daten mit
seiner adresse, gut ich geb zu bei mir ist dies sehr umständlich vom
code her.
aber wie krieg ich denn nun die werte in Volt, Ampere, Watt ;
vielleicht könnten sie mir da noch ein wenig weiterhelfen.
1
#define SLAVE_1_ADDR 40
2
#define SLAVE_2_ADDR 41
3
4
5
voidget_show_all(uint8_ts)
6
{
7
uint16_tVolt=0,Ampere=0,Watt=0;
8
uint8_tOutputColumn=3;
9
10
if(s==1)
11
{
12
GetValues(SLAVE_1_ADDR,&Volt,&Ampere,&Watt);
13
OutputColumn=3;
14
}
15
elseif(s==2)
16
{
17
GetValues(SLAVE_2_ADDR,&Volt,&Ampere,&Watt);
18
OutputColumn=171;
19
}
20
21
ShowValue(OutputColumn,252,"A: %1d.%02d",Ampere);
22
ShowValue(OutputColumn,316,"V: %1d.%02d",Volt);
23
ShowValue(OutputColumn,376,"W: %1d.%02d",Watt);
24
}
25
26
GetValues(SLAVE_1_ADDR,&Volt,&Ampere,&Watt)
27
{
28
charBuff1_V[20];
29
charBuff1_A[20];
30
charBuff1_W[20];
31
32
charinLine[32];
33
34
intc1;
35
inti=0;
36
intLen=32;
37
38
uint8_tv1,v2;
39
uint8_ta1,a2;
40
uint8_tw1,w2;
41
42
unsignedintspannung;
43
unsignedintstrom;
44
unsignedintwatt;
45
unsignedintadcval;
46
47
setTransmitMode();
48
rgbsend_data(0xA4);//Adresse zum Modul 2 senden
49
rgbsend_data(SLAVE_1_ADDR);//
50
setReceiveMode();
51
52
i=0;
53
54
while((c1=uart1_getc())!=SLAVE_1_ADDR&&i<Len-1)
55
{
56
inLine[i++]=c1;
57
}
58
inLine[i]='\0';
59
60
v1=inLine[0];
61
v2=inLine[1];
62
63
a1=inLine[0];
64
a2=inLine[1];
65
66
w1=inLine[0];
67
w2=inLine[1];
68
69
adcval=v1*256+v2;
70
71
spannung=((long)adcval*5000)/1023;// A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler:
ingo schrieb:> ich sende doch die slave adresse zb40 der slave sendet seine daten mit> seiner adresse,
Dann sieh dir (noch-)mal den von dir geposteten Code für Slave 1 an
1
//SLAVE_1
2
for(;;)
3
{
4
c=uart_getc();//Hole Daten vom UART ab
5
6
7
if(c==0xA4)//
8
{
9
c1=uart_getc();
10
if(c1==41)// Stimt die Geräte adresse
11
{
12
adcval=ADC_Read_Avg(0,4);// Kanal 0, Mittelwert aus 4 Messungen
13
setTransmitMode();
14
15
uart_putc(*((char*)&adcval+1));//High-Byte?
16
uart_putc(*((char*)&adcval));//Low-Byte
17
18
uart_putc(40);
19
setReceiveMode();
20
}
21
}
22
}
23
}
Der Slave reagiert auf den Erhalt von 41 und sendet 40 zurück.
(Und wenn der Messwert zufällig auch noch so ist, dass das Lowbyte als
40 gelesen werden kann, dann kommt sowieso alles durcheinander)
eine Frage habe ich noch;
der Aufruf ShowValue( OutputColumn, 252, "A: %1d.%02d", Ampere );
das hier "A: %1d.%02d" da weis ich nicht wie ich mir eine funktion
schreiben muss.
Leider gibst beim compelieren einen Fehler in der zeile
void ShowValue( OutputColumn, 252, s ,uint16_t wert )
before numeric constant
1
//Prototyp
2
//void ShowValue(int Column, int y, const char *s, uint16_t wert);
3
4
voidShowValue(OutputColumn,252,s,uint16_twert)
5
{
6
charBuff1_V[20];
7
charBuff1_A[20];
8
charBuff1_W[20];
9
10
11
12
wert=((long)wert*36000)/1023;// A/D-Wert in Watt umrechnen (AREF=5V, 10 Bit A/D-Wandler:
ingo schrieb:> //Prototyp> //void ShowValue(int Column, int y, const char *s, uint16_t wert);>> void ShowValue( OutputColumn, 252, s ,uint16_t wert )> {
Besorg Dir ein C-Buch. Und lies das durch.
Dir hier mit Tips weiterzuhelfen ist bei Deinem eklatanten Mangel an
Grundlagenwissen vollkommen sinnlos.
Auch das Durchklicken durch irgendwelche C-Tutorials dürfte Dich nicht
wirklich weiterbringen.
Empfehlung: Brian Kernighan & Dennis Ritchie, "Programmieren in C",
zweite Ausgabe, Hanser-Verlag.