Hallo Leute, Ich nutze einen PIC24FJ128GB204 als Master und möchte eine I2C- Verbindung zu einem FT200XD (I2C zu USB) aufbauen. Die Verbindung kann auch aufgebaut werden. aber nach einigen Malen "hängt" der Controller sich beim Senden der Adresse bzw. des Lese/schreib Bits auf. Manchmal fängt er sich wieder und manchmal nicht. Ich habe hier mal zwei Bilder, die den Vorgang zeigen. Im Bild "unvollstaendigeNachricht" seht ihr den Beginn der Nachricht und wie plötzlich beim letzten Bit SDA auf low bleibt und SCL auf high. Das zweite Bild (RestDerNachricht) zeigt wie 54ms später der Rest der Nachricht kommt. Auch, dass danach eine komplette Nachricht ohne Probleme gesendet wird. Ich muss dazu erwähnen, dass der Controller vor dem Fehler bereits über 100 Mal die Nachricht korrekt gesendet hat und das so eine Sittuation immer zu einem anderen Zeitpunkt kommt. Leider rettet er sich immer nur maximal ein mal aus so einem Zustand. Danach bleibt er komplett mit SDA low und SCL high stehen. Ich habe für die Programmierung den MCC im MPLAB genutzt und vermute, dass dort das problem liegt, da ich nicht alles verstehe was dort programmiert wird. Ich teile mal den Code, den ich nutze hier: Die Funktion, die ich aufrufe um den den Inhalt des USB speichers abzufragen.
1 | uint8_t USB_Read( uint8_t *pData, uint16_t nCount) |
2 | {
|
3 | I2C2_MESSAGE_STATUS status; |
4 | //uint8_t writeBuffer[3];
|
5 | uint16_t retryTimeOut, slaveTimeOut; |
6 | uint16_t counter; |
7 | uint8_t *pD; |
8 | |
9 | pD = pData; |
10 | |
11 | for (counter = 0; counter < nCount; counter++) |
12 | {
|
13 | // this portion will read the byte from the memory location.
|
14 | retryTimeOut = 0; |
15 | slaveTimeOut = 0; |
16 | |
17 | while(status != I2C2_MESSAGE_FAIL) |
18 | {
|
19 | // write one byte to EEPROM (2 is the count of bytes to write)
|
20 | I2C2_MasterRead(pD,3,USB_ADDRESS,&status); |
21 | |
22 | // wait for the message to be sent or status has changed.
|
23 | while(status == I2C2_MESSAGE_PENDING) |
24 | {
|
25 | // add some delay here
|
26 | // timeout checking
|
27 | // check for max retry and skip this byte
|
28 | if (slaveTimeOut == USB_DEVICE_TIMEOUT) |
29 | return (0); |
30 | else
|
31 | slaveTimeOut++; |
32 | }
|
33 | |
34 | if (status == I2C2_MESSAGE_COMPLETE) |
35 | break; |
36 | |
37 | // if status is I2C2_MESSAGE_ADDRESS_NO_ACK,
|
38 | // or I2C2_DATA_NO_ACK,
|
39 | // The device may be busy and needs more time for the last
|
40 | // write so we can retry writing the data, this is why we
|
41 | // use a while loop here
|
42 | |
43 | // check for max retry and skip this byte
|
44 | if (retryTimeOut == USB_RETRY_MAX) |
45 | break; |
46 | else
|
47 | retryTimeOut++; |
48 | }
|
49 | |
50 | |
51 | // exit if the last transaction failed
|
52 | if (status == I2C2_MESSAGE_FAIL) |
53 | {
|
54 | return(0); |
55 | break; |
56 | |
57 | }
|
58 | |
59 | //pD++;
|
60 | }
|
61 | return(1); |
62 | }
|
Die Funktion, die immer wieder aufgerufen wird. (in dieser Frage ich erst Taster ab und dann den USB Speicher)
1 | void interruptProcedure(){ |
2 | switchStatus=checkSwitch(); // Übergebe die Variable an SwitchStatus, welcher Taster gedrückt ist, CheckSwitch() schaut in die LookUp arrSwitch) |
3 | if (switchStatus!=-1){ // wenn ungleich -1 dann wurde Taster gedrückt |
4 | if (switchStatus<16){ // wenn Nummer kleiner 16 wurde ein INPUT angewählt |
5 | actInputPort = switchStatus; //Schreibe die Nummer des INPUT in die Variable: actInputPort |
6 | }
|
7 | else{ |
8 | actOutputPort = switchStatus; // wenn Nummer größer 16, wurde ein OUTPUT angewählt, schreibe die Nummer des Input in die Variable: actOutputPort |
9 | }
|
10 | // Setze die einzelnen Muliplexerbausteine, je nach Configuration
|
11 | setGates(); |
12 | //errorHandling(errorNumber);
|
13 | }
|
14 | |
15 | |
16 | // Start der USB Abfrage
|
17 | // es geht immer nur lesen oder schreiben in einem Intrrupt-Durchlauf
|
18 | // Prüfen ob etwas im Empfangsregister liegt
|
19 | |
20 | switch (RecievedCommand[0]){ |
21 | case 0x01: // Setze Ports |
22 | actInputPort = (int)RecievedCommand[1] ; |
23 | actOutputPort = (int)RecievedCommand[2] +16; |
24 | setGates(); |
25 | Flag_R_W = false; |
26 | break; |
27 | |
28 | case 0x02: // Versions Ausgabe |
29 | SendArray[0] = RecievedCommand[0]; |
30 | SendArray[1] = RecievedCommand[1]; |
31 | SendArray[2] = RecievedCommand[2]; |
32 | SendArray[3] = 0x01; // Befehel OK |
33 | SendArray[4] = 0x56; // V |
34 | SendArray[5] = 0x31; // 1 |
35 | SendArray[6] = 0x2E; // . |
36 | SendArray[7] = 0x30; // 0 |
37 | SendArray[8] = 0x30; // 0 |
38 | Flag_R_W = false; |
39 | break; |
40 | case 0x03: // Status Abfrage |
41 | SendArray[0] = RecievedCommand[0]; |
42 | SendArray[1] = RecievedCommand[1]; |
43 | SendArray[2] = RecievedCommand[2]; |
44 | SendArray[3] = 0x01; // Befehel OK |
45 | SendArray[4] = 0x00; // 0 |
46 | SendArray[5] = 0x01; // 1 |
47 | SendArray[6] = 0x00; // 0 |
48 | SendArray[7] = 0x00; // 0 |
49 | SendArray[8] = 0x00; // 0 |
50 | Flag_R_W = false; |
51 | break; |
52 | case 0x04: // Selbsttest |
53 | SendArray[0] = RecievedCommand[0]; |
54 | SendArray[1] = RecievedCommand[1]; |
55 | SendArray[2] = RecievedCommand[2]; |
56 | SendArray[3] = 0x01; // Befehel OK |
57 | SendArray[4] = 0x00; // 0 |
58 | SendArray[5] = 0x01; // 1 |
59 | SendArray[6] = 0x00; // 0 |
60 | SendArray[7] = 0x00; // 0 |
61 | SendArray[8] = 0x00; // 0 |
62 | Flag_R_W = false; |
63 | break; |
64 | case 0x05: // Softreset |
65 | Softreset = true; |
66 | SendArray[0] = RecievedCommand[0]; |
67 | SendArray[1] = RecievedCommand[1]; |
68 | SendArray[2] = RecievedCommand[2]; |
69 | SendArray[3] = 0x01; // Befehel OK |
70 | SendArray[4] = 0x00; // 0 |
71 | SendArray[5] = 0x00; // 1 |
72 | SendArray[6] = 0x00; // 0 |
73 | SendArray[7] = 0x00; // 0 |
74 | SendArray[8] = 0x00; // 0 |
75 | break; |
76 | default:
|
77 | SendArray [0] = 0x00; |
78 | SendArray [1] = 0x00; |
79 | SendArray [2] = 0x00; |
80 | SendArray [3] = 0x02; // Fehler Befehl nicht bekannt |
81 | SendArray [4] = 0xFF; |
82 | SendArray [5] = 0xFF; |
83 | SendArray [6] = 0xFF; |
84 | SendArray [7] = 0xFF; |
85 | SendArray [8] = 0xFF; |
86 | Flag_R_W = true; |
87 | break; |
88 | }
|
89 | if (Flag_R_W){ |
90 | ERROR = USB_Read( RecieveLink, 1); |
91 | |
92 | }
|
93 | if (!Flag_R_W) |
94 | {
|
95 | ERROR = USB_Write(SendLink ,1); |
96 | RecievedCommand[0] = 0x00; |
97 | RecievedCommand[1] = 0x00; |
98 | RecievedCommand[2] = 0x00; |
99 | |
100 | |
101 | }
|
102 | }
|
Vielleicht kann mir jemand einen Hinweis geben, wo ich noch suchen kann, oder wo der Fehler ist. Schon mal vielen Dank im Voraus. Grüße