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
//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
unsignedchari2cbyte;
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
voidinit(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
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.