Hallo zusammen, ich möchte gerne zwischen zwei Microcontrollern (beide F28335) per CAN-Bus kommunizieren. Dazu habe ich von den beiden gleichen Microcontrollern die Pins 30 miteinander verbunden (CANTXA) und auch die Pins 31 von beiden (CANRXA). Zwichen diesen beiden Leitungen (nur ein paar Zentimeter lang) habe ich ein 68 Ohm Widerstand gebastelt (anstelle von 2 120 Ohm Wid. an den Enden). Die beiden Programme für die Senderseite- und Empfängerseite sind hier aufgelistet: Senderseite:
1 | /* |
2 | * This script is intended to send messages on eCANA |
3 | * Messages are send to the message box address: 0xFF |
4 | * */ |
5 | |
6 | |
7 | #include "DSP28x_Project.h" // Device Headerfile and Examples Include File |
8 | // Prototype statements for functions found within this file. |
9 | void delay(); |
10 | void Gpio_select(void); |
11 | void SendCANMsg(int16 MBXnum, Uint32 MBXDL, Uint32 MBXDH); |
12 | |
13 | // CAN |
14 | #define CAN_TARGET_MAILBOX_ADDRESS 0xFF |
15 | #define CAN_BITS_SEND 4 |
16 | |
17 | |
18 | |
19 | void main(void) |
20 | { |
21 | |
22 | // eCAN control registers require read/write access using 32-bits. Thus we |
23 | // will create a set of shadow registers for this example. These shadow |
24 | // registers will be used to make sure the access is 32-bits and not 16. |
25 | struct ECAN_REGS ECanaShadow; |
26 | struct ECAN_MBOXES ECanMboxShadow; |
27 | |
28 | // Step 1. Initialize System Control: |
29 | // PLL, WatchDog, enable Peripheral Clocks |
30 | // This example function is found in the DSP2833x_SysCtrl.c file. |
31 | InitSysCtrl(); |
32 | |
33 | |
34 | // Step 2. Initalize GPIO: |
35 | // This example function is found in the DSP2833x_Gpio.c file and |
36 | // illustrates how to set the GPIO to it's default state. |
37 | // InitGpio(); // Skipped for this example |
38 | |
39 | Gpio_select(); // for LEDs |
40 | InitECanaGpio(); //for CAN bus |
41 | |
42 | // Step 3. Clear all interrupts and initialize PIE vector table: |
43 | // Disable CPU interrupts |
44 | DINT; |
45 | |
46 | // Initialize the PIE control registers to their default state. |
47 | // The default state is all PIE interrupts disabled and flags |
48 | // are cleared. |
49 | // This function is found in the DSP2833x_PieCtrl.c file. |
50 | InitPieCtrl(); |
51 | |
52 | // Disable CPU interrupts and clear all CPU interrupt flags: |
53 | IER = 0x0000; |
54 | IFR = 0x0000; |
55 | |
56 | // Initialize the PIE vector table with pointers to the shell Interrupt |
57 | // Service Routines (ISR). |
58 | // This will populate the entire table, even if the interrupt |
59 | // is not used in this example. This is useful for debug purposes. |
60 | // The shell ISR routines are found in DSP2833x_DefaultIsr.c. |
61 | // This function is found in DSP2833x_PieVect.c. |
62 | InitPieVectTable(); |
63 | |
64 | // Step 5. User specific code, enable interrupts |
65 | // CAN |
66 | InitECana(); // Initialize eCAN-A module |
67 | |
68 | ECanaRegs.CANME.all = 0x00000000; // Disable all mailboxes |
69 | |
70 | // Transmitting MBOX1 |
71 | ECanMboxShadow.MBOX1.MSGID.bit.STDMSGID = CAN_TARGET_MAILBOX_ADDRESS; |
72 | ECanaMboxes.MBOX1.MSGID.all = ECanMboxShadow.MBOX1.MSGID.all; |
73 | |
74 | |
75 | ECanaShadow.CANMD.all = ECanaRegs.CANMD.all; |
76 | ECanaShadow.CANMD.bit.MD1 = 0; // Mailbox 1 : transmitting mailbox |
77 | ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; |
78 | |
79 | // Enable Mailboxes |
80 | ECanaShadow.CANME.all = ECanaRegs.CANME.all; |
81 | ECanaShadow.CANME.bit.ME1 = 1; |
82 | ECanaRegs.CANME.all = ECanaShadow.CANME.all; |
83 | |
84 | ECanaMboxes.MBOX1.MSGCTRL.bit.DLC = CAN_BITS_SEND; |
85 | |
86 | ECanaMboxes.MBOX1.MSGCTRL.bit.RTR = 0; |
87 | |
88 | GpioDataRegs.GPBDAT.bit.GPIO34 = 1;//LED3 off |
89 | |
90 | // Step 6. IDLE loop. Just sit and loop forever (optional): |
91 | for(;;) |
92 | { |
93 | SendCANMsg(1, 2, 3); |
94 | if(GpioDataRegs.GPBDAT.bit.GPIO34) |
95 | GpioDataRegs.GPBDAT.bit.GPIO34 = 0;//LED3 on |
96 | else |
97 | GpioDataRegs.GPBDAT.bit.GPIO34 = 1;//LED3 off |
98 | delay(); |
99 | |
100 | } |
101 | |
102 | } |
103 | void SendCANMsg(int16 MBXnum, Uint32 MBXDL, Uint32 MBXDH) |
104 | { |
105 | volatile struct MBOX *srcMBox; |
106 | |
107 | if (0 <= MBXnum && MBXnum <= 32) |
108 | { |
109 | Uint32 MBXflag = (0x00000001 << MBXnum); |
110 | |
111 | srcMBox = &ECanaMboxes.MBOX0 + MBXnum; |
112 | srcMBox->MDL.all = MBXDL; |
113 | srcMBox->MDH.all = MBXDH; |
114 | |
115 | ECanaRegs.CANTRS.all = MBXflag; |
116 | while(ECanaRegs.CANTA.all != MBXflag) {} |
117 | ECanaRegs.CANTA.all = MBXflag; |
118 | } |
119 | } |
120 | |
121 | void delay() |
122 | { |
123 | double i; |
124 | for (i = 0; i < 2000000; i++) |
125 | { |
126 | } |
127 | |
128 | } |
129 | void Gpio_select(void) |
130 | { |
131 | |
132 | |
133 | EALLOW; |
134 | GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO |
135 | GpioCtrlRegs.GPAMUX2.all = 0x00000000; // All GPIO |
136 | GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO |
137 | GpioCtrlRegs.GPADIR.all = 0xFFFFFFFF; // All outputs |
138 | GpioCtrlRegs.GPBDIR.all = 0x0000000F; // All outputs |
139 | EDIS; |
140 | |
141 | } |
Empfangsseite:
1 | /* |
2 | * This script is intended to wait for message on eCANA |
3 | * Receiving message box address: 0xFF |
4 | * */ |
5 | |
6 | |
7 | #include "DSP28x_Project.h" // Device Headerfile and Examples Include File |
8 | // Prototype statements for functions found within this file. |
9 | void delay(); |
10 | void Gpio_select(void); |
11 | void ReceiveCANMsg(int16 MBXnum); |
12 | |
13 | // CAN |
14 | #define CAN_RECEIVE_MAILBOX_ADDRESS 0xFF |
15 | #define CAN_RECEIVER CAN_RECEIVE_MAILBOX_ADDRESS // test case |
16 | #define CAN_BITS_SEND 4 |
17 | |
18 | |
19 | |
20 | void main(void) |
21 | { |
22 | |
23 | // eCAN control registers require read/write access using 32-bits. Thus we |
24 | // will create a set of shadow registers for this example. These shadow |
25 | // registers will be used to make sure the access is 32-bits and not 16. |
26 | struct ECAN_REGS ECanaShadow; |
27 | struct ECAN_MBOXES ECanMboxShadow; |
28 | |
29 | // Step 1. Initialize System Control: |
30 | // PLL, WatchDog, enable Peripheral Clocks |
31 | // This example function is found in the DSP2833x_SysCtrl.c file. |
32 | InitSysCtrl(); |
33 | |
34 | |
35 | // Step 2. Initalize GPIO: |
36 | // This example function is found in the DSP2833x_Gpio.c file and |
37 | // illustrates how to set the GPIO to it's default state. |
38 | // InitGpio(); // Skipped for this example |
39 | |
40 | Gpio_select(); // for LEDs |
41 | InitECanaGpio(); //for CAN bus |
42 | |
43 | // Step 3. Clear all interrupts and initialize PIE vector table: |
44 | // Disable CPU interrupts |
45 | DINT; |
46 | |
47 | // Initialize the PIE control registers to their default state. |
48 | // The default state is all PIE interrupts disabled and flags |
49 | // are cleared. |
50 | // This function is found in the DSP2833x_PieCtrl.c file. |
51 | InitPieCtrl(); |
52 | |
53 | // Disable CPU interrupts and clear all CPU interrupt flags: |
54 | IER = 0x0000; |
55 | IFR = 0x0000; |
56 | |
57 | // Initialize the PIE vector table with pointers to the shell Interrupt |
58 | // Service Routines (ISR). |
59 | // This will populate the entire table, even if the interrupt |
60 | // is not used in this example. This is useful for debug purposes. |
61 | // The shell ISR routines are found in DSP2833x_DefaultIsr.c. |
62 | // This function is found in DSP2833x_PieVect.c. |
63 | InitPieVectTable(); |
64 | |
65 | // Step 5. User specific code, enable interrupts |
66 | // CAN |
67 | InitECana(); // Initialize eCAN-A module |
68 | |
69 | ECanaRegs.CANME.all = 0x00000000; // Disable all mailboxes |
70 | |
71 | |
72 | // Receiving MBOX2 |
73 | ECanMboxShadow.MBOX2.MSGID.bit.AAM = 0; // auto answer mode off |
74 | ECanMboxShadow.MBOX2.MSGID.bit.AME = 0; // acceptance mask disable |
75 | ECanMboxShadow.MBOX2.MSGID.bit.IDE = 0; |
76 | ECanMboxShadow.MBOX2.MSGID.bit.STDMSGID = CAN_RECEIVE_MAILBOX_ADDRESS; |
77 | ECanaMboxes.MBOX2.MSGID.all = ECanMboxShadow.MBOX2.MSGID.all; |
78 | |
79 | |
80 | ECanaShadow.CANMD.all = ECanaRegs.CANMD.all; |
81 | ECanaShadow.CANMD.bit.MD2 = 1; // Mailbox 2 : receiving mailbox |
82 | ECanaRegs.CANMD.all = ECanaShadow.CANMD.all; |
83 | |
84 | // Enable Mailboxes |
85 | ECanaShadow.CANME.all = ECanaRegs.CANME.all; |
86 | ECanaShadow.CANME.bit.ME2 = 1; |
87 | ECanaRegs.CANME.all = ECanaShadow.CANME.all; |
88 | |
89 | ECanaMboxes.MBOX2.MSGCTRL.bit.DLC = CAN_BITS_SEND; |
90 | |
91 | ECanaMboxes.MBOX2.MSGCTRL.bit.RTR = 0; |
92 | |
93 | GpioDataRegs.GPBDAT.bit.GPIO34 = 1;//LED3 off |
94 | |
95 | // Step 6. IDLE loop. Just sit and loop forever (optional): |
96 | for(;;) |
97 | { |
98 | if (ECanaRegs.CANRMP.all > 0 && ECanaRegs.CANGIF0.bit.MIV0 == 2) |
99 | { |
100 | ReceiveCANMsg (2); |
101 | } |
102 | |
103 | } |
104 | |
105 | } |
106 | void ReceiveCANMsg(int16 MBXnum) |
107 | { |
108 | volatile struct MBOX *srcMBox; |
109 | Uint32 raw_datah; |
110 | Uint32 raw_datal; |
111 | |
112 | if (0 <= MBXnum && MBXnum <= 32) |
113 | { |
114 | // Get pointer to mailbox struct and grab data |
115 | srcMBox = &ECanaMboxes.MBOX0 + MBXnum; |
116 | raw_datah = srcMBox->MDH.all; |
117 | raw_datal = srcMBox->MDL.all; |
118 | ECanaRegs.CANRMP.all = (0x00000001 << MBXnum); |
119 | |
120 | /* Process Data */ |
121 | if(GpioDataRegs.GPBDAT.bit.GPIO34) |
122 | GpioDataRegs.GPBDAT.bit.GPIO34 = 0;//LED3 on |
123 | else |
124 | GpioDataRegs.GPBDAT.bit.GPIO34 = 1;//LED3 off |
125 | } |
126 | } |
127 | |
128 | void delay() |
129 | { |
130 | double i; |
131 | for (i = 0; i < 2000000; i++) |
132 | { |
133 | } |
134 | |
135 | } |
136 | void Gpio_select(void) |
137 | { |
138 | |
139 | |
140 | EALLOW; |
141 | GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO |
142 | GpioCtrlRegs.GPAMUX2.all = 0x00000000; // All GPIO |
143 | GpioCtrlRegs.GPAMUX1.all = 0x00000000; // All GPIO |
144 | GpioCtrlRegs.GPADIR.all = 0xFFFFFFFF; // All outputs |
145 | GpioCtrlRegs.GPBDIR.all = 0x0000000F; // All outputs |
146 | EDIS; |
147 | |
148 | } |
Was mache ich falsch, dass die Signale nicht auf der Empfangsseite ankommen? (Led blinkt nicht) Vielen Dank und viele Grüße Sebastian