Forum: Mikrocontroller und Digitale Elektronik EEPROM SPI antwortet nicht über PIC16F1828


von Mark J. (markjo)


Angehängte Dateien:

Lesenswert?

Guten Tag,

ich versuche ein SPI EEPROM (M95640) mit einem PIC Microcontroller 
PIC16F1828 über SPI auszulesen. Die Daten auf der Outputleitung des PIcs 
werden erfolgreich in der richtigen Reihenfolge gesendet. Zuerst der 
READ Befehl (Instruction) dann die Adresse auf der ich Lesen will und 
anschließen müsste ich eine Antwort vom EEPROM bekommen über die 
Inputleitung des PICs, leider habe ich keine Erfolg und das EEPROM 
antwortet nicht. Der CHIPselect wird auch erfolgreich gesetzt, welches 
ich mit einem OSzi überprüft habe. Das ganze erfolgt in C- Code. Das 
OSZIbild befindet sich im Anhang in gelb der CLOCK welcher immer 8 mal 
taktet, in der Mitte die INPUT Leitung und ganz unten die Output 
Leitung.
Den C-Code habe ich auch hinzugefügt. Kann mir auch jemand sagen warum 
ich beim Clock immer diese riesigen Pausen habe? Ich habe schon alles 
versucht ich kriege die Pausen einfach nicht weg.;(

Ich wäre um jede Hilfe dankbar.

Mfg
Mark

1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
2
#pragma config WDTE = OFF        // Watchdog Timer Enable (WDT enabled)
3
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
4
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
5
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
6
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
7
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
8
#pragma config CLKOUTEN = ON   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
9
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
10
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
11
12
// CONFIG2
13
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
14
#pragma config PLLEN = OFF       // PLL Enable (4x PLL enabled)
15
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
16
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
17
#pragma config LVP = ON  
18
19
20
#include <xc.h>
21
#include <pic16f1828.h>
22
#include <stdint.h>
23
24
#define SCK PORTBbits.RB6 //Serial Clock
25
#define SDI LATCbits.LATC4 //Serial Data In
26
#define SD0 PORTCbits.RC7 //Serial Data Out
27
#define SS LATCbits.LATC6 //Slave Select
28
29
30
#define SCK_dir TRISBbits.TRISB6
31
#define SDI_dir TRISBbits.TRISB4
32
#define SDO_dir TRISCbits.TRISC7
33
#define SS_dir TRISCbits.TRISC6
34
35
// EEPROM SPI Instructions
36
#define WREN 0x06 //Write enable       
37
#define WRDI 0x04 //Write disable       
38
#define WRITE 0x02 //Write to Memory Array
39
#define READ 0x03 // Read from Memory Array
40
#define RDSR 0x05 // Read Status register
41
42
43
void SPI_initMaster();
44
void SPI_write(char data);
45
char SPI_read(char dummy);
46
void EEPROM_write(int address,char data);
47
char EEPROM_read(int address);
48
char EEPROM_status();
49
char EEPROM_busy();
50
51
void main(void) {
52
    
53
    
54
        OSCCONbits.SCS= 0b10; //internal Oscillator   
55
        OSCCONbits.IRCF=0b1011;   //1MHz
56
57
58
        int address = 0x0409;
59
        SPI_initMaster();
60
        EEPROM_read(address);
61
 
62
    return;
63
}
64
65
void SPI_initMaster()
66
{
67
        
68
        SS_dir = 0; 
69
        SCK_dir = 0;
70
        SDI_dir = 1;
71
        SDO_dir = 0;
72
        
73
    
74
        SSP1CON=0b00100000;
75
        SSP1STAT=0b01000000;
76
        
77
      
78
}
79
80
void SPI_write(char data)
81
{
82
        SSP1BUF = data;
83
        while(SSP1STATbits.BF== 0);
84
85
}
86
//-----------------------------------------------------------------------------
87
88
char SPI_read(char dummy)
89
{
90
        SSP1BUF = dummy; 
91
        while(SSP1STATbits.BF== 0);
92
        return SSP1BUF;
93
}
94
95
96
//------------------------------------------------------------------------------
97
char EEPROM_read(int address)
98
{
99
100
     
101
        SS=0;
102
        SPI_write(READ);
103
        SPI_write(address>>8); //Upper Byte
104
        SPI_write(address); //Lower Byte
105
        char data = SPI_read(0);
106
        
107
  
108
        SS=1;
109
        return data;
110
}

von Forist (Gast)


Lesenswert?

Mark J. schrieb:
> ich versuche ein SPI EEPROM (M95640) mit einem PIC Microcontroller
> PIC16F1828 über SPI auszulesen. Die Daten auf der Outputleitung des PIcs
> werden erfolgreich in der richtigen Reihenfolge gesendet.

SPI unterscheidet nicht zwischen lesen und schreiben. Es wird immer 1 
Byte vom Master zum Slave und eins vom Slave zum Master übertragen.
Aus deinem Oszi-Bild kann man leider nicht viel erkennen, weil die 
Zeitauflösung nicht reicht. Hast du den richtigen SPI-Mode gewählt - es 
gibt vier davon.

Was verbirgt sich hinter SSP1CON=0b00100000 und SSP1STAT=0b01000000?
(magic numbers?)

Mark J. schrieb:
> Oszi_SPI.jpeg

p.s.
Guck mal auf dein Oszi. Da gibt es einen USB-Slot und eine Save Taste - 
was könnte das wohl bedeuten.

p.p.s.
1
Wichtige Regeln - erst lesen, dann posten!
2
...
3
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

von Frank K. (fchk)


Lesenswert?

Meine Vermutung: Analogfunktionen an den Pins nicht abgeschaltet.

ANSELA=0;
ANSELB=0;
ANSELC=0;

Typischer Anfängerfehler.

fchk

von Klaus S. (kseege)


Lesenswert?

Mark J. schrieb:
> Zuerst der
> READ Befehl (Instruction) dann die Adresse auf der ich Lesen will und
> anschließen müsste ich eine Antwort vom EEPROM bekommen über die
> Inputleitung des PICs, leider habe ich keine Erfolg und das EEPROM
> antwortet nicht

Ist es sicher, dass im EEPROM etwas anderes als 0 steht?
Hängt MISO korrekt am Oszi?
SPI-Mode wurde schon erwähnt.

Mark J. schrieb:
> Kann mir auch jemand sagen warum
> ich beim Clock immer diese riesigen Pausen habe?

Steht so im Programmcode drin:
while (SSP1STATbits.BF== 0);
Der Controller braucht es wohl so.

Gruß Klaus (der soundsovielte)

von Mark J. (markjo)


Lesenswert?

Klaus S. schrieb:
> Steht so im Programmcode drin:
> while (SSP1STATbits.BF== 0);
> Der Controller braucht es wohl so.

Hallo selbst wenn ich die while Schleife weglassen und allles 
hintereinander in den buffer schreibe habe ich die Pausen beim takten 
normalerweise dürfte ja keine Pause sein und der takt muss durchlaufen. 
Beim lese Befehl Adressbefehl und bei der Antwort vom eeprom.

von Mark J. (markjo)


Lesenswert?

Forist schrieb:
> Was verbirgt sich hinter SSP1CON=0b00100000 und SSP1STAT=0b01000000?
> (magic numbers?)

Das ist das controllregister damit habe ich den spi mode aktiviert clock 
fosc/4 und die ports wurden damit aktiviert sdi sdo clk und slaveselect. 
Beim statusregister habe ich cke1 auf 1 gesetzt aufgrund der Polarität 
des CLOCKS.

von jau (Gast)


Lesenswert?

Frank K. schrieb:
> Meine Vermutung: Analogfunktionen an den Pins nicht abgeschaltet.
>
> ANSELA=0;
> ANSELB=0;
> ANSELC=0;
>
> Typischer Anfängerfehler.
>
> fchk

Jau !!!!!

von Klaus S. (kseege)


Lesenswert?

Frank K. schrieb:
> Meine Vermutung: Analogfunktionen an den Pins nicht abgeschaltet.

Wenn SCK und MOSI aus dem uC rauskommen, muß auf MISO die Antwort vom 
EEPROM kommen und auf dem Oszi sichtbar sein, wenn MISO ein Eingang am 
uC ist und kein Ausgang. Zur Not könnte man die Verbindung auftrennen.

Ich würde erstmal das EEPROM woanders einlesen und kontrollieren, ob die 
Inhalte von Null verschieden sind. Ansonsten wäre der Inhalt richtig zu 
0 beantwortet und die Funktion fehlerfrei ausgeführt.

Nach meinem Wissensstand sind die Pausen völlig unkritisch, SCK muß 
keineswegs durchlaufen.

Der Modus scheint auch richtig zu sein, soweit man das auf dem 
Oszillogramm sehen kann. Die Daten vom uC werden bei steigender 
SCK-Flanke übernommen und sollten bei fallender Flanke geändert werden, 
zumindest verstehe ich das Datenblatt so. Das sollte man aber am Oszi 
nochmal nachkontrollieren und SCK und MOSI übereinanderlegen.

Gruß Klaus (der soundsovielte)

von Klaus S. (kseege)


Lesenswert?

Kleiner Nachtrag:
Ein Schreibbefehl mit nachfolgendem Lesebefehl auf dieselbe Adresse 
könnte auch noch zur Erleuchtung beitragen.

von Mark J. (markjo)



Lesenswert?

Klaus S. schrieb:
> Kleiner Nachtrag:
> Ein Schreibbefehl mit nachfolgendem Lesebefehl auf dieselbe Adresse
> könnte auch noch zur Erleuchtung beitragen.

Ich habe versucht die Analogfunktionen auszustellen leider kein Erfolg. 
Ich habe mal versucht was in eine Adresse zu schreiben und dann 
auszulesen leider kein Erfolg. Oszi Bild im Anhang. Auf der MISO Leitung 
ist immer nur eine 0 zu sehen. Die 0 habe ich vom SPI DECODER im OSZI 
abgelesen.

von Frank K. (fchk)


Lesenswert?

Idee: MISO und MOSI irgendwo zwischen Prozessor und EEPROM vertauscht?

Schaltplan?

fchk

von Peter D. (peda)


Lesenswert?

Lege mal einen Pullup an MISO. Dann sollte zu sehen sein, wann der 
EEPROM aktiv auf low zieht.
Oder lege mit 2 Widerständen den MISO auf VCC/2.

von Mark J. (markjo)


Angehängte Dateien:

Lesenswert?

Frank K. schrieb:
> Idee: MISO und MOSI irgendwo zwischen Prozessor und EEPROM
> vertauscht?
>
> Schaltplan?
>
> fchk


Hallo RB4 habe ich an PIN 2(Q) angeschlossen.
RB6 an C
RC6 an S
RC7 an D
HOLD und W an GROUND
VCC sind 5 V

Plan befindet sich im Anhang.

von Mark J. (markjo)


Lesenswert?

Peter D. schrieb:
> Lege mal einen Pullup an MISO. Dann sollte zu sehen sein, wann der
> EEPROM aktiv auf low zieht.
> Oder lege mit 2 Widerständen den MISO auf VCC/2.

Hallo ich habe mal 2 Pull up Widerstände angelegt jetzt ist die Leitung 
konstant auf 5V aber sonst keine Veränderung.

von Klaus S. (kseege)


Lesenswert?

Mark J. schrieb:
> HOLD und W an GROUND

Das nennt man dann wohl Selbstüberlistung.
/HOLD auf GROUND heißt: SCK wird nicht weitergeleitet => 
Datenübertragung pausiert
/W an GROUND heißt: Schreibvorgang verboten.

Kann es sein, daß Du kein Englisch verstehst und lernen solltest, wie 
man "Google Translator" bedient?

Gruß Klaus (der soundsovielte)

von Peter D. (peda)


Lesenswert?

Mark J. schrieb:
> HOLD und W an GROUND

Ja, dann bleibt er in tristate.

von Mark J. (markjo)


Lesenswert?

Klaus S. schrieb:
> Mark J. schrieb:
>> HOLD und W an GROUND
>
> Das nennt man dann wohl Selbstüberlistung.
> /HOLD auf GROUND heißt: SCK wird nicht weitergeleitet =>
> Datenübertragung pausiert
> /W an GROUND heißt: Schreibvorgang verboten.
>
> Kann es sein, daß Du kein Englisch verstehst und lernen solltest, wie
> man "Google Translator" bedient?
>
> Gruß Klaus (der soundsovielte)


OK danke das RDSR Register vom EEPROM kann ich auslesen ich erhalte dann 
auch eine Antwort MISO Leitung, jedoch funktioniert das lesen und 
beschreiben des EEPROMs noch nicht.

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.