Forum: Mikrocontroller und Digitale Elektronik CAN-BUS mit dsPIC30F6014


von Tom (Gast)


Lesenswert?

Hi Leute,

ich würde mir gern einen eigenen CAN-Bus aufziehen. Dazu hab ich mir den 
dsPIC30f6014 von Microchip zugelegt und ein passendes Board dazu.

Jetzt würde ich gerne prinzipiell eine Nachricht auf Tastendruck eine 
Nachricht senden, diese dann verzögert wieder empfangen ( geschieht über 
2tes Board).

Hört sich doch eigentlich ganz einfach an, aber meine Probleme gehen 
leider schon beim initialisieren des CAN`s schief....

Kann mir da jemand helfen? Oder gibts irgendwo ein BSP. zum anschauen 
und lernen?

Thx

Tom

von Tom (Gast)


Lesenswert?

i made some changes in my file, but it doesn't work. the can-port 
wouldn`t send the message...is there anyone who can help me?

thx



#include "p30f6014.h"
#include "can.h"
/* ***********************************
included functions
can_clk_init
can_init
can_receive
can_transmit
  *********************************** */

void can_clk_init (void)    // Initialize CAN_CLK
{
// ***********************************
// CAN1 Control Register
// FCAN Clock = FCY
C1CTRLbits.CANCKS = 0x1;   // Bit CANCKS set 1
// ***********************************
// CAN1 Baud Rate Control Register
// PHASE Segment 1 = 8TQ
// PHASE Segment 2 = 6TQ
// Propagation Delay = 5TQ
// Synchronization Jump width = 4TQ
// Baud Rate Prescaler = BRP_VAL defined in can.h
// Sync. Segment = 1TQ
// Phase Segment 2 Time select bit = 6TQ

C1CFG1bits.BRP = BRP_VAL;   // Bit BRP set BRP_VAL
C1CFG1bits.SJW = 0x3;    // Bit SJW set 11
C1CFG2bits.PRSEG = 0x4;    // Bit PRSEG set 100
C1CFG2bits.SEG1PH = 0x7;    // Bit SEG1PH set 111
C1CFG2bits.SAM = 0x1;    // Bit SAM set 1
C1CFG2bits.SEG2PHTS = 0x1;   // Bit SEG2PHTS set 1
C1CFG2bits.SEG2PH = 0x5;   // Bit SEG2PH set 101

}
void can_init (void)     // Initialisier CAN
{
// ***********************************
// Request Configuration Mode
// Request Operation Mode = 4
C1CTRLbits.REQOP = 0x4;   // Bit REQ0P set 100
while (C1CTRLbits.OPMODE != 0x4);
can_clk_init();

// ***********************************
// Filter configuration
// Standard Identifier
// Standard Identifier Bit = 1111111111
// Extendes Identifier Enable Bit = 0 (MIDE = 1)
C1RXF0SIDbits.EXIDE = 0x0;   // Filter 0
C1RXF0SIDbits.SID = 0x3FF;

// Extended Identifier
// not included -> MIDE disabled
// ***********************************
// Mask Configuration
// Standard Identifier
// Identifier Mode Selection Bit = 0
// Standard Identifier Mask Bit = 1111111111
C1RXM0SIDbits.MIDE = 0x1;   // Bit Mide set 1
C1RXM0SIDbits.SID = 0x3FF;   // BIT SID set
// Extended Identifier
// not included
// ***********************************
// Normal Mode
// Request Operation Mode = 0
C1CTRLbits.REQOP = 0x0;   // Bit REQ0P set 000
while(C1CTRLbits.OPMODE != 0x0);
}
void can_receive (void)
{
}
void can_transmit (void)
{
// Message Transmit Priority Level 00
C1TX0CONbits.TXPRI = 0x0 ;   // Bit TXPRI set 00
}

von Schoasch (Gast)


Lesenswert?

Hi

Ich hab mit dem CAN-Modul leider noch nichts gemacht, aber probiers mal 
im Microchip Forum oder im Fernando Heitor Forum.

forum.microchip.com
www.fernando-heitor.com

mfg schoasch

von Schoasch (Gast)


Lesenswert?

PS.: Schreib dann auch dazu was sich nicht tut. Schickst du irgendwas 
hinaus? Hast du das mit dem OSzi geprüft?

von Tom (Gast)


Lesenswert?

also danke für die beiden posts,

ich hab mal unter beiden geschaut und auch gepostet, bin mal gespannt.

was nicht geht:

eigentlich wollt ich eine folge von bits ausgeben lassen und mit dem 
oszi anzeigen, also erst so, bevor ich an das 2te board gehe, aber ich 
bekomm nichts raus, und ich vermute, dass es an der init liegt...

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Schau mal ob am C1TX Pin des dsPIC was rauskommt.

von Tom (Gast)


Lesenswert?

da kommt nichts raus, aber rein gar nichts..aber ich hab jetzt glaub ich 
was entdeck, wenn ich schritt für schritt debugge, dann hängt mir das 
progi in einer schleife fest und geht nimmer raus (schleife im normal 
mode)
und dann kann ich ja net weitermachen, wenns da immer hängt

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Poste doch mal dein komplettes Projekt, dann kann man leichter 
nachvollziehen was du machst.

von Tom (Gast)


Lesenswert?

hier mal das ganze projekt, nur die dspic30f6014.h und die dazugehörige 
*.gld hab ich jetzt nicht mit gepostet....

problemstellung: Ich bekomm keine Datan am Can-port ausgegeben
Board: dspicdem 1.1 von microchip
Controller: dspic30f6014
programm: mplab
compiler: c30
programmer: icd 2

wenn mir da jemand weiterhelfen könnt, wäre ich dankbar

code below:
-main.c
-can.c
-can.h
-global_variables.c
-global_variables.h
-define_portpins.h

*******************main.c***********************
#include <stdio.h>
#include "p30f6014.h"
#include "can.h"
#include "global_variables.h"
#include "define_portpins.h"
int main (void)
{
TRISA = 0xF000;
TRISB = 0x017B;
TRISC = 0x0000;
PORTD = 0x00EF;
TRISD = 0x0010;
PORTF = 0x002A;
TRISF = 0x0055;
TRISG = 0x1080;
// enable interrupts
C1INTE = 0x00FF;
// set operation mode
can_set_op_mode_1();
while (C1CTRLbits.OPMODE <=3);
// load configuration register
can_init();
// load acceptance filter
can_acceptance_filter();
// load mask filter
can_mask();
// set transmit and receive mode
can_tx_mode();
can_rx_mode();
// load message ID, data_transmit -> transmit buffer, transmit request 
bit
unsigned char *tx_data_ptr;
tx_data_ptr = &tx_data[0];
can_transmit(tx_data_ptr);
// set operation mode
can_set_op_mode_2();
while (C1CTRLbits.REQOP !=2);
// wait till transmit is finished
while (!C1TX0CONbits.TXREQ);
// wait till receive buffer contains message
while (C1RX0CONbits.RXFUL);
// received data -> data_received
unsigned char *rx_data_ptr;
rx_data_ptr = &rx_data[0];
can_receive(rx_data_ptr);
// loop
while (1);
return 0;
}


**********************can.c************************
#include "can.h"
#include "p30f6014.h"
#include "global_variables.h"
void can_set_op_mode_1()
{
C1CTRLbits.CSIDL = 0x0;    // continue can modul operation in idle mode
C1CTRLbits.CANCKS = 0x1;   // fcan = fcy
C1CTRLbits.REQOP = 0x4;    // set operation mode
}
void can_init()
{
C1CFG1bits.SJW = 0x1;    // synchronized jump width = 01
C1CFG1bits.BRP = 0x3F;    // baud rate 128/fcsn
C1CFG2bits.WAKFIL = 0x0;   // can bus line filter is not used for wake 
up
C1CFG2bits.SEG2PH = 0x4;   // phase buffer segment 2 = 100
C1CFG2bits.SEG2PHTS = 0x1;   // phase segment 2 time select = freely 
programmable
C1CFG2bits.SAM = 0x0;    // sample can bus line = 0 (1x)
C1CFG2bits.SEG1PH = 0x3;   // phase buffer segment 1 = 011
C1CFG2bits.PRSEG = 0x3;    // propagation time = 011
}
void can_acceptance_filter()
{
C1RXF0SID = 0x555;     // standard identifier bits
C1RXF0SIDbits.EXIDE = 0x1;   // enable filter SID=0 EID=1
C1RXF0EIDH = 0xAAA;     // extended identifier bits upper byte
C1RXF0EIDL = 0x2A;     // extended identifier bits lower byte
}
void can_mask()
{
C1RXM0SID = 0x2AA;     // standard identifier mask bits
C1RXM0SIDbits.MIDE = 0x0;   // identifier mode 0
C1RXM0EIDH = 0x555;     // extended identifier mask bits upper byte
C1RXM0EIDL = 0x25;     // extendet identifier mask bits lower byte
}
void can_tx_mode()
{
C1TX0CONbits.TXPRI = 0x2;   // message transmission priority (high = 10)
C1TX0CONbits.TXREQ = 0x0;   // message send request bit (1 = request)
}
void can_rx_mode()
{
C1RX0CONbits.DBEN = 0x1;   // receive buffer 0 double buffer enable bit
C1RX0CONbits.RXFUL = 0x0;   // receive full status (buffer open = 0)
}
void can_transmit(unsigned char *data)
{
int i;
C1TX0SID = 0x2AA;     // standard identifier bits
C1TX0EID = 0x1555;     // extended identifier bits

for(i=0;i<data_length;i++)
    {
      *((unsigned char *)&C1TX0B1+i) = data;
       }
C1TX0DLCbits.DLC = data_length;  // data length code bits
   C1TX0CONbits.TXREQ = 0x1;   // message send request bit

}
void can_set_op_mode_2()
{
C1CTRLbits.CSIDL = 0x0;    // continue can modul operation in idle mode
C1CTRLbits.CANCKS = 0x1;   // fcan = fcy
C1CTRLbits.REQOP = 0x2;    // set loopback mode
C1CTRLbits.CANCAP = 0x0;   // can message receive capture disable
}
void can_receive(unsigned char *data)
{
int i;
   for(i = 0;i<data_length;i++)
    {
  data = *((unsigned char *)&C1RX0B1+i);
       }
C1RX0CONbits.RXFUL = 0x0;   // receive full status bit
}


***********************can.h*******************************
extern void can_set_op_mode_1();
extern void can_init();
extern void can_acceptance_filter();
extern void can_mask();
extern void can_tx_mode();
extern void can_rx_mode();
extern void can_transmit(unsigned char *);
extern void can_set_op_mode_2();
extern void can_receive( unsigned char *);

