MCP3911 SPI-Interface funktioniert nicht

#4206806
Lesenswert?

Um mich kurz zu fassen: Ich habe für meine Diplomarbeit die Aufgabe 
bekommen ein Messgerät für E-Autos zu bauen. Nach zahlreichen 
Fehlschlägen bei der Messung bin ich auf den MCP3911 gekommen.
Alles Klar. Testprogramm geschrieben und mit PICKIT2 Werte an den PC 
gesendet. Dann die enttäuschung: Es kommt je nach Versuch nur 0, 1, -1 
oder 255 am Terminal an.
Nochmal alles überprüft, Programm neu geschrieben, wieder nichts.
Dann habe ich einfach ein paar Register beschrieben und ausgelesen: aber 
es kommt nur 0 oder 255 raus.

Hatte schon mal jemand ein ähnliches Problem oder kann mir jemand 
helfen?
Sitze seit 3 Tagen ununterbrochen vorm Bildschirm aber es wird nicht 
besser.

Hier der größte Teil des Programms:
1
#include  "C:\Users\Michael\Documents\Schule\Microcontroller\PICC\Devices\18F2550.h"
2
#include  "C:\Users\Michael\Desktop\Netzanalyse\Programme\PIC18F2550\MCP3911 Test\Hardware.h"
3
#include  "C:\Users\Michael\Desktop\Netzanalyse\Programme\PIC18F2550\MCP3911 Test\MCP3911_EVB.h"
4
#device  ADC = 10
5
#fuses  NOWDT, NOPUT, HSPLL, PLL5, CPUDIV1, NOMCLR  
6
#use    delay(clock=48M)        
7
#use    rs232(Stream=PICKIT2,Baud = 38400, FORCE_SW, RCV = pin_b6, XMIT = pin_b7)
8

9

10

11

12
#define CS_delay      50
13
#define  VDD        4000
14
#define CH0_VAL_H      0x00      //READ-ONLY, ADC-Daten
15
#define CH0_VAL_M      0x01      //READ-ONLY, ADC-Daten
16
#define CH0_VAL_L      0x02      //READ-ONLY, ADC-Daten
17
#define CH1_VAL_H      0x03      //READ-ONLY, ADC-Daten
18
#define CH1_VAL_M      0x04      //READ-ONLY, ADC-Daten
19
#define CH1_VAL_L      0x05      //READ-ONLY, ADC-Daten
20
#define MOD         0x06      //Wegen ADC-Genauigkeit darf hier nicht geschrieben werden, Modulator-Daten
21
#define PHASE_H        0x07      //Bei WRITE --> RESET, Phasen-Delay: Bit 0-7
22
#define PHASE_L        0x08      //Bei WRITE --> RESET, Phasen-Delay: Bit 8-11 Bit 11-15 = 0
23
#define GAIN        0x09      // GAIN2: Bit 0-2 GAIN1: Bit 3-5 BOOST: Bit 6-7
24
#define STATUS_H       0x0A      
25
#define STATUS_L       0x0B      
26
#define CONFIG_H       0x0C      // CLKEXT: Bit 1  VREFEXT: Bit 2 SHUTDOWN: Bit 4-5 RESET: Bit 6-7
27
#define CONFIG_L       0x0D    //AZFREQ: Bit 8 DITHER: Bit 9-10 OSR Bit: 11-13 PRE: 14 -15
28
#define CH0_OFF_H      0x0E      // CH0 OFFSET: Bit 0-7
29
#define CH0_OFF_M      0x0F      // CH0 OFFSET: Bit 8-15
30
#define CH0_OFF_L      0x10      // CH0 OFFSET: Bit 16-23
31
#define CH0_GAIN_H      0x11      // CH0 GAIN-ERROR: Bit 0-7
32
#define CH0_GAIN_M      0x12      // CH0 GAIN-ERROR: Bit 7-15
33
#define CH0_GAIN_L      0x13      // CH0 GAIN-ERROR: Bit 15-23
34
#define CH1_OFF_H      0x14      // CH1 OFFSET: Bit 0-7
35
#define CH1_OFF_M      0x15      // CH1 OFFSET: Bit 8-15
36
#define CH1_OFF_L      0x16     // CH1 OFFSET: Bit 16-23
37
#define CH1_GAIN_H      0x17      // CH1 GAIN-ERROR: Bit 0-7
38
#define CH1_GAIN_M      0x18      // CH1 GAIN-ERROR: Bit 8-15
39
#define CH1_GAIN_L      0x19      // CH1 GAIN-ERROR: Bit 15-23
40
#define V_REF        0x1A      //READ-ONLY, VREF einstellen
41

42

43
unsigned char internal_registers[27];
44

45
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
46
/*****************************************************
47
* Local Prototypes
48
*****************************************************/
49
void Init_PIC(void);
50
void Write3911(unsigned char address, unsigned char data);
51
unsigned char Read3911(char addres);
52
void Read_Internal_Registers(void);
53
void Print_Internal_Registers(void);
54

