Hallo,
habe ein kleines Problem, ein paar Bytes mit VisualBasic Express2008 aus
meinem ATmega32 zu lesen.
Mit der Funktion ConfigRead_Click sende ich ein 0xA1 an den ATmega, um
ihm zu sagen, was er schicken soll. Leider muß ich es 2-3 mal ausführen,
bis die Zeichen in richtiger Reihenfolge ankommen.
Teste ich es mit HTerm, funktioniert es tadellos. Wo habe ich einen
Fehler in der Empfangsroutine?
1 | Private Sub ConfigRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConfigRead.Click
| 2 | bytTransmit(0) = &HA1
| 3 | bytTransmit(1) = &H0
| 4 | SerialPort1.Write(bytTransmit, 0, 2)
| 5 | ReceiveBytes()
| 6 |
| 7 | Bel1EinStunden = bytReceived(0)
| 8 | Bel1EinschaltStunden.Value = CStr(Bel1EinStunden)
| 9 | Bel1EinMinuten = bytReceived(1)
| 10 | Bel1EinschaltMinuten.Value = CStr(Bel1EinMinuten)
| 11 | Bel1AusStunden = bytReceived(2)
| 12 | Bel1AusschaltStunden.Value = CStr(Bel1AusStunden)
| 13 | Bel1AusMinuten = bytReceived(3)
| 14 | Bel1AusschaltMinuten.Value = CStr(Bel1AusMinuten)
| 15 | ' Bel1EinschaltMinuten.Value = CStr(Bel1EinMinuten = bytReceived(1)) 'Beleuchtungszeit 1 Einschaltzeit Minuten
| 16 | ' Bel1AusschaltStunden.Value = CStr(Bel1AusStunden = bytReceived(2)) 'Beleuchtungszeit 1 Ausschaltzeit Stunden
| 17 | ' Bel1AusschaltMinuten.Value = CStr(Bel1AusMinuten = bytReceived(3)) 'Beleuchtungszeit 1 Ausschaltzeit Minuten
| 18 | End Sub
| 19 |
| 20 |
| 21 |
| 22 | Public Sub ReceiveBytes()
| 23 | ' receives it on serial port2
| 24 |
| 25 | 'dim includes the 0 case
| 26 | 'must be dimensioned or you will get a run time
| 27 | 'error with the "bytReceived(iI) = SerialPort2.ReadByte"
| 28 | 'below- this will be generalized
| 29 | Dim iI As Integer = 0
| 30 | While SerialPort1.BytesToRead > 0 Or iI = 0
| 31 | 'note that if we are waiting for a message
| 32 | 'the >0 will show as false immediately,
| 33 | 'so the iI=0 condition is added
| 34 | bytReceived(iI) = SerialPort1.ReadByte
| 35 | iI = iI + 1
| 36 | End While
| 37 | 'MsgBox("Number of bytes received- " & Str(iI) & vbCrLf & _
| 38 | 'BitConverter.ToString(bytReceived), _
| 39 | 'MsgBoxStyle.OkOnly, "Message Received")
| 40 | End Sub
|
Gruß Sascha
Sascha Focus schrieb:
1 | Dim iI As Integer = 0
| 2 | While SerialPort1.BytesToRead > 0 Or iI = 0
| 3 | 'note that if we are waiting for a message
| 4 | 'the >0 will show as false immediately,
| 5 | 'so the iI=0 condition is added
| 6 | bytReceived(iI) = SerialPort1.ReadByte
| 7 | iI = iI + 1
| 8 | End While
|
Nach dem ersten Durchlauf ist iI nicht mehr 0, aber vielleicht das
zweite Zeichen (wieviele Zeichen erwartest Du eigentlich?) noch nicht
eingetroffen, also .BytesToRead = 0 und die While Schleife bricht ab.
Du solltest entweder lesen (und dabei warten) bis Du ein eindeutiges
Endzeichen oder eine vorbestimmte Anzahl Zeichen empfangen hast.
Eventuell mit einem Timeout, falls etwas schiefgeht.
Hallo,
@severino, danke für deine Antwort. Habe es geändert und es
funktioniert.
Nun kommt (natürlich) das nächste Problem. Ich sende vom PC zum AVR bis
zu 64 Bytes ( nutze die Uart-Lib von Peter Fleury). Nun gehen teilweise
welche verloren, anstatt dem eigentlichen Wert dann eine 0. Das bei 10
Versuchen, ca. 4 mal.
Teste ich es anstatt dem AVR mit HTerm, sieht man, das alle Bytes
erfolgreich gesendet werden. Also liegt es jetzt am AVR Programm.
Hier der Teil der main.c 1 | unsigned int c;
| 2 | unsigned char Kommando;
| 3 | int main(void)
| 4 | {
| 5 | lcd_ini();
| 6 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
| 7 | Init_ISR();
| 8 |
| 9 | while(1)
| 10 | {
| 11 |
| 12 | lcd_gotoline(1);
| 13 | lcd_writezahl (STUNDE, 2, 0);
| 14 | lcd_writechar (':');
| 15 | lcd_writezahl (MINUTE, 2, 0);
| 16 | lcd_writechar (':');
| 17 | lcd_writezahl (SEKUNDE, 2, 0);
| 18 |
| 19 | lcd_gotoline(3);
| 20 | lcd_writezahl (Bel1EinStunden, 2, 0);
| 21 | lcd_writezahl (Bel1EinMinuten, 2, 0);
| 22 | lcd_writezahl (Bel1AusStunden, 2, 0);
| 23 | lcd_writezahl (Bel1AusMinuten, 2, 0);
| 24 | lcd_writezahl (BelDimbar, 2, 0);
| 25 | lcd_writezahl (Bel1Dimzeit, 2, 0);
| 26 | lcd_writezahl (Bel1DimMin, 2, 0);
| 27 | lcd_writezahl (Bel1DimMax, 2, 0);
| 28 | c = uart_getc();
| 29 | if ( c & UART_NO_DATA )
| 30 | {
| 31 | /*
| 32 | * no data available from UART
| 33 | */
| 34 | }
| 35 | else
| 36 | {
| 37 | Kommando = (c & 0xff);
| 38 | // 0xa0 = Uhrzeit vom PC empfangen
| 39 | // 0xa1 = Config an PC senden
| 40 | // 0xa2 = config vom PC empfangen
| 41 | switch (Kommando)
| 42 | {
| 43 | case (0xA0):
| 44 | Set_Time();
| 45 | break;
| 46 |
| 47 | case (0xA1):
| 48 | Write_Uart_Config();
| 49 | break;
| 50 |
| 51 | case (0xA2):
| 52 | Read_Uart_Config();
| 53 | break;
| 54 |
| 55 | default:
| 56 | ;
| 57 | break;
| 58 | }
| 59 |
| 60 |
| 61 | }
| 62 | }
| 63 |
| 64 | return 0;
| 65 | }
|
1 | void Read_Uart_Config(void)
| 2 | {
| 3 | unsigned char LowByte, HighByte;
| 4 | Bel1EinStunden = uart_getc();
| 5 | Bel1EinMinuten = uart_getc();
| 6 | Bel1AusStunden = uart_getc();
| 7 | Bel1AusMinuten = uart_getc();
| 8 | BelDimbar = uart_getc();
| 9 | Bel1Dimzeit = uart_getc();
| 10 | Bel1DimMin = uart_getc();
| 11 | Bel1DimMax = uart_getc();
| 12 | Bel2Aktiviert = uart_getc();
| 13 | Bel2EinStunden = uart_getc();
| 14 | Bel2EinMinuten = uart_getc();
| 15 | Bel2AusStunden = uart_getc();
| 16 | Bel2AusMinuten = uart_getc();
| 17 | Bel2Dimzeit = uart_getc();
| 18 | Bel2DimMin = uart_getc();
| 19 | ...
| 20 | }
|
Gruß Sascha
Sascha Focus schrieb:
> Teste ich es anstatt dem AVR mit HTerm, sieht man, das alle Bytes
> erfolgreich gesendet werden. Also liegt es jetzt am AVR Programm.
Also mach im Forum "µC & Elektronik" einen neuen passenden Thread auf.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|