************************global_variables.c**************************
#include "global_variables.h"
unsigned char tx_data[data_length] ={1,0,1,0,1,0,1,0};
unsigned char rx_data[data_length];

***********************define_portpins.h**************************
#include "p30f6014.h"
#define LED1 LATDbits.LATD0
#define LED2 LATDbits.LATD1
#define LED3 LATDbits.LATD2
#define LED4 LATDbits.LATD3
#define LEDS_OFF (LATD |= 0x000F)
#define LEDS_ON  (LATD &= 0xFFF0)
#define _CS_LCD  PORTGbits.RG9
#define _CS_POTI  PORTDbits.RD7
#define CAN_RXD  PORTFbits.RF0
#define CAN_TXD  PORTFbits.RF1
#define CTS PORTDbits.RD4
#define RTS PORTDbits.RD5


***********************global_variables.h**********************
#define data_length 8
extern unsigned char rx_data[data_length];
extern unsigned char tx_data[data_length];


**********************assemlby code****************************
---  P:\CAN-BUS\Sender\can.c 
--------------------------------------------------------------------
1:                 #include "can.h"
2:                 #include "p30f6014.h"
3:                 #include "global_variables.h"
4:
5:                 void can_set_op_mode_1()
6:                 {
0001EC  FA0000     lnk #_dinit_tblpage
7:                  C1CTRLbits.CSIDL = 0x0;    // continue can modul 
operation in idle mode
0001EE  A9A391     bclr.b 0x391,#5
8:                  C1CTRLbits.CANCKS = 0x1;   // fcan = fcy
0001F0  A86391     bset.b 0x391,#3
9:                  C1CTRLbits.REQOP = 0x4;    // set operation mode
0001F2  203911     mov.w #0x391,w1
0001F4  784091     mov.b [w1],w1
0001F6  B3CF80     mov.b #0xf8,w0
0001F8  60C000     and.b w1,w0,w0
0001FA  A02400     bset w0,#2
0001FC  B7E391     mov.b w0,0x391
10:                }
0001FE  FA8000     ulnk
11:
12:                void can_init()
13:                {
000202  FA0000     lnk #_dinit_tblpage
14:                 C1CFG1bits.SJW = 0x1;    // synchronized jump width 
= 01
000204  BFC392     mov.b C1CFG1bits,w0
000206  B243F0     and.b #0x3f,w0
000208  B3C401     mov.b #0x40,w1
00020A  704001     ior.b w0,w1,w0
00020C  B7E392     mov.b w0,C1CFG1bits
15:                 C1CFG1bits.BRP = 0x3F;    // baud rate 128/fcsn
00020E  203921     mov.w #0x392,w1
000210  784091     mov.b [w1],w1
000212  B3C3F0     mov.b #0x3f,w0
000214  70C000     ior.b w1,w0,w0
000216  B7E392     mov.b w0,C1CFG1bits
16:                 C1CFG2bits.WAKFIL = 0x0;   // can bus line filter is 
not used for wake up
000218  A9C395     bclr.b 0x395,#6
17:                 C1CFG2bits.SEG2PH = 0x4;   // phase buffer segment 2 
= 100
00021A  203951     mov.w #0x395,w1
00021C  784091     mov.b [w1],w1
00021E  B3CF80     mov.b #0xf8,w0
000220  60C000     and.b w1,w0,w0
000222  A02400     bset w0,#2
000224  B7E395     mov.b w0,0x395
18:                 C1CFG2bits.SEG2PHTS = 0x1;   // phase segment 2 time 
select = freely programmable
000226  A8E394     bset.b C1CFG2bits,#7
19:                 C1CFG2bits.SAM = 0x0;    // sample can bus line = 0 
(1x)
000228  A9C394     bclr.b C1CFG2bits,#6
20:                 C1CFG2bits.SEG1PH = 0x3;   // phase buffer segment 1 
= 011
00022A  203941     mov.w #0x394,w1
00022C  784091     mov.b [w1],w1
00022E  B3CC70     mov.b #0xc7,w0
000230  60C000     and.b w1,w0,w0
000232  B34180     ior.b #0x18,w0
000234  B7E394     mov.b w0,C1CFG2bits
21:                 C1CFG2bits.PRSEG = 0x3;    // propagation time = 011
000236  203941     mov.w #0x394,w1
000238  784091     mov.b [w1],w1
00023A  B3CF80     mov.b #0xf8,w0
00023C  60C000     and.b w1,w0,w0
00023E  B34030     ior.b #0x3,w0
000240  B7E394     mov.b w0,C1CFG2bits
22:                }
000242  FA8000     ulnk
23:
24:                void can_acceptance_filter()
25:                {
000246  FA0000     lnk #_dinit_tblpage
26:                 C1RXF0SID = 0x555;     // standard identifier bits
000248  205550     mov.w #0x555,w0
00024A  881800     mov.w w0,CAN1
27:                 C1RXF0SIDbits.EXIDE = 0x1;   // enable filter SID=0 
EID=1
00024C  A80300     bset.b CAN1,#0
28:                 C1RXF0EIDH = 0xAAA;     // extended identifier bits 
upper byte
00024E  20AAA0     mov.w #0xaaa,w0
000250  881810     mov.w w0,C1RXF0EIDHbits
29:                 C1RXF0EIDL = 0x2A;     // extended identifier bits 
lower byte
000252  2002A0     mov.w #0x2a,w0
000254  881820     mov.w w0,C1RXF0EIDL
30:                }
000256  FA8000     ulnk
31:
32:                void can_mask()
33:                {
00025A  FA0000     lnk #_dinit_tblpage
34:                 C1RXM0SID = 0x2AA;     // standard identifier mask 
bits
00025C  202AA0     mov.w #0x2aa,w0
00025E  881980     mov.w w0,C1RXM0SID
35:                 C1RXM0SIDbits.MIDE = 0x0;   // identifier mode 0
000260  A90330     bclr.b C1RXM0SID,#0
36:                 C1RXM0EIDH = 0x555;     // extended identifier mask 
bits upper byte
000262  205550     mov.w #0x555,w0
000264  881990     mov.w w0,C1RXM0EIDH
37:                 C1RXM0EIDL = 0x25;     // extendet identifier mask 
bits lower byte
000266  200250     mov.w #0x25,w0
000268  8819A0     mov.w w0,C1RXM0EIDLbits
38:                }
00026A  FA8000     ulnk
39:
40:                void can_tx_mode()
41:                {
00026E  FA0000     lnk #_dinit_tblpage
42:                 C1TX0CONbits.TXPRI = 0x2;   // message transmission 
priority (high = 10)
000270  2036E1     mov.w #0x36e,w1
000272  784091     mov.b [w1],w1
000274  B3CFC0     mov.b #0xfc,w0
000276  60C000     and.b w1,w0,w0
000278  A01400     bset w0,#1
00027A  B7E36E     mov.b w0,C1TX0CON
43:                 C1TX0CONbits.TXREQ = 0x0;   // message send request 
bit (1 = request)
00027C  A9636E     bclr.b C1TX0CON,#3
44:                }
00027E  FA8000     ulnk
45:
46:                void can_rx_mode()
47:                {
000282  FA0000     lnk #_dinit_tblpage
48:                 C1RX0CONbits.DBEN = 0x1;   // receive buffer 0 
double buffer enable bit
000284  A8438E     bset.b C1RX0CONbits,#2
49:                 C1RX0CONbits.RXFUL = 0x0;   // receive full status 
(buffer open = 0)
000286  A9E38E     bclr.b C1RX0CONbits,#7
50:                }
000288  FA8000     ulnk
51:
52:                void can_transmit(unsigned char *data)
53:                {
00028C  FA0004     lnk #WREG2
54:                 int i;
55:
56:                 C1TX0SID = 0x2AA;     // standard identifier bits
000290  202AA0     mov.w #0x2aa,w0
000292  881B00     mov.w w0,C1TX0SIDbits
57:                 C1TX0EID = 0x1555;     // extended identifier bits
000294  215550     mov.w #0x1555,w0
000296  881B10     mov.w w0,C1TX0EIDbits
58:
59:                 for(i=0;i<data_length;i++)
000298  EB0000     clr.w w0
00029A  780F00     mov.w w0,[w14]
00029C  37000B     bra .L14
0002B2  E80F1E     inc.w [w14],[w14]
0002B4  200070     mov.w #0x7,w0
0002B6  100F9E     subr.w w0,[w14],[w15]
0002B8  34FFF2     bra les, .L15
60:                     {
61:                       *((unsigned char *)&C1TX0B1+i) = data;
00029E  78001E     mov.w [w14],w0
0002A0  780080     mov.w w0,w1
0002A2  203660     mov.w #0x366,w0
0002A4  408100     add.w w1,w0,w2
0002A6  78001E     mov.w [w14],w0
0002A8  780080     mov.w w0,w1
0002AA  90001E     mov.w [w14+2],w0
0002AC  408000     add.w w1,w0,w0
0002AE  784010     mov.b [w0],w0
0002B0  784900     mov.b w0,[w2]
62:                        }
63:
64:                 C1TX0DLCbits.DLC = data_length;  // data length code 
bits
0002BA  203641     mov.w #0x364,w1
0002BC  784091     mov.b [w1],w1
0002BE  B3C870     mov.b #0x87,w0
0002C0  60C000     and.b w1,w0,w0
0002C2  B3C401     mov.b #0x40,w1
0002C4  704001     ior.b w0,w1,w0
0002C6  B7E364     mov.b w0,C1TX0DLC
65:                    C1TX0CONbits.TXREQ = 0x1;   // message send 
request bit
0002C8  A8636E     bset.b C1TX0CON,#3
66:
67:                }
0002CA  FA8000     ulnk
68:
69:                void can_set_op_mode_2()
70:                {
0002CE  FA0000     lnk #_dinit_tblpage
71:                 C1CTRLbits.CSIDL = 0x0;    // continue can modul 
operation in idle mode
0002D0  A9A391     bclr.b 0x391,#5
72:                 C1CTRLbits.CANCKS = 0x1;   // fcan = fcy
0002D2  A86391     bset.b 0x391,#3
73:                 C1CTRLbits.REQOP = 0x2;    // set loopback mode
0002D4  203911     mov.w #0x391,w1
0002D6  784091     mov.b [w1],w1
0002D8  B3CF80     mov.b #0xf8,w0
0002DA  60C000     and.b w1,w0,w0
0002DC  A01400     bset w0,#1
0002DE  B7E391     mov.b w0,0x391
74:                 C1CTRLbits.CANCAP = 0x0;   // can message receive 
capture disable
0002E0  A9E391     bclr.b 0x391,#7
75:                }
0002E2  FA8000     ulnk
76:
77:                void can_receive(unsigned char *data)
78:                {
0002E6  FA0004     lnk #WREG2
79:                 int i;
80:
81:                    for(i = 0;i<data_length;i++)
0002EA  EB0000     clr.w w0
0002EC  780F00     mov.w w0,[w14]
0002EE  37000B     bra .L21
000304  E80F1E     inc.w [w14],[w14]
000306  200070     mov.w #0x7,w0
000308  100F9E     subr.w w0,[w14],[w15]
00030A  34FFF2     bra les, .L22
82:                     {
83:                   data = *((unsigned char *)&C1RX0B1+i);
0002F0  78001E     mov.w [w14],w0
0002F2  780080     mov.w w0,w1
0002F4  90001E     mov.w [w14+2],w0
0002F6  408100     add.w w1,w0,w2
0002F8  78001E     mov.w [w14],w0
0002FA  780080     mov.w w0,w1
0002FC  203860     mov.w #0x386,w0
0002FE  408000     add.w w1,w0,w0
000300  784010     mov.b [w0],w0
000302  784900     mov.b w0,[w2]
84:                        }
85:
86:                 C1RX0CONbits.RXFUL = 0x0;   // receive full status 
bit
00030C  A9E38E     bclr.b C1RX0CONbits,#7
87:                }
00030E  FA8000     ulnk
---  P:\CAN-BUS\Sender\main.c
35:
36:                #include <stdio.h>
37:                #include "p30f6014.h"
38:                #include "can.h"
39:                #include "global_variables.h"
40:                #include "define_portpins.h"
41:
42:                int main (void)
43:                {
000180  FA0004     lnk #WREG2
44:                 TRISA = 0xF000;
000182  2F0000     mov.w #0xf000,w0
000184  881600     mov.w w0,TRISAbits
45:                 TRISB = 0x017B;
000186  2017B0     mov.w #0x17b,w0
000188  881630     mov.w w0,TRISBbits
46:                 TRISC = 0x0000;
00018A  EB0000     clr.w w0
00018C  881660     mov.w w0,TRISC
47:                 PORTD = 0x00EF;
00018E  200EF0     mov.w #0xef,w0
000190  8816A0     mov.w w0,PORTD
48:                 TRISD = 0x0010;
000192  200100     mov.w #0x10,w0
000194  881690     mov.w w0,TRISD
49:                 PORTF = 0x002A;
000196  2002A0     mov.w #0x2a,w0
000198  881700     mov.w w0,PORTFbits
50:                 TRISF = 0x0055;
00019A  200550     mov.w #0x55,w0
00019C  8816F0     mov.w w0,TRISF
51:                 TRISG = 0x1080;
00019E  210800     mov.w #0x1080,w0
0001A0  881720     mov.w w0,TRISG
52:
53:                // enable interrupts
54:
55:                 C1INTE = 0x00FF;
0001A2  200FF0     mov.w #0xff,w0
0001A4  881CC0     mov.w w0,C1INTEbits
56:
57:                // set operation mode
58:
59:                 can_set_op_mode_1();
0001A6   70022     rcall can_set_op_mode_1
60:                 while (C1CTRLbits.OPMODE <=3);
0001A8  BFC390     mov.b C1CTRLbits,w0
0001AA  FB8000     ze.b w0,w0
0001AC  DE0045     lsr w0,#5,w0
0001AE  FB8000     ze.b w0,w0
0001B0  500FE3     sub.w w0,#3,[w15]
0001B2  34FFFA     bra les, .L2
61:
62:                // load configuration register
63:
64:                 can_init();
0001B4   70026     rcall can_init
65:
66:                // load acceptance filter
67:
68:                 can_acceptance_filter();
0001B6   70047     rcall can_acceptance_filter
69:
70:                // load mask filter
71:
72:                 can_mask();
0001B8   70050     rcall can_mask
73:
74:                // set transmit and receive mode
75:
76:                 can_tx_mode();
0001BA   70059     rcall can_tx_mode
77:                 can_rx_mode();
0001BC   70062     rcall can_rx_mode
78:
79:                // load message ID, data_transmit -> transmit buffer, 
transmit request bit
80:
81:                 unsigned char *tx_data_ptr;
82:                 tx_data_ptr = &tx_data[0];
0001BE  208080     mov.w #0x808,w0
0001C0  980710     mov.w w0,[w14+2]
83:
84:                 can_transmit(tx_data_ptr);
0001C2  90001E     mov.w [w14+2],w0
0001C4   70063     rcall can_transmit
85:
86:                // set operation mode
87:
88:                 can_set_op_mode_2();
0001C6   70083     rcall can_set_op_mode_2
89:                 while (C1CTRLbits.REQOP !=2);
0001C8  BFC391     mov.b 0x391,w0
0001CA  604067     and.b w0,#7,w0
0001CC  504FE2     sub.b w0,#2,[w15]
0001CE  3AFFFC     bra nz, .L4
90:
91:                // wait till transmit is finished
92:
93:                 while (!C1TX0CONbits.TXREQ);
0001D0  BFC36E     mov.b C1TX0CON,w0
0001D2  604068     and.b w0,#8,w0
0001D4  E00400     cp0.b w0
0001D6  32FFFC     bra z, .L5
94:
95:                // wait till receive buffer contains message
96:
97:                 while (C1RX0CONbits.RXFUL);
0001D8  BFC38E     mov.b C1RX0CONbits,w0
0001DA  B3C801     mov.b #0x80,w1
0001DC  604001     and.b w0,w1,w0
0001DE  E00400     cp0.b w0
0001E0  3AFFFB     bra nz, .L6
98:
99:                // received data -> data_received
100:
101:                unsigned char *rx_data_ptr;
102:                rx_data_ptr = &rx_data[0];
0001E2  208000     mov.w #0x800,w0
0001E4  780F00     mov.w w0,[w14]
103:
104:                can_receive(rx_data_ptr);
0001E6  78001E     mov.w [w14],w0
0001E8   7007E     rcall can_receive
105:
106:               // loop
107:
108:                while (1);
0001EA  37FFFF     bra .L8



thanks :-)

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

OK, das meinte ich nicht.
Das ist das Disassembly listing.

Ich habe gemeint, dass du dein komplettes projekt packst und die 
gepackte datei hier in den anhang hängst.

Dann kann man die dateien mit mplab simulieren.

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

kein thema,

hab ich falsch verstanden...

hab noch ein fehler gefunden..und zwar waren die configuration bits 
falsch...gesetzt, also in mplab, habs jetzt ins progi mit eingebunden...

mach gerade nen neuen test

thx

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Wunderbar, so kann man da was machen.

Erst mal allgemeine C Sachen:
- Variablen am Anfang eines Blocks deklarieren, nicht mittendrin
- Am Ende von Main steht return 1;
  Das würde bedeuten, dass main mit einem Fehler beendet wurde.
  Da er da eh nicht hinkommt deklarier die main einfach als void.
- schreib alles was du zur initialisierung brauchst in die CAN Init 
Funktion.
  Dann muss man beim lesen nicht dauernd springen.
  In der Main sollte dann nur noch stehen:
    can_init();
    can_senden(...);
    while(1);

Zum CAN Problem.

- Wo genau bleibt er hängen, wenn du ihn mit dem Debugger laufen lässt?
- Versuchst du den CAN in den Loopback Mode zu versetzen?
   -> Dann kanns nicht gehen
- Wie bist du auf den Code gekommen?
  Mich wundert dass du das alles ohne Interrupt machen willst.

von Tom (Gast)


Lesenswert?

*    also mit dem debugger bleibt er nur hängen, bzw. bleibt in der 
while schleife, wenn ich auf die empfangene nachricht abfrage, ansonsten 
läuft der durch...

while (C1RX0CONbits.RXFUL);

*    ja, ich setz den CAN in den loopbackmode, ist das falsch?

*    wieso ohne interrupt? kann ich nicht wirklich gut...also interrupt 
routinen aufrufen und richtig behandeln...aber werd dass dann später 
noch versuchen, wenn das jetzt so mal irgendwann laufen sollte

*    das ich am Oszi nichts darstellen kann, also die frames, liegt das 
am loopbackmode?

*    das mit dem return 1; habe ich schon geändert gehabt, war nur ein 
fehler, der mir erst nach dem posten aufgefallen ist...

*    bei void main(void) gibt der c30 nen fehler raus, dass da ein int 
hin muss...(Version 6.6 hier auf dem rechner, bei version 7.6 nimmt er 
auch das void)

von Tom (Gast)


Lesenswert?

und das mit dem code ist überlegens- und probiersache...

ich hab mich durch den ganzen papierkram gewühlt und mir das versucht 
irgendwie zu verinnerlichen...hab auch schon im netz rumgesucht, aber da 
findet sich nicht wirklich was zum can mid dem dspic30f6014...

