📄 f33x_smbus_master.lst
字号:
286 1 TR1 = 1; // Timer1 enabled
287 1 }
288
289 //-----------------------------------------------------------------------------
290 // Timer3_Init
291 //-----------------------------------------------------------------------------
292 //
293 // Return Value : None
294 // Parameters : None
295 //
296 // Timer3 configured for use by the SMBus low timeout detect feature as
297 // follows:
298 // - Timer3 in 16-bit auto-reload mode
299 // - SYSCLK/12 as Timer3 clock source
300 // - Timer3 reload registers loaded for a 25ms overflow period
301 // - Timer3 pre-loaded to overflow after 25ms
302 // - Timer3 enabled
303 //
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 6
304 void Timer3_Init (void)
305 {
306 1 TMR3CN = 0x00; // Timer3 configured for 16-bit auto-
307 1 // reload, low-byte interrupt disabled
308 1
309 1 CKCON &= ~0x40; // Timer3 uses SYSCLK/12
310 1
311 1 TMR3RL = -(SYSCLK/12/40); // Timer3 configured to overflow after
312 1 TMR3 = TMR3RL; // ~25ms (for SMBus low timeout detect):
313 1 // 1/.025 = 40
314 1
315 1 EIE1 |= 0x80; // Timer3 interrupt enable
316 1 TMR3CN |= 0x04; // Start Timer3
317 1 }
318
319 //-----------------------------------------------------------------------------
320 // PORT_Init
321 //-----------------------------------------------------------------------------
322 //
323 // Return Value : None
324 // Parameters : None
325 //
326 // Configure the Crossbar and GPIO ports.
327 //
328 // P0.0 digital open-drain SMBus SDA
329 // P0.1 digital open-drain SMBus SCL
330 //
331 // P1.3 digital push-pull LED
332 //
333 // all other port pins unused
334 //
335 // Note: If the SMBus is moved, the SCL and SDA sbit declarations must also
336 // be adjusted.
337 //
338 void PORT_Init (void)
339 {
340 1 P0MDOUT = 0x00; // All P0 pins open-drain output
341 1
342 1 P1MDOUT |= 0x08; // Make the LED (P1.3) a push-pull
343 1 // output
344 1
345 1 XBR0 = 0x04; // Enable SMBus pins
346 1 XBR1 = 0x40; // Enable crossbar and weak pull-ups
347 1
348 1 P0 = 0xFF;
349 1 }
350
351 //-----------------------------------------------------------------------------
352 // Interrupt Service Routines
353 //-----------------------------------------------------------------------------
354
355 //-----------------------------------------------------------------------------
356 // SMBus Interrupt Service Routine (ISR)
357 //-----------------------------------------------------------------------------
358 //
359 // SMBus ISR state machine
360 // - Master only implementation - no slave or arbitration states defined
361 // - All incoming data is written to global variable <SMB_DATA_IN>
362 // - All outgoing data is read from global variable <SMB_DATA_OUT>
363 //
364 void SMBus_ISR (void) interrupt 7
365 {
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 7
366 1 bit FAIL = 0; // Used by the ISR to flag failed
367 1 // transfers
368 1 static bit ADDR_SEND = 0; // Used by the ISR to flag byte
369 1 // transmissions as slave addresses
370 1
371 1 if (ARBLOST == 0) // Check for errors
372 1 {
373 2 // Normal operation
374 2 switch (SMB0CN & 0xF0) // Status vector
375 2 {
376 3 // Master Transmitter/Receiver: START condition transmitted.
377 3 case SMB_MTSTA:
378 3 SMB0DAT = TARGET; // Load address of the target slave
379 3 SMB0DAT &= 0xFE; // Clear the LSB of the address for the
380 3 // R/W bit
381 3 SMB0DAT |= SMB_RW; // Load R/W bit
382 3 STA = 0; // Manually clear START bit
383 3 ADDR_SEND = 1;
384 3 break;
385 3
386 3 // Master Transmitter: Data byte transmitted
387 3 case SMB_MTDB:
388 3 if (ACK) // Slave ACK?
389 3 {
390 4 if (ADDR_SEND) // If the previous byte was a slave
391 4 { // address,
392 5 ADDR_SEND = 0; // Next byte is not a slave address
393 5 if (SMB_RW == WRITE) // If this transfer is a WRITE,
394 5 {
395 6 // send data byte
396 6 SMB0DAT = SMB_DATA_OUT;
397 6 }
398 5 else {} // If this transfer is a READ,
399 5 // proceed with transfer without
400 5 // writing to SMB0DAT (switch
401 5 // to receive mode)
402 5 }
403 4 else // If previous byte was not a slave
404 4 { // address,
405 5 STO = 1; // Set STO to terminate transfer
406 5 SMB_BUSY = 0; // And free SMBus interface
407 5 }
408 4 }
409 3 else // If slave NACK,
410 3 {
411 4 STO = 1; // Send STOP condition, followed
412 4 STA = 1; // By a START
413 4 NUM_ERRORS++; // Indicate error
414 4 }
415 3 break;
416 3
417 3 // Master Receiver: byte received
418 3 case SMB_MRDB:
419 3 SMB_DATA_IN = SMB0DAT; // Store received byte
420 3 SMB_BUSY = 0; // Free SMBus interface
421 3 ACK = 0; // Send NACK to indicate last byte
422 3 // of this transfer
423 3
424 3 STO = 1; // Send STOP to terminate transfer
425 3 break;
426 3
427 3 default:
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 8
428 3 FAIL = 1; // Indicate failed transfer
429 3 // and handle at end of ISR
430 3 break;
431 3
432 3 } // end switch
433 2 }
434 1 else
435 1 {
436 2 // ARBLOST = 1, error occurred... abort transmission
437 2 FAIL = 1;
438 2 } // end ARBLOST if
439 1
440 1 if (FAIL) // If the transfer failed,
441 1 {
442 2 SMB0CF &= ~0x80; // Reset communication
443 2 SMB0CF |= 0x80;
444 2 STA = 0;
445 2 STO = 0;
446 2 ACK = 0;
447 2
448 2 SMB_BUSY = 0; // Free SMBus
449 2
450 2 FAIL = 0;
451 2 LED = 0;
452 2
453 2 NUM_ERRORS++; // Indicate an error occurred
454 2 }
455 1
456 1 SI = 0; // Clear interrupt flag
457 1 }
458
459 //-----------------------------------------------------------------------------
460 // Timer3 Interrupt Service Routine (ISR)
461 //-----------------------------------------------------------------------------
462 //
463 // A Timer3 interrupt indicates an SMBus SCL low timeout.
464 // The SMBus is disabled and re-enabled here
465 //
466 void Timer3_ISR (void) interrupt 14
467 {
468 1 SMB0CF &= ~0x80; // Disable SMBus
469 1 SMB0CF |= 0x80; // Re-enable SMBus
470 1 TMR3CN &= ~0x80; // Clear Timer3 interrupt-pending flag
471 1 STA = 0;
472 1 SMB_BUSY = 0; // Free SMBus
473 1 }
474
475 //-----------------------------------------------------------------------------
476 // Support Functions
477 //-----------------------------------------------------------------------------
478
479 //-----------------------------------------------------------------------------
480 // SMB_Write
481 //-----------------------------------------------------------------------------
482 //
483 // Return Value : None
484 // Parameters : None
485 //
486 // Writes a single byte to the slave with address specified by the <TARGET>
487 // variable.
488 // Calling sequence:
489 // 1) Write target slave address to the <TARGET> variable
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 9
490 // 2) Write outgoing data to the <SMB_DATA_OUT> variable
491 // 3) Call SMB_Write()
492 //
493 void SMB_Write (void)
494 {
495 1 while (SMB_BUSY); // Wait for SMBus to be free.
496 1 SMB_BUSY = 1; // Claim SMBus (set to busy)
497 1 SMB_RW = 0; // Mark this transfer as a WRITE
498 1 STA = 1; // Start transfer
499 1 }
500
501 //-----------------------------------------------------------------------------
502 // SMB_Read
503 //-----------------------------------------------------------------------------
504 //
505 // Return Value : None
506 // Parameters : None
507 //
508 // Reads a single byte from the slave with address specified by the <TARGET>
509 // variable.
510 // Calling sequence:
511 // 1) Write target slave address to the <TARGET> variable
512 // 2) Call SMB_Write()
513 // 3) Read input data from <SMB_DATA_IN> variable
514 //
515 void SMB_Read (void)
516 {
517 1 while (SMB_BUSY); // Wait for bus to be free.
518 1 SMB_BUSY = 1; // Claim SMBus (set to busy)
519 1 SMB_RW = 1; // Mark this transfer as a READ
520 1
521 1 STA = 1; // Start transfer
522 1
523 1 while (SMB_BUSY); // Wait for transfer to complete
524 1 }
525
526 //-----------------------------------------------------------------------------
527 // T0_Wait_ms
528 //-----------------------------------------------------------------------------
529 //
530 // Return Value : None
531 // Parameters :
532 // 1) unsigned char ms - number of milliseconds to wait
533 // range is full range of character: 0 to 255
534 //
535 // Configure Timer0 to wait for <ms> milliseconds using SYSCLK as its time
536 // base.
537 //
538 void T0_Wait_ms (unsigned char ms)
539 {
540 1 TCON &= ~0x30; // Stop Timer0; Clear TF0
541 1 TMOD &= ~0x0f; // 16-bit free run mode
542 1 TMOD |= 0x01;
543 1
544 1 CKCON |= 0x04; // Timer0 counts SYSCLKs
545 1
546 1 while (ms) {
547 2 TR0 = 0; // Stop Timer0
548 2 TH0 = -(SYSCLK/1000 >> 8); // Overflow in 1ms
549 2 TL0 = -(SYSCLK/1000);
550 2 TF0 = 0; // Clear overflow indicator
551 2 TR0 = 1; // Start Timer0
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 10
552 2 while (!TF0); // Wait for overflow
553 2 ms--; // Update ms counter
554 2 }
555 1
556 1 TR0 = 0; // Stop Timer0
557 1 }
558
559 //-----------------------------------------------------------------------------
560 // End Of File
561 //-----------------------------------------------------------------------------
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 439 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 7 1
IDATA SIZE = ---- ----
BIT SIZE = 3 1
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -