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
Das Problem hatte ich eben auch. Wirf mal ein Delay vor MCP2515_WRREG. Das Delay-Schäufelchen war gerade kaputt, weswegen ich eine 50 ms Berg gesetzt habe. Das geht aber bestimmt auch mit deutlich weniger. Gruß frank
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.