Stimmt das was ich im code mach? oder hab ich da noch nen großen 
verständnissfehler?

z.b. ist mir noch nicht klar, wie das mit den buffern ist. wenn ich die 
daten in den buffer schiebe und den dann sende, woher weiß das prog. 
wohin er die buffer ausgeben muss?

ich hab zwar in der define_portpins:

#define CAN_RXD    PORTFbits.RF0
#define CAN_TXD    PORTFbits.RF1

die sache deklariert, aber wirklich an CAN_*XD übergeben tu ich nich

von Tom (Gast)


Lesenswert?

muss ich statt in den loopback mode in den normal operation mode (000)?

loopback brauch ich dann für was?

? wenn ich ein echo an den selben pic zurücksenden will?

von Tom (Gast)


Lesenswert?

okay, die eine frage mit dem mode hat sich geklärt:

Normal Operation Mode
Normal Operating mode is selected when REQOP<2:0> = ‘000’. In this mode, 
the module is
activated, the I/O pins will assume the CAN bus functions. The module 
will transmit and receive
CAN bus messages as described in subsequent sections.

Loopback Mode
If the Loopback mode is activated, the module will connect the internal 
transmit signal to the
internal receive signal at the module boundary. The transmit and receive 
pins revert to their
PORT I/O function.
The transmitter will receive an acknowledge for its sent messages. 
Special hardware will
generate an acknowledge for the transmitter.

dann ist mir schon klar, wieso ich da nix sehe...

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Genau. Hasts ja schon selbst rausgefunden.
Wenn du code zu dem CAN Modul suchst, kannst du auch ma bei den Code 
Examples von den 33ern schauen. Die haben zwar ein anderes CAN Modul, 
die Befehle sind aber weitestgehend gleich.

Kommt was raus, wenn du nicht in den loopback modus gehst?

von Tom (Gast)


Lesenswert?

ja und wie, bin gerade dabei das signal mit dem oszi darzustellen und 
den frame auseinander zu nehmen, damit ich seh obs richtige raus 
kommt...

wie ist das mit den SID und EID?

gibts da was zu beachten?

stimmen die so in meinem progi?

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Was heisst stimmen die?
Soweit ich sehe, hast du die Eingangsfilter und Masken gesetzt.
mit dem Senden hat das nichts zu tun.

Das heisst nur, dass nicht alle CAN Nachrichten empfangen werden, 
sondern nur diejenigen, die von Filter und Maske akzeptiert wurden.

Aber das was rauskommt ist schon mal sehr gut.

Bei SID und EID musst du eigentlich nichts beachten.

Ich würde dir raten für den Anfang nur SID zu verwenden und Filter und 
Maske so einzustellen, dass alles durchgelassen wird.

von Tom (Gast)


Lesenswert?

ah okay, mit dem SID, bzw. EID stelle ich dann an den einzelnen Knoten 
ein, welche der vielen nachrichten empfangen werden kann, bzw. werden 
darf.
ist also bildlich die adresse des senders (also die maske) und der 
filter entscheidet dann, ob angenommen werden darf via vergleich?

von Tom (Gast)


Lesenswert?

Knoten A:

SID: 1
Filter: 2

Knoten B:

SID: 2
Filter: 1

----> Knoten B, kann nachrichten von A empfangen und umgekehrt, wenn 
jetzt aber eine nachricht mit SID: 3 kommt, dann kann weder A noch B 
empfangen?

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Hast du das getestet?

Ich hab dich gesagt, du sollst erst mal Filter und Maske weglassen. Das 
macht dir nur Probleme, wenn dus nicht 100%ig verstanden hast. Damit 
kannst du dich auseinandersetzen wenn der rest geht.

Setz mal alle Masken auf 0, dann müssten auch alle IDs durchkommen.

von Tom (Gast)


Lesenswert?

also wenn ich alle masken auf 0 gesetzt habe, dann geht alles durch, wie 
du geschrieben hast...

von Tom (Gast)


Lesenswert?

weißt du was der unterschied zwischen

message acceptance filter (CiRXFnSID)

und

acceptance filter mask (CiRXMnSID)

ist?

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Ja.
Mit der Maske kannst du die eintreffende ID maskieren.
damit sagst du im Prinzip welche Bits der ID überhaupt gefiltert werden 
sollen.
Wenn Maske = 0 wird kein Bit gefiltert.
Wenn Maske = 0x7FF kommen alle Bits in den Filter.

von Tom (Gast)


Lesenswert?

also irgendwie check ich das nicht....

ich bekomme vom bus einmal den identifier und die daten

identifier -> SID oder EID

dann habe ich den filter und die maske

kannst du mir das irgendwie an einem bsp. erklären?

z.b.

SID = 0x3BF = 1111011111   -> das ist der SID, der vom Knoten B stammt

Knoten A empfängt SID und Data

Filter & Maske ?

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Ich hoff ich erzähl dir jetzt kein blödsinn. ich habe die filter noch 
nicht oft benutzt.

Filtern kannst du nur die IDs.
Vergiss erst mal die EIDs.

Angenommen du willst alle ungeraden IDs wegfiltern:

Maske: 1 // für unterstes Bit
Filter: 0 // Alle geraden erlauben

wenn du die geraden weghaben willst, mach folgendes:

Maske: 1 // für unterstes Bit
Filter: 1 // Alle ungeraden erlauben


Alle Angaben ohne Gewähr ;-)

von Tom (Gast)


Lesenswert?

aha, also muss ich mir das so vorstellen:

SID = 0x7BF = 11111011111   Knoten B

Acceptance mask: Knoten A