55

56

57

58
int16  adcValueVDD;
59
int16   VoltA, VoltD;
60
int8    spidata;
61

62
// Hauptprogramm
63
void main() 
64
{
65
  delay_ms(2000);
66
  Init_PIC();
67
  
68
  output_low(SS_Pin);
69
  delay_us(CS_delay);
70
  spi_write(0b00011010);  // Adresse Config-2
71
  spi_write(0b11000000);  // CONFIG2: Beide ADC-Reset
72
  output_high(SS_Pin);
73
  delay_us(CS_delay);
74
  output_low(SS_Pin);
75
  delay_us(CS_delay);
76
  spi_write(0b00001110);  // Adresse Phase 
77
  spi_write(0b00000000);  // PHASE: Bit 15- 8 
78
  spi_write(0b00000000);  // PHASE: Bit 7- 0
79
  spi_write(0b10000000);   // GAIN: 
80
  spi_write(0b00011111);   // STATUSCOM2: Bit 15-8 
81
  spi_write(0b00100000);   // STATUSCOM1: Bit 7-0: immer das gleiche register lesen
82
  spi_write(0b00000110);  // CONFIG2:
83
  spi_write(0b00000000);  // CONFIG1: Beide ADC-Reset Ende
84
  output_high(SS_Pin);
85
  delay_us(CS_delay);
86
  Read_Internal_Registers();
87
  Print_Internal_Registers();
88
  
89
  while(1)
90
  {
91
    
92
  //  Read3911(CH0_VAL_M);
93
  //  Read3911(CH0_VAL_L);
94
  //  output_high(SS_Pin);
95
  //  delay_us(CS_delay);
96
  //  Write3911(GAIN,0b11111111);
97
  //  delay_ms(100);
98
  //  fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
99
  //  fprintf(PICKIT2,"SPI: %u",Read3911(GAIN));
100

101
  }
102
}  
103

104
void Init_PIC(void)        // Gibt die Spannungen über das PICKIT2-UART-Tool an den PC
105
{
106
  fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
107
  fprintf(PICKIT2,"Initialisierung");
108
  setup_adc(ADC_CLOCK_INTERNAL);    // ADC-Konfiguration
109
  setup_adc_ports(AN0_TO_AN1|VSS_VDD);
110

111
  set_adc_channel(AVDD);      // MCP3911-Steckbrett Spannungsmessung und ADC-Test
112
  delay_us(100);  
113
  adcValueVDD = read_adc();
114
  VoltA = (adcValueVDD / (double) 1023) * VDD;
115
  
116
  set_adc_channel(DVDD);
117
  delay_us(100);
118
  adcValueVDD = read_adc();
119
  VoltD = (adcValueVDD / (double) 1023) * VDD;
120
    
121
  delay_ms(2000);
122
  fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
123
  fprintf(PICKIT2,"Analog-Spannung: %LD", VoltA);
124
  
125
  fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
126
  fprintf(PICKIT2,"Digital-Spannung: %LD", VoltD);
127
  delay_ms(2000);
128

129
  setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);  // SPI-Master Einstellung
130
  output_high(SS_Pin);
131
  delay_us(1000);
132
}  
133

134
//>>>>>>> Read the registers from MCP3911
135
unsigned char Read3911(char address)
136
{
137
  char data;
138
  address=(address<<1)+1;
139

140
  output_low(SS_Pin);
141
  delay_us(CS_delay);
142
  spi_write(address);
143
      data=spi_read();
144
  delay_us(CS_delay);
145
  output_high(SS_Pin);
146
  
147
  return(data);
148
}
149
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
150
//  Reads the all the registers from MCP3911
151

152
void Read_Internal_Registers(void)
153
{
154
  unsigned char i, address;
155
  for(i=0; i<=26; i++)
156
  {
157
    internal_registers[i]=Read3911(i);
158
  }
159

160
}
161
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
162
//   Write each register from MCP3911
163

164
void Write3911(unsigned char address, unsigned char data)
165
{
166
  address=(address<<1);
167
  
168
     output_low(SS_Pin);
169
     delay_us(CS_delay);
170
  spi_write(address);
171
  spi_write(data);
172
  delay_us(CS_delay);
173
    output_high(SS_Pin);
174
}
175

176
void Print_Internal_Registers(void)
177
{
178
  int8 i = 0;
179
  fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
180
  for(i = 0;i <= 26;i++)
181
  {
182
    fprintf(PICKIT2,"Register %d: %u",i,internal_registers[i]);
183
    fprintf(PICKIT2,"%c%c", 0x0D, 0x0A);
184
    delay_ms(1);
185
  }  
186
}

Raus komm das:

Initialisierung
Analog-Spannung: 3061
Digital-Spannung: 3053
Register 0: 255
Register 1: 0
Register 2: 0
Register 3: 0
Register 4: 0
Register 5: 0
Register 6: 0
Register 7: 0
Register 8: 0
Register 9: 0
Register 10: 255
Register 11: 0
Register 12: 0
Register 13: 0
Register 14: 0
Register 15: 0
Register 16: 0
Register 17: 0
Register 18: 0
Register 19: 0
Register 20: 0
Register 21: 0
Register 22: 0
Register 23: 0
Register 24: 0
Register 25: 0
Register 26: 0
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #4206833
Lesenswert?

Michael S. schrieb:
> Dann habe ich einfach ein paar Register beschrieben und ausgelesen: aber
> es kommt nur 0 oder 255 raus.
Stichwort: Oszilloskop.
Damit kann man sich Signale ansehen und kontrollieren, ob sie mit den im 
Datenblatt angegebenen Zeiten und Timings (Taktfrequenz, Polarität und 
Phase) zusammenpassen.

> Hatte schon mal jemand ein ähnliches Problem oder kann mir jemand
> helfen?
Schließt sich das aus?

Noch ein Tipp:
>  setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4);
Den SPI zu Beginn ruhig erst mal langsam anfahren, und nicht mit der 
/maximal/erlaubten Geschwindigkeit...

BTW:
Wie sieht der Hardwareaufbau aus?
#4206845
Lesenswert?

Andre schrieb:
>
> 1)
> Wie sieht die Gegenstelle aus, die mit dem MCP kommuniziert? Beschaltung
> richtig?

Die Beschaltung ist ganz simpel:
1
      
2

3
          VDD
4
    MCLR  I
5
     I  __I___
6
     I-I      I---TX                        I
7
  I    I   1  I---RX          _________  15pF
8
 15pF  I   8  I---DR   DR----I         I   _I_
9
 _I_   I   F  I---CS   CS----I         I--I 2 I
10
I 2 I--I   2  I---CLK  CLK---I MCP3911 I--I_0_I
11
I_0_I--I   5  I---SDO  SDI---I         I    I
12
  I    I   5  I---SDI  SDO---I_________I   15pF   
13
 15pF  I   0  I                             I
14
  I    I______I
15
           I
16
           I
17
         VSS
20MHz Quarz 15pF Kondis, am PIC sowie auch am MCP3911
Moderator (Firma: Titel) Persönliche Seite #4206989
Lesenswert?

Michael S. schrieb:
> Die Beschaltung ist ganz simpel:
Das ist ja mal eine grausige ASCII-Grafik  :-o
Kleiner Tipp: mit den passenden Tags (siehe unter 
https://www.mikrocontroller.net/articles/Formatierung_im_Forum) lässt 
sich die Darstellung nicht von Formatierungen durcheinanderbringen...

Seis drum:
> 20MHz Quarz 15pF Kondis, am PIC sowie auch am MCP3911
Sonst nix? Ich sehe da keine Blockkondensatoren und tu mir auch schwer, 
den tatsächlichen Hardwareaufbau vorzustellen (Leitungslängen usw.).


BTW: SPI kennt auch keine SDO und SDI, sondern nur MISO und MOSI...
#4207107
Lesenswert?

> Seis drum:
>> 20MHz Quarz 15pF Kondis, am PIC sowie auch am MCP3911
> Sonst nix? Ich sehe da keine Blockkondensatoren und tu mir auch schwer,
> den tatsächlichen Hardwareaufbau vorzustellen (Leitungslängen usw.).
>
Kabel so kurz wie möglich. 2 separate 3.3V-Spannungsregler, 
Pufferkondensatoren 10uF, mehr Bauteile gibts nicht(siehe Bild)
Angehängte Dateien:
#4208100
Lesenswert?

JAAA! Problem gelöst:
ohne Daten im
1
 spi_read(data);
gibts keine Clock, also kann er auch nichts lesen.
1
unsigned char Read3911(char address)
2
{
3
  char data;
4
  address=(address<<1)+1;
5

6
  output_low(SS_Pin);
7
  delay_us(CS_delay);
8
  spi_write(address);
9
      data=spi_read(); /// hier fehlt die 0 im spi_read(0);
10
  delay_us(CS_delay);
11
  output_high(SS_Pin);
12
  
13
  return(data);
14
}
#4208242
Lesenswert?

Michael S. schrieb:
>> Seis drum:
>>> 20MHz Quarz 15pF Kondis, am PIC sowie auch am MCP3911
>> Sonst nix? Ich sehe da keine Blockkondensatoren und tu mir auch schwer,
>> den tatsächlichen Hardwareaufbau vorzustellen (Leitungslängen usw.).
>>
> Kabel so kurz wie möglich. 2 separate 3.3V-Spannungsregler,
> Pufferkondensatoren 10uF, mehr Bauteile gibts nicht(siehe Bild)

Grundregel 1: an jedes VCC-GND-Pärchen gehört immer ein 100n keramisch 
DIREKT am Pinpaar
Grundregel 2: keine offenen Eingänge

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren