MCP2515 Register vergisst die Werte

Gast #559791
Hallo,

ich habe einen MCP2515 an einem ATMega128. Wenn ich ein Register 
beschreibe:

// Software-Reset durchführen
SPI_PORT &= ~(1<<SPI_SS);
SPI_PUT(MCP2515_RESET);
SPI_PORT |= (1<<SPI_SS);

MCP2515_WRREG( CNF1,(1<<BRP0));

und wieder auslese:
test = MCP2515_RDREG( CNF1 );

bekomme ich nicht den Inhalt zurück, den ich geschrieben habe, sondern 
0.

dementsprechend kann ich den Controller nicht konfigurieren um 
Nachrichten zu senden und zu empfangen.
Die Daten auf dem SPI-bus hab ich mir mit dem Oszi angesehen, da sah 
alles gut aus.

Weiß jemand was ich falsch mache?

MFG
MAtthias
So habe ich das auch gemacht:

* Reset-Instruction per SPI senden
* 15ms warten
* restliche Initialisierung über SPI durchführen

Der MCP2515 braucht nach dem Reset einfach etwas Zeit, um sich selbst zu 
initialisieren.
Später ist keinerlei Delay zwischen den SPI-Kommandos mehr notwendig 
(ich benutze 2 bzw. 4Mhz SPI-Frequenz).

Viele Grüße, Stefan
Gast
Hallo,

Danke für die Tips!

An der Stelle hab ich schon mit einigen Wartezeiten experimentiert.
Hier sind die entsprechenden Funktionen:

1
int8_t initMCP2515(void)
2
{
3
  uint16_t test;
4
  char testtext[]= " . ";
5

6
  // Software-Reset durchführen
7
  SPI_PORT &= ~(1<<SPI_SS);
8
  SPI_PUT(MCP2515_RESET);
9
  asm volatile ("nop");
10
  SPI_PORT |= (1<<SPI_SS);
11
  wait10ms(5);
12
  asm volatile ("nop");
13
  asm volatile ("nop");
14
  
15
  UART_Text_out("CANCTL:",0);
16
  test = MCP2515_RDREG(CANCTRL);
17
  testtext[1]=test;
18
  UART_Text_out(testtext,1);
19

20
  UART_Text_out("CANSTAT:",0);
21
  test = MCP2515_RDREG(CANSTAT);
22
  testtext[1]=test;
23
  UART_Text_out(testtext,1);
24

25
  MCP2515_WRREG( CNF1,(1<<BRP0)); //(0x01)
26

27
  test = MCP2515_RDREG( CNF1 );
28
  testtext[1]=test;
29
  UART_Text_out("CNF1:",0);
30
  UART_Text_out(testtext,1);
31

32
// MCP2515 zurueck in den normalen Modus versetzen
33
  mcp2515_bit_modify( CANCTRL, 0xE0, 0);
34

35
  test = MCP2515_RDREG( CNF1 );
36
  testtext[1]=test;
37
  UART_Text_out("CNF1:",0);
38
  UART_Text_out(testtext,1);
39
}
40

41
void wait10ms(uint16_t xms) // wartet xms*10ms
42
{
43
  for(uint8_t i=0 ; i<xms; i++)
44
  {
45
    _delay_ms(mswait); // Argument muss Konstante sein!
46
  }
47
}
48

49
uint8_t SPI_PUT(uint8_t cData)
50
{
51
  /* Start transmission */
52
  SPDR = cData;
53
  /* Wait for transmission complete */
54
  while(!(SPSR & (1<<SPIF)))
55
  ;
56
  //loop_until_bit_is_set(SPSR,SPIF);  //  warten bis das Byte gesendet wurde
57
  return SPDR;
58
}
59

60
uint8_t MCP2515_WRREG(uint8_t Adresse, uint8_t Daten)
61
{
62
  SPI_PORT &= ~(1<<SPI_SS);
63
  SPI_PUT(MCP2515_WRITE);
64
  SPI_PUT(Adresse);
65
  SPI_PUT(Daten);
66
  SPI_PORT |= (1<<SPI_SS);
67
  return 0;
68
}
69

70
uint8_t MCP2515_RDREG(uint8_t Adresse)
71
{
72
  uint8_t Daten;
73
  SPI_PORT &= ~(1<<SPI_SS);
74
  SPI_PUT(MCP2515_READ);
75
  SPI_PUT(Adresse);
76
  Daten = SPI_PUT(0xaa);
77
  SPI_PORT |= (1<<SPI_SS);
78
  return Daten;
79
}
80

81
uint8_t MCP2515_READ_STATUS(void)
82
{
83
  uint8_t status;
84
  // Status des MCP2515 auslesen
85
  SPI_PORT &= ~(1<<SPI_SS);
86
  SPI_PUT(MCP2515_READ_STAT);
87
  status = SPI_PUT(0xaa);
88
  SPI_PUT(0xaa);
89
  SPI_PORT |= (1<<SPI_SS);
90
  return status;
91
}
92

93
uint8_t mcp2515_bit_modify(uint8_t adress, uint8_t mask, uint8_t data)
94
{
95
  // /CS des MCP2515 auf Low ziehen
96
  SPI_PORT &= ~(1<<SPI_SS);
97
  SPI_PUT(MCP2515_BIT_MODIFY);
98
  SPI_PUT(adress);
99
  SPI_PUT(mask);
100
  SPI_PUT(data);
101
     // /CS Leitung wieder freigeben
102
  SPI_PORT |= (1<<SPI_SS);
103
  return 0;
104
}
105

106
int8_t init_SPI_Master(void)
107
{
108
  /* Set MOSI and SCK output, all others input */
109
  SPI_DDR |= ((1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS));
110
  SPI_DDR &= ~(1<<SPI_MISO);
111
  
112
  SPI_PORT |= (1<<SPI_MISO); // Pull-up EIN
113

114
  //SPI_PORT &= ~((1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_MISO));
115
  SPI_PORT |= (1<<SPI_SS); // SS HIGH  
116

117
  /* Enable SPI, Master, set clock rate fck/16 */
118
  //SPCR = 0;
119
  //SPCR |= ((1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1));
120

121
  SPCR = ((1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1));
122
  SPSR = (1<<SPI2X);
123
  return 0;
124
}

Das meiste hab ich hier: 
http://www.kreatives-chaos.com/artikel/ansteuerung-eines-mcp2515
her.

Danke + Grüße
Matthias

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.