CiRXMnSID = 0x000 = 00000000000  -> alle kommenden id`s werden 
durchgelassen

CiRXMnSID = 0x700 = 11100000000  -> nur die bits <10:8> werden an den 
filter weitergegeben

Acceptance filter: Knoten A

CiRXFnSID = 0x 7FF = 11111011111  -> nur diese ID wird erlaubt

-> alle bits werden verglichen, message kommt nur durch, wenn bits, die 
durch die maske kommen mit filter übereinstimmen


???

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Richtig, in deinem Beispiel würden alle IDs mit 0x7xx durchkommen.

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

gut dann hab ich das jetzt verstanden....

jetzt ist mir gerade noch was anderes aufgefallen:

wenn ich das signal am scope anschaue das ich sende...ist das immer 
gleich...egal, ob ich daten im register C1TX0B1 = 0xFF
stehen hab oder net...

das was über den CANH rausgeht sollte doch normalerweise so aufgebaut 
sein:

Start of frame <1>
SID <11>
RTR <1>
IDE <1>
RB0 <1>
DLC <4>
Data <8>
CRC <16>
ACK <2>
End of Frame <7>

<anzahl der bits>

im anhang hab ich die beiden scope-auszüge

einmal mit C1TX0B1 = 0x0 und dann mit 0xFF

--> wenn ich mir das so anschau, dann mach ich doch wohl noch irgendwo 
einen fehler....

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

hier der 2te ausdruck vom scope

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Hast du zwei Knoten verbunden?
Wenn die CAN Nachricht niemand empfängt und bestätigt, wird sie ständig 
weitergesendet.

von Tom (Gast)


Lesenswert?

ich hab nur einen knoten...vorerst...den zweiten knoten bau ich aber 
genauso auf wie den ersten, änder nur die sid und die maske ab...

das die nachricht ständig gesendet wird, klar..hab ich ja so ins prog. 
geschrieben...nur was da gesendet wird...damit komm ich noch nicht 
klar..

normalerweise müsste ich doch aus dem signal am CANH das Frame auslesen 
können und so vergleichen, was ich im prog gesendet hab und was da jetzt 
wirklich rauskommen tut...weil das scheint ja laut scope nicht daselbige 
zu sein..*leider*

wäre ja zu schön gewesen, wenns gleich ohne probleme gefunzt hätt...lol

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Da bei dir die Nachricht nie empfangen wird, wird diejenige, die als 
erstes gesendet wurde immer wieder gesendet. Daher ist es völlig ok, 
dass du immer dasselbe auf dem scope siehst.

So einfach kannst du mit dem Scope die CAN Nachricht nicht ablesen, weil 
du dazu erst mal deine wirklich zu sendende nachricht ausrechnen 
müsstest. Dazu musst du auch die Stuff Bits beachten. Ganz zu schweigen 
von der CRC. Ich habe noch keine Quelle gefunden die sagt wie die CRC 
berechnet wird. Weiss das jemand?

Bau erst mal den zweiten Knoten auf, dann erst kannst du sagen ob es 
geht oder nicht. Ein CAN Bus mit nur einem Teilnehmer gibt es nicht.

von Tom (Gast)


Lesenswert?

okay, mach ich mal,bzw. bin schon dabei

von Tom (Gast)


Lesenswert?

mit gleich bei den bildern meinte ich aber nicht, dass die message immer 
gleich bleibt, sondern

das wenn ich das wort 0xff schicke am scope bild 1 kommt

das wenn ich das wort 0x0 schicke am scope bild 2 kommt

jedesmal neu gestartet und initialisiert, deswegen meinte ich das ich da 
nen unterschied sehen müsste

wenn ich 0xff und 0x00 hintereinander schicken würde, dann wärs mir auch 
klar, aber da erst das eine wort (1), dann ein neues programming und 
dann wort 2 geschickt wird....kommt mir das spanisch vor

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Achso ok.
Aber ich würde trotzdem erst mal den zweiten Knoten bauen, bevor ich mir 
da weiter Gedanken drüber mache.

von Tom (Gast)


Lesenswert?

misst jetzt muss ich mir erst noch so nen can-treiber besorgen, sonst 
kann ich den 2ten knoten nicht anbinden....

naja ich mach mal und poste wieder wenns da ist..

merci

und nen schönes wochenende

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Bei zwei Knoten kannst du ausnahmsweise mal die CANRX und CANTX 
Leitungen gekreuzt verbinden.

Aber wenn der zweite Transceiver da ist, vergisst du das wieder !

von Tom (Gast)


Lesenswert?

also ich hab jetzt versucht den zweiten knoten auf meinem dsPICDem 28 zu 
realisieren, scheitere aber da noch an der mangelnden Beschreibung zu 
dem Board. Die Register für den Can bleiben bei einem dsPIC30F4012 
gleich wie beim 6014, aber die portinitialisierung, bzw. beim clock ist 
irgendwas anders...des funzt net....ich probier mal weiter. Das mit den 
überkreuzten Leitungen lass ich mal lieber, net das ich das aus dusselei 
dann so lass und mich wunder wenn nichts geht....lol

von Tom (Gast)


Angehängte Dateien:

Lesenswert?

ui ui ui....

jetzt geht ein neuer bug um....habs mal in einem anderen thread 
gepostet...

bitte mal durchlesen wenns geht...

danke

Thomas


Beitrag "dsPIC30F6014 using 2 CAN-Module"

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

wozu hast du jetzt noch einen Thread aufgemacht?
Es ist schwer genug hier einen wiederzufinden...

von Tom (Gast)


Lesenswert?

So langsam zweifel ich wieder daran ob ich das richtig gemacht habe...

Wenn ich das Progi so, wie ich es geschrieben habe auf dem gleichen 
board, aber mit verschiedenen ds teste, kommt jedesmal ein anderes 
signal am ende raus....

kann es sein, dass ich beim init, bzw. bei den timings einen 
gravierenden fehler drinn habe, so dass ich wenn ich was senden will, 
immer das error-frame gesendet bekomme?

hab mich mit der frage noch nicht auseinandergesezt. kennst du dich 
damit aus?

von Meister E. (edson)


Lesenswert?

>du eh der einzige bist der hier zurückschreibt, bzw. bereit ist mit
>bei meinem problem zu helfen

Ok Tom, wenn Du auf meine Fragen nicht eingehen willst, wirst Du schon 
mit Willivonbienemaja's (großzügiger) Hilfe auskommen müssen. (Oder 
liest du deinen zweit-Thread nicht?)

Gruss,
Edson

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.