Hallo zusammen, ich mache gerade die ersten Schritte mit PIC32 Controller und habe hierbei noch ein paar Probleme. Ich hab davor viel mit den Serien PIC12, PIC16 und PIC18 gemacht, bin also kein Neuling im Bereich PIC Controller. Mein Problem ist folgendes, ich möchte mit dem Controller die I2C Schnittstelle initialisieren und Slaves ansprechen. Nach dem ich das PIC32 Reference Manual durch hatte, habeich festgestellt das die Architektur und der Umfang der Einstellungen beim PIC32 sehr viel größer sind als beim den anderen PICs bei dennen ich diese Schnittstelle bereits verwendet habe. Mein Arbeitskollege meinte ich soll den Controller am besten mit dem C32 Compiler programmieren. Ich habe bisher immer den Hi-Tech verwendet, daher ist mir der Compiler von den Befehlen neu. Hat jemand von Euch schon einmal mit der I2C Schnittstelle bei den PIC32 Controllern und dem C32 Compiler gearbeitet? Ich bin über jede Hilfe dankbar. Über die Googlesuche bin ich nicht wirklich weiter gekommen. Den Controller den ich verwende ist der PIC32MX795F512L. Vielen Dank. Gruß Chris
Es gibt im Verzeichniss worin der C32 installiert ist für fast jede Peripherie ein Beispiel. Auch wenn diese meist für ein bestimmtes DevBoard von MICROCHIP geschrieben sind, kann man diese relativ leicht anpassen. I2C z.b. unter ....mplab32/v2.02/examples/plib_examples/i2c/i2c_master/source..... ein Beispiel für den Zugriff auf ein 25LC256 EEPROM.
Davon abgesehen würde ich mir MPLABX 1.85 und den dazugehörigen Compiler XC32 1.21 installieren da MPLAB (letzte Ver. 8.92) nicht mehr weiter unterstützt wird (und wahrscheinlich auch der C32 nicht).
Das habe ich gefunden, aber ich vermisse dabei z.B. eine Funktion mit der man die Schnittstelle initialisiert. Mir ist klar das man dann sicher noch einiges anpassen muss, dennoch muss ja die Geschwindigkeit und verwendete Pins irgendwo eingerichtet werden.
Chris B. schrieb: > Davon abgesehen würde ich mir MPLABX 1.85 und den dazugehörigen Compiler > XC32 1.21 installieren da MPLAB (letzte Ver. 8.92) nicht mehr weiter > unterstützt wird (und wahrscheinlich auch der C32 nicht). Ah okay wusste ich noch gar nicht, dann steige ich vllt gleich auf das Programm und den Compiler um da das projekt auch später evtl softwareseitig erweitert werden muss.
Chris Br schrieb: > Das habe ich gefunden, aber ich vermisse dabei z.B. eine Funktion mit > der man die Schnittstelle initialisiert. > > Mir ist klar das man dann sicher noch einiges anpassen muss, dennoch > muss ja die Geschwindigkeit und verwendete Pins irgendwo eingerichtet > werden. In dem Beispiel gibt es auche eine Datei <HardwareProfile.h> wo unter anderem!! <I2C_CLOCK_FREQU 100000 > definiert ist. Initialisiert wird mit ....actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ);
> In dem Beispiel gibt es auche eine Datei <HardwareProfile.h> wo unter > anderem!! <I2C_CLOCK_FREQU 100000 > definiert ist. > > Initialisiert wird mit > ....actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), > I2C_CLOCK_FREQ); Das ist alles? Muss man keine Register wie das I2CxCON beschreiben, damit der Controller erstmal weiß ob er Master oder Slave ist? Find ich seltsam das es von Micriochip dann ein Reference Manual gibt in dem das alles beschrieben ist wie welches Register beschrieben sein muss und in Ihrem Beispiel wenden Sie das gar nicht an.
So solangsam blick ich bei dem MPLABX und dem Controller durch. Aktuell habe ich folgendes Problem mit dem I2C, wenn ich das CON Register beschrieben habe und anschließend die Startsequenz mit dem SEN bit einleite wird dieses gleich wieder deaktiviert und das BCL (Bus collision bit) wird gesetzt. Jemand eine Idee woran das liegen kann?
Chris Br schrieb: > Das ist alles? > Muss man keine Register wie das I2CxCON beschreiben, damit der > Controller erstmal weiß ob er Master oder Slave ist? > > Find ich seltsam das es von Micriochip dann ein Reference Manual gibt in > dem das alles beschrieben ist wie welches Register beschrieben sein muss > und in Ihrem Beispiel wenden Sie das gar nicht an. zum 1.: Na gut ich habe mir jetzt nicht jedes Bit der I2C-SFR angesehen und auch nicht die Defaultwerte nach einem Reset angesehen, bin aber ziemlich sicher das ein simples I2C1CON = 0 und ein enstprechender Wert für die Busgeschwindigkeit in das enstsprechende Register das I2C-Modul in die Grundeinstellung "MasterMode, 7-Bit-Adresse" schaltet. Das reicht für irgendwelche poppeligen EEPROM sicher aus ;-) zum 2.: Was die eingebundene <plib> alles kann, ist in <i2c.h> ersichtlich und das ist wesentlich mehr als die paar Einstellungen die für einen EEPROM-Zugriff notwendig sind (wie in dem angeführten Beispiel). Dort sind auch für jede Funktion Beispiel angeführt. Falls es irgendwelche speziellen I2C-Eigenschaften gibt, welche NICHT durch die <plib>-Funktionen abgedeckt sind - dafür braucht man dann das Reference Manual. Aber dann die ausführliche Version (DS61116E) und nicht das allgemeine, wo die Sektion "I2C" gerade mal das Blockdiagramm und die paar Kontrollregister enthält.
So ich bin inzwischen einen Schritt weiter gekommen. Ich hab jetzt mal mithilfe der plib.h ein Programm geschrieben das scheinbar auch durchläuft, aber am Port selbst kann ich mit dem Oszi keinerlei Pegeländerungen messen. Hier einmal mein Programm, wenn jemand etwas findet was ich nicht beachtet habe wäre ich für Eure Hilfe dankbar. Hier die ist der code meiner main.c
1 | #include <p32xxxx.h> |
2 | #include <plib.h> |
3 | #include <peripheral/i2c.h> |
4 | #include "init.h" |
5 | |
6 | |
7 | // Configuration Bit settings
|
8 | // SYSCLK = 80 MHz (8MHz Crystal / FPLLIDIV * FPLLMUL / FPLLODIV)
|
9 | // PBCLK = 80 MHz (SYSCLK / FPBDIV)
|
10 | // Primary Osc w/PLL (XT+,HS+,EC+PLL)
|
11 | // WDT OFF
|
12 | // Other options are don't care
|
13 | #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
|
14 | #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
|
15 | #define SYS_FREQ (80000000L)
|
16 | |
17 | #define CCLK (SYS_FREQ)
|
18 | #define PBCLK (SYS_FREQ/8)
|
19 | |
20 | #define Fsck 375000
|
21 | #define BRG_VAL (PBCLK/2/Fsck)
|
22 | |
23 | #define Nop() asm( "nop" )
|
24 | |
25 | UCHAR8 SlaveAddress; |
26 | char i2cData[10]; |
27 | int DataSz; |
28 | |
29 | |
30 | void i2c_wait(unsigned int cnt) |
31 | {
|
32 | while(--cnt) |
33 | {
|
34 | Nop(); |
35 | Nop(); |
36 | }
|
37 | }
|
38 | |
39 | |
40 | void main(void) |
41 | {
|
42 | |
43 | init(); |
44 | |
45 | OpenI2C2( I2C_EN, BRG_VAL ); |
46 | |
47 | SlaveAddress = 0x57; // 1010 111 0 |
48 | |
49 | i2cData[0] = (SlaveAddress << 1) | 0; |
50 | i2cData[1] = 0x0A; |
51 | i2cData[2] = 0x00; |
52 | i2cData[3] = 0xAA; |
53 | DataSz = 4; |
54 | |
55 | StartI2C2(); // Sende das Start Bit |
56 | IdleI2C2(); //Warten bis Ende |
57 | |
58 | int Index = 0; |
59 | while(DataSz) |
60 | {
|
61 | MasterWriteI2C1(i2cData[Index++]); |
62 | IdleI2C2(); |
63 | |
64 | DataSz--; |
65 | |
66 | //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not
|
67 | //acknowlede the data
|
68 | if(I2C2STATbits.ACKSTAT) |
69 | break; |
70 | }
|
71 | |
72 | StopI2C2(); |
73 | IdleI2C2(); |
74 | |
75 | while(1) |
76 | {
|
77 | i2c_wait(10); |
78 | |
79 | StartI2C2(); |
80 | IdleI2C2(); |
81 | |
82 | MasterWriteI2C2(i2cData[0]); |
83 | IdleI2C2(); |
84 | |
85 | if(I2C2STATbits.ACKSTAT == 0) |
86 | {
|
87 | StopI2C2(); |
88 | IdleI2C2(); |
89 | |
90 | break; |
91 | }
|
92 | |
93 | StopI2C2(); |
94 | IdleI2C2(); |
95 | }
|
96 | |
97 | //Now Readback the data from the serial eeprom
|
98 | |
99 | i2cData[0] = (SlaveAddress << 1) | 0; |
100 | i2cData[1] = 0x05; |
101 | i2cData[2] = 0x40; |
102 | DataSz = 3; |
103 | |
104 | StartI2C2(); |
105 | IdleI2C2(); |
106 | |
107 | Index = 0; |
108 | while(DataSz) |
109 | {
|
110 | MasterWriteI2C2(i2cData[Index++]); |
111 | IdleI2C2(); |
112 | |
113 | DataSz--; |
114 | //ACKSTAT is 0 when slave acknowledge. if 1 then slave has not
|
115 | //acknowlede the data
|
116 | if(I2C2STATbits.ACKSTAT) |
117 | break; |
118 | }
|
119 | |
120 | //now send a start sequence again
|
121 | RestartI2C2(); |
122 | IdleI2C2(); |
123 | |
124 | MasterWriteI2C2((SlaveAddress << 1)| 1); |
125 | IdleI2C2(); |
126 | |
127 | unsigned char i2cbyte; |
128 | i2cbyte = MasterReadI2C2(); |
129 | |
130 | StopI2C2(); |
131 | IdleI2C2(); |
132 | |
133 | if(i2cbyte != 0xAA) |
134 | {
|
135 | while(1) //Error |
136 | {
|
137 | PORTDbits.RD1 = 1; |
138 | }
|
139 | }
|
140 | |
141 | while(1) //Success |
142 | {
|
143 | PORTBbits.RB10 = 1; |
144 | }
|
145 | |
146 | }
|
und hier noch die init.c
1 | #include <p32xxxx.h> |
2 | |
3 | void init(void) |
4 | {
|
5 | AD1PCFG = 0xFFFF; // PORTS auf Digital umschalten |
6 | |
7 | TRISBbits.TRISB10 = 0; // TRIS Register für LED |
8 | TRISDbits.TRISD1 = 0; // TRIS Register für LED |
9 | TRISDbits.TRISD2 = 0; // TRIS Register für LED |
10 | PORTBbits.RB10 = 0; // LED = 0 setzen |
11 | PORTDbits.RD1 = 0; // LED = 0 setzen |
12 | PORTDbits.RD2 = 0; // LED = 0 setzen |
13 | |
14 | TRISAbits.TRISA15 = 1; // PORT RA14 als Eingang definieren --> SCL1 |
15 | TRISAbits.TRISA14 = 0; // PORT RA15 als Eingang definieren --> SDA1 |
16 | LATA = 0; |
17 | // TRISAbits.TRISA2 = 1; // PORT RA14 als Eingang definieren --> SCL2
|
18 | // TRISAbits.TRISA3 = 1; // PORT RA15 als Eingang definieren --> SDA2
|
19 | |
20 | }
|
Dieses Programm ist ein example von Microchip, von dort ist alles bis auf die Port Init und dort liegt vermutlich auch das Problem. Danke schonmal im Vorraus. Gruß Chris
>aber am Port selbst kann ich mit dem Oszi >keinerlei Pegeländerungen messen. Und wo ist der Pegel? Mach mal Pullups auf SDA und SCL.
holger schrieb: >>aber am Port selbst kann ich mit dem Oszi >>keinerlei Pegeländerungen messen. > > Und wo ist der Pegel? Mach mal Pullups auf SDA und SCL. Die Pullups sind drauf 4,7k gegen 3,3V zu SDA und zu SCL. Der Pegel ist also immer auf 3,3V und ändert sich auch nicht. Hab das programm auch mal mit dem Debugger durchgearbeitet, hier hat sich aber auch nichts geändert. Was ich sehr komisch finde ist das der Controller die Acknowledge abfrag durchläuft obwohl der Bus eindeutig high ist.
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.