Gast
#402286
Hallo!
Ich moechte mithilfe eines ATMega128 und eines MPC2510 einen CAN-Bus
abhoeren und abh. von den eintreffenden Nachrichten die Ausgaenge
steuern. Das bedeutet, ich muss CAN-Nachrichten lesen koennen...
Ich habe auch schon im Netz gestoebert und mit den gefundenen
Beitraegen versucht mir ein Programm zusammmen zu basteln, aber so ganz
klar ist mir das ganze noch nicht, vor allem das Einlesen der
CAN-Nachrichten
/**************************** importierte Header-Files
**********************/
#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#include <mcp2510.h>
#define MISO 3 //ist Eingang
#define MOSI 2 //ist Ausgang
#define SCK 1 //ist Ausgang
#define SS 0 //ist Ausgang
//SPI Control Register SPCR
#define SPIE 7
#define SPE 6
#define DORD 5
#define MSTR 4
#define CPOL 3
#define CPHA 2
#define SPR1 1
#define SPR0 0
//SPI Status Register SPSR
#define SPIF 7
#define WCOL 6
/**************************** Funktionsdeklarationen
*************************/
void init_SPI (void);
void configure_mcp (void);
void reset_mcp (void);
void write_mcp (unsigned char adress, unsigned char value);
unsigned char read_mcp(unsigned char adress);
//Initialisierung des Serial Peripheral Interfaces
void init_SPI (void)
{
DDRB = (1<<MOSI) | (1<< SCK) | (1<<SS); //MOSI, SCK, SS
als Ausgang (-> DDRB=0x07)
PORTB |= (1<<SS); //Pull-up an SS
(mcp disable) (PORTB.0=1);
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0); // SPI Controll
Register (-> SPCR=0x51)
//| (1<<SPIE);
Interruptfreigabe
}
void reset_mcp (void)
{
PORTB &= ~(1<<SS); //CS auf LOW setzen,
SPI Übertragung einleiten (-> PORTB.0=0)
SPCR=RESET_MCP; //Reset Instruction
senden (0xC0)
while (!(SPSR && 0x80));
while (!(SPSR && (1<<SPIF))); //warten bis
BYTE (SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
PORTB |= (1<<SS); //CS auf HIGH setzen,
Übertragung beendet (-> PORTB.0=1)
}
void configure_mcp (void)
{
reset_mcp(); //mcp in den
Grundzustand setzen
write_mcp(CANCTRL, 0x85); //Configuration
Mode, CLKOUT enable, System Clock/2
write_mcp(CNF1, 0x05); //CNF1, CNF2,
CNF3 legen 83,3 kbaud @ 8 MHz fest
write_mcp(CNF2, 0x90);
write_mcp(CNF3, 0x02);
write_mcp(CANCTRL, 0x45); //Loopback
Mode, CLKOUT enable, System Clock/2
}
//Beschreiben der MPC-Register
void write_mcp (unsigned char adress, unsigned char value)
{
PORTB &= ~(1<<SS); //CS auf LOW setzen,
SPI Übertragung einleiten (-> PORTB.0=0)
SPCR=WRITE_MCP; //Write Instruction
senden (0x02)
while (!(SPSR && (1<<SPIF))); //warten bis BYTE
(SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
SPDR=adress; //Addresse senden
while (!(SPSR && (1<<SPIF))); //warten bis
BYTE (SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
SPDR=value; //Wert senden
while (!(SPSR && (1<<SPIF))); //warten bis BYTE
(SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
PORTB |= (1<<SS); //CS auf HIGH setzen,
Übertragung beendet (-> PORTB.0=1)
}
//Auslesen der MPC-Register
unsigned char read_mcp(unsigned char adress)
{
unsigned char spidata;
PORTB &= ~(1<<SS); //CS auf LOW setzen,
SPI Übertragung einleiten (-> PORTB.0=0)
SPCR=READ_MCP; //Read Instruciotn
senden (0x03)
while (!(SPSR && (1<<SPIF))); //warten bis BYTE
(SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
SPDR=adress; //Addresse senden
while (!(SPSR && (1<<SPIF))); //warten bis BYTE
(SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
SPDR=0xAA; //Dummy-Byte senden
while (!(SPSR && (1<<SPIF))); //warten bis BYTE
(SPIF-Flag gesetzt) gesendet wurde (Ende Übertragung)
spidata=SPDR; //Daten aus SPI
abholen
PORTB |= (1<<SS); //CS auf HIGH setzen,
Übertragung beendet (-> PORTB.0=1)
return (spidata);
}
/**************************** Hauptprogramm
**********************************/
int main( void )
{
DDRC=0x0F; //C.0, C.1, C.2, C.3 sind Eingang,
C.4, C.5, C.6, C.7 sind Ausgang
DDRB=0x0F; //B.0, B.1, B.2, B.3 sind Eingang,
B.4, B.5, B.6, B.7 sind Ausgang
init_SPI();
while(1)
{
}
}
Folgende Punkte sind fuer mich noch vollkommen unklar:
* Wie kann ich die (richtigen) CAN-Nachrichte empfangen??? Wie frage
ich den Identifier ab?
* Was ist besser: Polling oder Interrupt?? und wie werden diese
generiert??
* sind CNF1, 2 und 3 richtig festgelegt???
* Wofuer benoetigt der MCP einen eigenen Quarz, wo er doch die
Taktleitung des Mega128s hat?
Wie man leicht merken kann, ist die Verwirrung noch recht gross, daher
bin ich sehr dankbar, wenn mir der ein oder andere einen Tipp geben
kann um ein bisschen Licht in die Dunkelheit zu bringen!
Herzlichen Dank und viele Gruesse
LARA