📄 can2.lst
字号:
210 void external_osc (void)
211 {
212 1 int n; // local variable used in delay FOR loop.
213 1 SFRPAGE = CONFIG_PAGE; // switch to config page to config oscillator
214 1 OSCXCN = 0x77; // start external oscillator; 22.1 MHz Crystal
215 1 // system clock is 22.1 MHz / 2 = 11.05 MHz
216 1 for (n=0;n<255;n++); // delay about 1ms
217 1 while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
218 1 CLKSEL |= 0x01; // switch to external oscillator
219 1 }
220
221 void config_IO (void)
222 {
223 1 SFRPAGE = CONFIG_PAGE; //Port SFR's on Configuration page
224 1 XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull digital output
225 1
226 1 P5MDOUT |= 0x10; // Configure P5.4 as push-pull to drive LED
227 1
228 1 XBR2 = 0x40; // Enable Crossbar/low ports
229 1 }
230
231 ////////////////////////////////////////////////////////////////////////////////
232 //CAN Functions
233 ////////////////////////////////////////////////////////////////////////////////
234
235
236 //Clear Message Objects
237 void clear_msg_objects (void)
238 {
239 1 SFRPAGE = CAN0_PAGE;
240 1 CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1
241 1 CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to Msg Obj
C51 COMPILER V7.02b CAN2 01/20/2006 11:20:24 PAGE 5
242 1 for (i=1;i<33;i++)
243 1 {
244 2 CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
245 2 CAN0DATL = i;
246 2 }
247 1 }
248
249 //Initialize Message Object for RX
250 void init_msg_object_RX (char MsgNum)
251 {
252 1 SFRPAGE = CAN0_PAGE;
253 1 CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
254 1 CAN0DAT = 0x00B8; // Set to WRITE, and alter all Msg Obj except ID MASK
255 1 // and data bits
256 1 CAN0ADR = IF1ARB1; // Point to arbitration1 register
257 1 CAN0DAT = 0x0000; // Set arbitration1 ID to "0"
258 1 CAN0DAT = 0x8000; // Arb2 high byte:Set MsgVal bit, no extended ID,
259 1 // Dir = RECEIVE
260 1 CAN0DAT = 0x0480; // Msg Cntrl: set RXIE, remote frame function disabled
261 1 CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
262 1 CAN0DATL = MsgNum; // Select Msg Obj passed into function parameter list
263 1 // --initiates write to Msg Obj
264 1 // 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
265 1 }
266
267 //Initialize Message Object for TX
268 void init_msg_object_TX (char MsgNum)
269 {
270 1 SFRPAGE = CAN0_PAGE;
271 1 CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
272 1 CAN0DAT = 0x00B2; // Set to WRITE, & alter all Msg Obj except ID MASK bits
273 1 CAN0ADR = IF1ARB1; // Point to arbitration1 register
274 1 CAN0DAT = 0x0000; // Set arbitration1 ID to highest priority
275 1 CAN0DAT = 0xA004; // Autoincrement to Arb2 high byte:
276 1 // Set MsgVal bit, no extended ID, Dir = WRITE
277 1 CAN0DAT = 0x0081; // Msg Cntrl: DLC = 1, remote frame function not enabled
278 1 CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
279 1 CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter list
280 1 // --initiates write to Msg Obj
281 1 // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
282 1 }
283
284 //Start CAN
285 void start_CAN (void)
286 {
287 1 /* Calculation of the CAN bit timing :
288 1
289 1 System clock f_sys = 22.1184 MHz/2 = 11.0592 MHz.
290 1 System clock period t_sys = 1/f_sys = 90.422454 ns.
291 1 CAN time quantum tq = t_sys (at BRP = 0)
292 1
293 1 Desired bit rate is 1 MBit/s, desired bit time is 1000 ns.
294 1 Actual bit time = 11 tq = 996.65ns ~ 1000 ns
295 1 Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381%
296 1
297 1 CAN bus length = 10 m, with 5 ns/m signal delay time.
298 1 Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns
299 1 (maximum loop delay between CAN nodes)
300 1
301 1 Prop_Seg = 5 tq = 452 ns ( >= 400 ns).
302 1 Sync_Seg = 1 tq
303 1
C51 COMPILER V7.02b CAN2 01/20/2006 11:20:24 PAGE 6
304 1 Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq
305 1 Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq
306 1 SJW = (min(Phase_Seg1, 4) tq = 2 tq
307 1
308 1 TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6
309 1 TSEG2 = (Phase_Seg2 - 1) = 2
310 1 SJW_p = (SJW - 1) = 1
311 1
312 1 Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640
313 1
314 1 Clock tolerance df :
315 1
316 1 A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2))
317 1 B: df < SJW / (20 * bit_time)
318 1
319 1 A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246%
320 1 B: df < 2/(20*11) = 1/110 = 0.9091%
321 1
322 1 Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz)
323 1 */
324 1
325 1 SFRPAGE = CAN0_PAGE;
326 1 CAN0CN |= 0x41; // Configuration Change Enable CCE and INIT
327 1 CAN0ADR = BITREG ; // Point to Bit Timing register
328 1 CAN0DAT = 0x2640; // see above
329 1
330 1 CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
331 1 CAN0DAT = 0x0087; // Config for TX : WRITE to CAN RAM, write data bytes,
332 1 // set TXrqst/NewDat, clr IntPnd
333 1
334 1 // RX-IF2 operation may interrupt TX-IF1 operation
335 1 CAN0ADR = IF2CMDMSK; // Point to Command Mask 2
336 1 CAN0DATL = 0x1F; // Config for RX : READ CAN RAM, read data bytes,
337 1 // clr NewDat and IntPnd
338 1 CAN0CN |= 0x06; // Global Int. Enable IE and SIE
339 1 CAN0CN &= ~0x41; // Clear CCE and INIT bits, starts CAN state machine
340 1 }
341
342 //Transmit CAN frame to turn other node's LED ON
343 void transmit_turn_LED_ON (char MsgNum)
344 {
345 1 SFRPAGE = CAN0_PAGE; // IF1 already set up for TX
346 1 CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
347 1 CAN0DAT = 0x0087; // Config to WRITE to CAN RAM, write data bytes,
348 1 // set TXrqst/NewDat, Clr IntPnd
349 1 CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field
350 1 CAN0DATL = 0x11; // Ones signals to turn LED's light ON in data A1 field
351 1 CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
352 1 CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
353 1 }
354
355 //Transmit CAN Frame to turn other node's LED OFF
356 void transmit_turn_LED_OFF (char MsgNum)
357 {
358 1 SFRPAGE = CAN0_PAGE; // IF1 already set up for TX
359 1 CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field
360 1 CAN0DATL = 0x00; // Zero signals to turn LED's light ON in Data A1 field
361 1 CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
362 1 CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
363 1 }
364
365
C51 COMPILER V7.02b CAN2 01/20/2006 11:20:24 PAGE 7
366 // Receive Data from the IF2 buffer
367 void receive_data (char MsgNum)
368 {
369 1 char virtual_button;
370 1 char SFRPAGE_SAVE = SFRPAGE; // Save SFRPAGE
371 1 SFRPAGE = CAN0_PAGE; // IF1 already set up for RX
372 1 CAN0ADR = IF2CMDRQST;// Point to Command Request Reg.
373 1 CAN0DATL = MsgNum; // Move new data for RX from Msg Obj "MsgNum"
374 1 // Move new data to a
375 1 CAN0ADR = IF2DATA1; // Point to 1st byte of Data Field
376 1
377 1 virtual_button = CAN0DATL;
378 1 SFRPAGE = CONFIG_PAGE;
379 1 if (virtual_button == 0x11) //Ones is signal from other node to turn LED ON
380 1 LED_1;
381 1 else
382 1 LED_0; //Otherwise turn LED OFF (message was one's)
383 1 SFRPAGE = SFRPAGE_SAVE;
384 1 }
385
386 ////////////////////////////////////////////////////////////////////////////////
387 //Interrupt Service Routine
388 ////////////////////////////////////////////////////////////////////////////////
389 void ISRname (void) interrupt 19
390 {
391 1 char SFRPAGE_SAVE = SFRPAGE; // Save SFRPAGE
392 1 SFRPAGE = CAN0_PAGE;
393 1
394 1 status = CAN0STA;
395 1 if ((status&0x10) != 0)
396 1 { // RxOk is set, interrupt caused by reception
397 2 CAN0STA = (CAN0STA&0xEF)|0x07; // Reset RxOk, set LEC to NoChange
398 2 /* read message number from CAN INTREG */
399 2 receive_data (0x01); // Up to now, we have only one RX message
400 2 }
401 1 if ((status&0x08) != 0)
402 1 { // TxOk is set, interrupt caused by transmision
403 2 CAN0STA = (CAN0STA&0xF7)|0x07; // Reset TxOk, set LEC to NoChange
404 2 }
405 1 if (((status&0x07) != 0)&&((status&0x07) != 7))
406 1 { // Error interrupt, LEC changed
407 2 /* error handling ? */
408 2 CAN0STA = CAN0STA|0x07; // Set LEC to NoChange
409 2 }
410 1 SFRPAGE = SFRPAGE_SAVE;
411 1 }
412
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 450 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 38 1
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -