Forum: Mikrocontroller und Digitale Elektronik PIC16F18855 I2C Problem


von Nixda (Gast)


Lesenswert?

Hi Forum,
ich versuche gerade mit dem XPRESS Board ein 0,96" OLED anzusteuern. Bin 
noch dabei überhaupt die I2C ans laufen zu bekommen...

Das Prioblem ist, es kommt auf der I2C Leitung nichts raus. Die Pegel 
sind dauerhaft high. Ich teste es mit einem LA.

Meine Konfiguration sieht wie folgt aus:
1
#pragma config FEXTOSC = OFF    // External Oscillator mode selection bits (Oscillator not enabled)
2
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
3
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
4
#pragma config CSWEN = ON       // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
5
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)
6
7
// CONFIG2
8
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR pin is Master Clear function)
9
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
10
#pragma config LPBOREN = ON     // Low-Power BOR enable bit (ULPBOR enabled)
11
#pragma config BOREN = ON       // Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)
12
#pragma config BORV = HI        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) is set to 2.7V)
13
#pragma config ZCD = ON         // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
14
#pragma config PPS1WAY = OFF    // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
15
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
16
17
// CONFIG3
18
#pragma config WDTCPS = WDTCPS_15// WDT Period Select bits (Divider ratio 1:1048576)
19
#pragma config WDTE = OFF       // WDT operating mode (WDT Disabled, SWDTEN is ignored)
20
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
21
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)
22
23
// CONFIG4
24
#pragma config WRT = OFF        // UserNVM self-write protection bits (Write protection off)
25
#pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
26
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
27
28
// CONFIG5
29
#pragma config CP = OFF         // UserNVM Program memory code protection bit (Program Memory code protection disabled)
30
#pragma config CPD = OFF        // DataNVM code protection bit (Data EEPROM code protection disabled)
31
32
#define _XTAL_FREQ 32000000
33
34
void initPIC(void)
35
{
36
    TRISA = 0xF0;                   // RA0-3 out / RA4-7 in
37
    TRISC = 0x3E;                   // RC0,RC6,RC7 out / RC1,RC2,RC3,RC4,RC5 in
38
39
    ANSELA = 0x10;                  // RA4 Analog
40
}
41
42
void initI2C(void)
43
{
44
    /* Zugehörige Tris-Bits auf Input schalten */
45
    /* Master-Mode - Clock = Fosc / (4*(SSPxADD+1)) */  
46
    /* SSPxADD values of 0, 1 or 2 are not supported for I2C Mode */
47
    
48
    RC3PPS = 0x17;   //RC3->MSSP2:SDA2;
49
    RC4PPS = 0x16;   //RC4->MSSP2:SCL2;
50
    SSP2DATPPSbits.SSP2DATPPS = 0x13;   //RC3->MSSP2:SDA2;
51
    SSP2CLKPPSbits.SSP2CLKPPS = 0x14;   //RC4->MSSP2:SCL2; 
52
    
53
    SSP2CON1bits.SSPM3 = 1;
54
    SSP2CON1bits.SSPM2 = 0;
55
    SSP2CON1bits.SSPM1 = 0;
56
    SSP2CON1bits.SSPM0 = 0;
57
    SSP2CON1bits.SSPEN = 1;
58
    SSP2ADD = 0x13;                      // für 400kHz (Fosc = 32 MHz)
59
    SSP2CON2bits.ACKDT = 0;
60
}
61
62
63
void waitI2C(void)
64
{
65
    while(!PIR3bits.SSP2IF);          // Aktion* wurde beendet
66
    PIR3bits.SSP2IF = 0;              // Flag zurücksetzten
67
} 
68
 
69
// *Zum Beispiel: START-Sequenze, Übertragung von 8 Bit, ...
70
71
void idleI2C(void)
72
{
73
    while( SSP2STATbits.R_W );        // Läuft eine Übertragung?
74
    while( SSP2CON2 & 0x1F );         // Ist irgendwas anderes aktiv?
75
}
76
77
void startI2C(void)
78
{
79
    idleI2C(); // Ist der Bus frei?
80
    SSP2CON2bits.SEN = 1;             // Auslösen einer START-Sequenze
81
    while( SSP2CON2bits.SEN );        // Beendet, wenn SEN gelöscht wurde*
82
}
83
84
uint8_t sendI2C(uint8_t byte)
85
{
86
    idleI2C();                        // Ist der Bus verfügbar?
87
    PIR3bits.SSP2IF = 0;              // Flag löschen (wird in waitI2C() abgefragt)
88
    SSP2BUF = byte;                   // Durch füllen des Puffers Sendevorgang auslösen
89
    waitI2C();                        // Warten bis Übertragung abgeschlossen ist
90
91
    return ~SSP2CON2bits.ACKSTAT;     // Return 1: ACK empfangen, 0: kein ACK empfangen
92
}
Wenn ich etwas sende, komme ich bis zu:
1
while(!PIR3bits.SSP2IF);          // Aktion* wurde beendet
Hier hängt es dann..
Aber ich sehe auch schon bei
1
SSP2CON2bits.SEN = 1;             // Auslösen einer START-Sequenze
 nichts auf dem Bus. Immer dauerhaft high...
Denke es liegt irgendwie an dem Pin Mappuing aber finde meinen Fehler 
nicht...

von nils (Gast)


Lesenswert?

Könnte es sein, dass die I2C Pins RC3 und RC4 nicht als Eingang 
deklariert sein dürfen?

TRISC = 0x3E;

von holger (Gast)


Lesenswert?

>    SSP2DATPPSbits.SSP2DATPPS = 0x13;   //RC3->MSSP2:SDA2;
>    SSP2CLKPPSbits.SSP2CLKPPS = 0x14;   //RC4->MSSP2:SCL2;

Dürfen die beiden nicht nur 0 oder 1 sein?

von No Y. (noy)


Lesenswert?

So jetzt auch angemeldet..
Also laut Datenblatt müssen die Pins die ich mappen will auf Input 
stehen. Wäre also richtig. Das PPSLOCK Bit ist auch nicht gesetzt.. Habe 
ich geprüft.

Und laut tabelle 13-2 ist 0x13 und 0x14 korrekt. Hab auch im Beispiel 
nachgeschaut was es von Microchip gibt, passt...

von Peter C. (peter_c49)


Lesenswert?

Hallo Nixda,

ANSELCbits.ANSC3 = 0;
ANSELCbits.ANSC4 = 0;

ev sind die 2 pins noch auf Analog?

mfG

Peter

von Peter C. (peter_c49)


Lesenswert?

Hallo Nixda,

es regnet...also habe ich das Xpress mal wieder ausgepackt.

Du solltest wie ich schon vermutet hatte, die beiden Pins die du für I2C 
gemappt hast via ANSELC von dem Anlog-Modul(Comperator) trennen.
Dann funkioniert es bei mir mit dem OnBoard I2C Temp-Sensor.

hier ein link zu einem funktionierendem Beispiel, da wird es auch so 
gemacht https://mplabxpress.microchip.com/mplabcloud/example/details/98.

mfG
Peter ;-)

von No Y. (noy)


Lesenswert?

Hi Peter,
vielen Dank für den Hinweis. Es funktioniert jetzt. War wirklich nur das 
ANSELC=0;
was fehlte.
War das bei den "älteren" Pics auch so, dass die nach Reset die Eingänge 
alle auf dem Analog Input hatten?
Kann mich irgendwie nicht dran erinnern das immer entkoppeln zu 
müssen...
Oder ich hab es früher immer automatisch richtig gemacht...

Auf jedenfall vielen Dank!

von Peter C. (peter_c49)


Lesenswert?

Hallo No Y,

>War wirklich nur das ANSELC=0;

>War das bei den "älteren" Pics auch so, dass die nach Reset die Eingänge
alle auf dem Analog Input hatten?
Oh ja! (http://www.sprut.de/electronic/pic/fallen/fallen.html#analog)

Das ist bei fast allen PIC(8|24|32) noch immer eine Falle für die 
Vergesslichen.
Die neuen 16er, zb der auf dem Xpress Board umso mehr.
Die haben mehr Analoge Module als die alten.
Das digitale lässt sich mittlerweile bei allen neueren per PPS 
umstellen|mappen.
Analog ist das leider meist nicht der fall.
Also immer erst schauen ob da Analog Module am Pin dran sind falls was 
nicht wie erwartet funktioniert ist immer noch "gültig".

mfG

Peter ;-)

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
Noch kein Account? Hier anmelden.