1 | /* Includes */
|
2 | #include "stm32f4xx.h"
|
3 | #include "system_stm32f4xx.h"
|
4 | #include "stm32f4_discovery.h"
|
5 | #include "main.h"
|
6 | #include "stm32f4xx_can.h"
|
7 | /* Private macro */
|
8 | /* Private variables */
|
9 | CAN_InitTypeDef CAN_InitStructure;
|
10 | CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
11 |
|
12 | GPIO_InitTypeDef GPIO_InitStructure;
|
13 |
|
14 | CanTxMsg TxMessage;
|
15 | CanRxMsg RxMessage;
|
16 | CanTxMsg TxMessage2;
|
17 | CanRxMsg RxMessage2;
|
18 | /* Private function prototypes */
|
19 | void CAN_Config(void);
|
20 | void NVIC_Config(void);
|
21 | void LDoff(void);
|
22 | /* Private functions */
|
23 | //Pin definitions
|
24 |
|
25 | #define CAN_RX_PIN GPIO_Pin_8
|
26 | #define CAN_TX_PIN GPIO_Pin_9
|
27 |
|
28 | #define CAN_RX_SOURCE GPIO_PinSource8
|
29 | #define CAN_TX_SOURCE GPIO_PinSource9
|
30 |
|
31 | //Port definitions
|
32 | #define CAN_COM_PORT GPIOB
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | //Clock definitions
|
38 | #define CAN_GPIO_CLK RCC_AHB1Periph_GPIOB
|
39 | #define CAN_CLK RCC_APB1Periph_CAN1
|
40 |
|
41 |
|
42 |
|
43 | #define CAN2_RX_PIN GPIO_Pin_5
|
44 | #define CAN2_TX_PIN GPIO_Pin_6
|
45 |
|
46 | #define CAN2_RX_SOURCE GPIO_PinSource5
|
47 | #define CAN2_TX_SOURCE GPIO_PinSource6
|
48 |
|
49 | //Port definitions
|
50 | #define CAN2_COM_PORT GPIOB
|
51 |
|
52 | //Clock definitions
|
53 | #define CAN2_GPIO_CLK RCC_AHB1Periph_GPIOB
|
54 | #define CAN2_CLK RCC_APB1Periph_CAN2
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | void CAN_Config(void)
|
60 | {
|
61 | GPIO_InitTypeDef GPIO_InitStructure;
|
62 |
|
63 | /* CAN GPIOs configuration **************************************************/
|
64 |
|
65 | /* Enable GPIO clock */
|
66 | RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);
|
67 |
|
68 | /* Connect CAN pins to AF9 */
|
69 | GPIO_PinAFConfig(CAN_COM_PORT, CAN_RX_SOURCE, GPIO_AF_CAN1);
|
70 | GPIO_PinAFConfig(CAN_COM_PORT, CAN_TX_SOURCE, GPIO_AF_CAN1);
|
71 |
|
72 | /* Configure CAN RX and TX pins */
|
73 | GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
|
74 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
75 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
76 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
77 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
78 | GPIO_Init(CAN_COM_PORT, &GPIO_InitStructure);
|
79 |
|
80 | /* CAN configuration ********************************************************/
|
81 | /* Enable CAN clock */
|
82 | RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);
|
83 |
|
84 | //CAN1
|
85 | /* CAN register init */
|
86 | CAN_DeInit(CAN1);
|
87 |
|
88 | /* CAN cell init */
|
89 | CAN_DBGFreeze(CAN1, DISABLE);
|
90 | CAN_InitStructure.CAN_TTCM = DISABLE;
|
91 | CAN_InitStructure.CAN_ABOM = DISABLE;
|
92 | CAN_InitStructure.CAN_AWUM = ENABLE;
|
93 | CAN_InitStructure.CAN_NART = ENABLE;
|
94 | CAN_InitStructure.CAN_RFLM = DISABLE;
|
95 | CAN_InitStructure.CAN_TXFP = ENABLE;
|
96 | CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
97 | CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
|
98 |
|
99 | /* CAN Baudrate = 500 kBps (CAN clocked at 42MHz) */
|
100 | CAN_InitStructure.CAN_BS1 = CAN_BS1_15tq;
|
101 | CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
102 | CAN_InitStructure.CAN_Prescaler = 4;
|
103 | CAN_Init(CAN1, &CAN_InitStructure);
|
104 |
|
105 | /* CAN filter init */
|
106 | CAN_FilterInitStructure.CAN_FilterNumber = 0;
|
107 | CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
108 | CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
109 | CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
|
110 | CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
|
111 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
|
112 | CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|
113 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
|
114 | CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
115 | CAN_FilterInit(&CAN_FilterInitStructure);
|
116 |
|
117 | /* Transmit Structure preparation */
|
118 | TxMessage.StdId = 0x321;
|
119 | TxMessage.ExtId = 0x01;
|
120 | TxMessage.RTR = CAN_RTR_DATA;
|
121 | TxMessage.IDE = CAN_ID_STD;
|
122 | TxMessage.DLC = 8;
|
123 |
|
124 | /* Enable FIFO 0 message pending Interrupt */
|
125 | CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
|
126 | }
|
127 |
|
128 |
|
129 | void CAN2_Config(void)
|
130 | {
|
131 | GPIO_InitTypeDef GPIO_InitStructure;
|
132 |
|
133 | /* CAN GPIOs configuration **************************************************/
|
134 |
|
135 | RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);
|
136 | /* Enable GPIO clock */
|
137 | RCC_AHB1PeriphClockCmd(CAN2_GPIO_CLK, ENABLE);
|
138 |
|
139 | /* Connect CAN pins to AF9 */
|
140 | GPIO_PinAFConfig(CAN2_COM_PORT, CAN2_RX_SOURCE, GPIO_AF_CAN2);
|
141 | GPIO_PinAFConfig(CAN2_COM_PORT, CAN2_TX_SOURCE, GPIO_AF_CAN2);
|
142 |
|
143 | /* Configure CAN RX and TX pins */
|
144 | GPIO_InitStructure.GPIO_Pin = CAN2_RX_PIN | CAN2_TX_PIN;
|
145 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
146 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
147 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
148 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
149 | GPIO_Init(CAN_COM_PORT, &GPIO_InitStructure);
|
150 |
|
151 | /* CAN configuration ********************************************************/
|
152 | /* Enable CAN clock */
|
153 | RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);
|
154 | RCC_APB1PeriphClockCmd(CAN2_CLK, ENABLE);
|
155 |
|
156 | //CAN1
|
157 | /* CAN register init */
|
158 | CAN_DeInit(CAN2);
|
159 |
|
160 | /* CAN cell init */
|
161 | CAN_DBGFreeze(CAN2, DISABLE);
|
162 | CAN_InitStructure.CAN_TTCM = DISABLE;
|
163 | CAN_InitStructure.CAN_ABOM = DISABLE;
|
164 | CAN_InitStructure.CAN_AWUM = ENABLE;
|
165 | CAN_InitStructure.CAN_NART = ENABLE;
|
166 | CAN_InitStructure.CAN_RFLM = DISABLE;
|
167 | CAN_InitStructure.CAN_TXFP = ENABLE;
|
168 | CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
|
169 | CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
|
170 |
|
171 | /* CAN Baudrate = 500 kBps (CAN clocked at 42MHz) */
|
172 | CAN_InitStructure.CAN_BS1 = CAN_BS1_15tq;
|
173 | CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
|
174 | CAN_InitStructure.CAN_Prescaler = 4;
|
175 | CAN_Init(CAN2, &CAN_InitStructure);
|
176 |
|
177 | /* CAN filter init */
|
178 | CAN_FilterInitStructure.CAN_FilterNumber = 14;
|
179 | CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
|
180 | CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
|
181 | CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
|
182 | CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
|
183 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
|
184 | CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
|
185 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 1;
|
186 | CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
|
187 | CAN_FilterInit(&CAN_FilterInitStructure);
|
188 |
|
189 | /* Transmit Structure preparation */
|
190 | TxMessage2.StdId = 0x123;
|
191 | TxMessage2.ExtId = 0x01;
|
192 | TxMessage2.RTR = CAN_RTR_DATA;
|
193 | TxMessage2.IDE = CAN_ID_STD;
|
194 | TxMessage2.DLC = 8;
|
195 |
|
196 | /* Enable FIFO 0 message pending Interrupt */
|
197 | CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
|
198 | }
|
199 |
|
200 | void NVIC_Config(void)
|
201 | {
|
202 | NVIC_InitTypeDef NVIC_InitStructure;
|
203 | NVIC_InitTypeDef NVIC2_InitStructure;
|
204 |
|
205 | NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
|
206 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
|
207 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
|
208 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
209 | NVIC_Init(&NVIC_InitStructure);
|
210 |
|
211 |
|
212 | NVIC2_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
|
213 | NVIC2_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
|
214 | NVIC2_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
|
215 | NVIC2_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
216 | NVIC_Init(&NVIC2_InitStructure);
|
217 |
|
218 | }
|
219 |
|
220 |
|
221 | void Init_RxMes(CanRxMsg *RxMessage)
|
222 | {
|
223 | uint8_t i = 0;
|
224 |
|
225 | RxMessage->StdId = 0x00;
|
226 | RxMessage->ExtId = 0x00;
|
227 | RxMessage->IDE = CAN_ID_STD;
|
228 | RxMessage->DLC = 0;
|
229 | RxMessage->FMI = 0;
|
230 | for (i = 0;i < 8;i++)
|
231 | {
|
232 | RxMessage->Data[i] = 0x00;
|
233 | }
|
234 | }
|
235 |
|
236 |
|
237 |
|
238 | int main(void)
|
239 | {
|
240 |
|
241 |
|
242 | /* Initialize LEDs */
|
243 | STM_EVAL_LEDInit(LED3);
|
244 | STM_EVAL_LEDInit(LED4);
|
245 | STM_EVAL_LEDInit(LED5);
|
246 | STM_EVAL_LEDInit(LED6);
|
247 |
|
248 | /* Turn on LEDs */
|
249 | STM_EVAL_LEDOn(LED3);
|
250 | STM_EVAL_LEDOn(LED4);
|
251 | STM_EVAL_LEDOn(LED5);
|
252 | STM_EVAL_LEDOn(LED6);
|
253 |
|
254 | NVIC_Config();
|
255 |
|
256 | CAN_Config();
|
257 | CAN2_Config();
|
258 | Init_RxMes(&RxMessage);
|
259 | Init_RxMes(&RxMessage2);
|
260 |
|
261 | TxMessage.Data[0] = 0x09;
|
262 | TxMessage.Data[1] = 0x08;
|
263 | TxMessage.Data[2] = 0x07;
|
264 | TxMessage.Data[3] = 0x06;
|
265 | TxMessage.Data[4] = 0x05;
|
266 | CAN_Transmit(CAN2, &TxMessage);
|
267 | CAN_Transmit(CAN1, &TxMessage);
|
268 |
|
269 |
|
270 |
|
271 | /* Infinite loop */
|
272 | while (1)
|
273 | {
|
274 |
|
275 | }
|
276 | }
|
277 |
|
278 | void CAN1_RX0_IRQHandler(void)
|
279 | {
|
280 |
|
281 | CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);
|
282 | STM_EVAL_LEDToggle(RxMessage.Data[0]);
|
283 |
|
284 | }
|
285 |
|
286 | void CAN2_RX0_IRQHandler(void)
|
287 | {
|
288 |
|
289 | LD1(1);
|
290 | CAN_Receive(CAN2, CAN_FIFO1, &RxMessage2);
|
291 | STM_EVAL_LEDToggle(RxMessage2.Data[0]);
|
292 |
|
293 | }
|