5986|3

121

帖子

2642

TA的资源

纯净的硅(中级)

楼主
 

iar avr twi 多从机源码 [复制链接]

来源于AVR网站







  1. /*****************************************************************************
  2. *
  3. * Atmel Corporation
  4. *
  5. * File         : main.c
  6. * Compiler       : IAR EWAAVR 2.28a/3.10c
  7. * Revision       : $Revision: 2516 $
  8. * Date         : $Date: 2007-09-27 10:41:15 +0200 (to, 27 sep 2007) $
  9. * Updated by     : $Author: mlarsson $
  10. *
  11. * Support mail     : avr@atmel.com
  12. *
  13. * Supported devices : All devices with a TWI module the has a slave address mask
  14. *               register. The example is written for the ATmega48.
  15. *
  16. * AppNote       : AVR311 - TWI Slave Implementation
  17. *
  18. * Description     : Example of how to use the driver for TWI slave
  19. *               communication. This version utilises the address mask register
  20. *               to enable response on several TWI slave addresses.
  21. *
  22. ****************************************************************************/
  23. /*! \page MISRA
  24. *
  25. * General disabling of MISRA rules:
  26. * * (MISRA C rule 1) compiler is configured to allow extensions
  27. * * (MISRA C rule 111) bit fields shall only be defined to be of type unsigned int or signed int
  28. * * (MISRA C rule 37) bitwise operations shall not be performed on signed integer types
  29. * As it does not work well with 8bit architecture and/or IAR

  30. * Other disabled MISRA rules
  31. * * (MISRA C rule 109) use of union - overlapping storage shall not be used
  32. * * (MISRA C rule 61) every non-empty case clause in a switch statement shall be terminated with a break statement
  33. */

  34. #include
  35. #include
  36. #include "TWI_Slave.h"

  37. // Sample TWI transmission commands
  38. #define TWI_CMD_MASTER_WRITE 0x10
  39. #define TWI_CMD_MASTER_READ 0x20

  40. // The AVR can be waken up by a TWI address match from all sleep modes,
  41. // But it only wakes up from other TWI interrupts when in idle mode.
  42. // If POWER_MANAGEMENT_ENABLED is defined the device will enter power-down
  43. // mode when waiting for a new command and enter idle mode when waiting
  44. // for TWI receives and transmits to finish.
  45. #define POWER_MANAGEMENT_ENABLED

  46. // When there has been an error, this function is run and takes care of it
  47. unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg );


  48. void main( void )
  49. {
  50. unsigned char messageBuf[TWI_BUFFER_SIZE];
  51. unsigned char TWI_slaveAddress, TWI_slaveAddress2, TWI_slaveAddressMask;

  52. // LED feedback port - connect port B to the STK500 LEDS
  53. DDRB = 0xFF; // Set to ouput
  54. PORTB = 0x55; // Startup pattern

  55. // Own TWI slave address
  56. TWI_slaveAddress   = (0x10<
  57. TWI_slaveAddress2   = (0x11<
  58. TWI_slaveAddressMask = TWI_slaveAddress ^ TWI_slaveAddress2; // XOR the addresses to get the address mask.

  59. // Initialise TWI module for slave operation. Include address and/or enable General Call.
  60. TWI_Slave_Initialise( (unsigned char)(TWI_slaveAddress | (TRUE<
  61.               
  62. __enable_interrupt();

  63. // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  64. TWI_Start_Transceiver();

  65. // This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI
  66. // pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a
  67. // general call, or an address call. If it is an address call, then the first byte is considered a command byte and
  68. // it then responds differently according to the commands.

  69. // This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
  70. for(;;)
  71. {
  72.   #ifdef POWER_MANAGEMENT_ENABLED
  73.     // Sleep while waiting for TWI transceiver to complete or waiting for new commands.
  74.     // If we have data in the buffer, we can't enter sleep because we have to take care
  75.     // of it first.
  76.     // If the transceiver is busy, we enter idle mode because it will wake up by all TWI
  77.     // interrupts.
  78.     // If the transceiver not is busy, we can enter power-down mode because next receive
  79.     // should be a TWI address match and it wakes the device up from all sleep modes.
  80.     if( ! TWI_statusReg.RxDataInBuf ) {
  81.     if(TWI_Transceiver_Busy()) {
  82.       MCUCR = (1<
  83.     } else {
  84.       MCUCR = (1<
  85.     }
  86.     __sleep();
  87.     } else {
  88.     __no_operation(); // There is data in the buffer, code below takes care of it.
  89.     }
  90.   #else // No power management
  91.     // Here you can add your own code that should be run while waiting for the TWI to finish   
  92.     __no_operation(); // Put own code here.
  93.   #endif
  94.    
  95.   
  96.   // Check if the TWI Transceiver has completed an operation.
  97.   if ( ! TWI_Transceiver_Busy() )                     
  98.   {
  99.     // Check if the last operation was successful
  100.     if ( TWI_statusReg.lastTransOK )
  101.     {
  102.     // Check if the last operation was a reception
  103.     if ( TWI_statusReg.RxDataInBuf )
  104.     {
  105.       TWI_Get_Data_From_Transceiver(messageBuf, 2);      
  106.       // Check if the last operation was a reception as General Call     
  107.       if ( TWI_statusReg.genAddressCall )
  108.       {
  109.         // Put data received out to PORTB as an example.     
  110.         PORTB = messageBuf[0];
  111.       }           
  112.       else // Ends up here if the last operation was a reception as Slave Address Match   
  113.       {
  114.         // Example of how to interpret a command and respond.
  115.         
  116.         // TWI_CMD_MASTER_WRITE stores the data to PORTB
  117.         if (messageBuf[0] == TWI_CMD_MASTER_WRITE)
  118.         {
  119.         PORTB = messageBuf[1];                  
  120.         }
  121.         // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
  122.         if (messageBuf[0] == TWI_CMD_MASTER_READ)
  123.         {
  124.         messageBuf[0] = PINB;
  125.         TWI_Start_Transceiver_With_Data( messageBuf, 1 );
  126.         }
  127.       }
  128.     }           
  129.     else // Ends up here if the last operation was a transmission
  130.     {
  131.         __no_operation(); // Put own code here.
  132.     }
  133.     // Check if the TWI Transceiver has already been started.
  134.     // If not then restart it to prepare it for new receptions.         
  135.     if ( ! TWI_Transceiver_Busy() )
  136.     {
  137.       TWI_Start_Transceiver();
  138.     }
  139.     }
  140.     else // Ends up here if the last operation completed unsuccessfully
  141.     {
  142.     TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() );
  143.     }
  144.   }
  145. }
  146. }


  147. unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg )
  148. {
  149.             // A failure has occurred, use TWIerrorMsg to determine the nature of the failure
  150.             // and take appropriate actions.
  151.             // Se header file for a list of possible failures messages.

  152.             // This very simple example puts the error code on PORTB and restarts the transceiver with
  153.             // all the same data in the transmission buffers.
  154. PORTB = TWIerrorMsg;
  155. TWI_Start_Transceiver();
  156.             
  157. return TWIerrorMsg;
  158. }

  159. /*
  160. // A simplified example.
  161. // This will store data received on PORTB, and increment it before sending it back.

  162. TWI_Start_Transceiver( );   
  163.       
  164. for(;;)
  165. {
  166.   if ( ! TWI_Transceiver_Busy() )                     
  167.   {
  168.     if ( TWI_statusReg.RxDataInBuf )
  169.     {
  170.     TWI_Get_Data_From_Transceiver(&temp, 1);
  171.     PORTB = temp;
  172.     }
  173.     temp = PORTB + 1;
  174.     TWI_Start_Transceiver_With_Data(&temp, 1);
  175.   }
  176.   __no_operation();   // Do something else while waiting
  177. }
  178. }

  179. */

复制代码

最新回复

好资料啊  收下了 歇息  详情 回复 发表于 2010-12-22 20:11
点赞 关注
 

回复
举报

121

帖子

2642

TA的资源

纯净的硅(中级)

沙发
 
  1. #include "ioavr.h"
  2. #include "inavr.h"
  3. #include "TWI_slave.h"

  4. static unsigned char TWI_buf[TWI_BUFFER_SIZE]; // Transceiver buffer. Set the size in the header file
  5. static unsigned char TWI_msgSize = 0; // Number of bytes to be transmitted.
  6. static unsigned char TWI_state = TWI_NO_STATE; // State byte. Default set to TWI_NO_STATE.

  7. // This is true when the TWI is in the middle of a transfer
  8. // and set to false when all bytes have been transmitted/received
  9. // Also used to determine how deep we can sleep.
  10. static unsigned char TWI_busy = 0;

  11. union TWI_statusReg_t TWI_statusReg = {0}; // TWI_statusReg is defined in TWI_Slave.h

  12. /****************************************************************************
  13. Call this function to set up the TWI slave to its initial standby state.
  14. Remember to enable interrupts from the main application after initializing the TWI.
  15. Pass both the slave address and the requrements for triggering on a general call in the
  16. same byte. Use e.g. this notation when calling this function:
  17. TWI_Slave_Initialise( (TWI_slaveAddress<
  18. The TWI module is configured to NACK on any requests. Use a TWI_Start_Transceiver function to
  19. start the TWI.
  20. ****************************************************************************/
  21. void TWI_Slave_Initialise( unsigned char TWI_ownAddress, unsigned char TWI_ownAddressMask )
  22. {
  23. TWAR = TWI_ownAddress; // Set own TWI slave address. Accept TWI General Calls.
  24. TWAMR= TWI_ownAddressMask; // Set own TWI slave address mask to enable respons on several addresses.
  25. TWCR = (1<
  26. (0<
  27. (0<
  28. (0<
  29. TWI_busy = 0;
  30. }

  31. /****************************************************************************
  32. Call this function to test if the TWI_ISR is busy transmitting.
  33. ****************************************************************************/
  34. unsigned char TWI_Transceiver_Busy( void )
  35. {
  36. return TWI_busy;
  37. }

  38. /****************************************************************************
  39. Call this function to fetch the state information of the previous operation. The function will hold execution (loop)
  40. until the TWI_ISR has completed with the previous operation. If there was an error, then the function
  41. will return the TWI State code.
  42. ****************************************************************************/
  43. unsigned char TWI_Get_State_Info( void )
  44. {
  45. while ( TWI_Transceiver_Busy() ) {} // Wait until TWI has completed the transmission.
  46. return ( TWI_state ); // Return error state.
  47. }

  48. /****************************************************************************
  49. Call this function to send a prepared message, or start the Transceiver for reception. Include
  50. a pointer to the data to be sent if a SLA+W is received. The data will be copied to the TWI buffer.
  51. Also include how many bytes that should be sent. Note that unlike the similar Master function, the
  52. Address byte is not included in the message buffers.
  53. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation,
  54. then initialize the next operation and return.
  55. ****************************************************************************/
  56. void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize )
  57. {
  58. unsigned char temp;

  59. while ( TWI_Transceiver_Busy() ) {} // Wait until TWI is ready for next transmission.

  60. TWI_msgSize = msgSize; // Number of data to transmit.
  61. for ( temp = 0; temp < msgSize; temp++ ) // Copy data that may be transmitted if the TWI Master requests data.
  62. {
  63. TWI_buf[ temp ] = msg[ temp ];
  64. }
  65. TWI_statusReg.all = 0;
  66. TWI_state = TWI_NO_STATE ;
  67. TWCR = (1<
  68. (1<
  69. (1<
  70. (0<
  71. TWI_busy = 1;
  72. }

  73. /****************************************************************************
  74. Call this function to start the Transceiver without specifing new transmission data. Useful for restarting
  75. a transmission, or just starting the transceiver for reception. The driver will reuse the data previously put
  76. in the transceiver buffers. The function will hold execution (loop) until the TWI_ISR has completed with the
  77. previous operation, then initialize the next operation and return.
  78. ****************************************************************************/
  79. void TWI_Start_Transceiver( void )
  80. {
  81. while ( TWI_Transceiver_Busy() ) {} // Wait until TWI is ready for next transmission.
  82. TWI_statusReg.all = 0;
  83. TWI_state = TWI_NO_STATE ;
  84. TWCR = (1<
  85. (1<
  86. (1<
  87. (0<
  88. TWI_busy = 0;
  89. }
  90. /****************************************************************************
  91. Call this function to read out the received data from the TWI transceiver buffer. I.e. first call
  92. TWI_Start_Transceiver to get the TWI Transceiver to fetch data. Then Run this function to collect the
  93. data when they have arrived. Include a pointer to where to place the data and the number of bytes
  94. to fetch in the function call. The function will hold execution (loop) until the TWI_ISR has completed
  95. with the previous operation, before reading out the data and returning.
  96. If there was an error in the previous transmission the function will return the TWI State code.
  97. ****************************************************************************/
复制代码
 
 
 

回复

121

帖子

2642

TA的资源

纯净的硅(中级)

板凳
 
  1. unsigned char TWI_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize )
  2. {
  3. unsigned char i;

  4. while ( TWI_Transceiver_Busy() ) {} // Wait until TWI is ready for next transmission.

  5. if( TWI_statusReg.lastTransOK ) // Last transmission completed successfully.
  6. {
  7. for ( i=0; i
  8. {
  9. msg[ i ] = TWI_buf[ i ];
  10. }
  11. TWI_statusReg.RxDataInBuf = FALSE; // Slave Receive data has been read from buffer.
  12. }
  13. return( TWI_statusReg.lastTransOK );
  14. }


  15. // ********** Interrupt Handlers ********** //
  16. /****************************************************************************
  17. This function is the Interrupt Service Routine (ISR), and called when the TWI interrupt is triggered;
  18. that is whenever a TWI event has occurred. This function should not be called directly from the main
  19. application.
  20. ****************************************************************************/
  21. #pragma vector=TWI_vect
  22. __interrupt void TWI_ISR( void )
  23. {
  24. static unsigned char TWI_bufPtr;

  25. switch (TWSR)
  26. {
  27. case TWI_STX_ADR_ACK: // Own SLA+R has been received; ACK has been returned
  28. // case TWI_STX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
  29. TWI_bufPtr = 0; // Set buffer pointer to first data location
  30. case TWI_STX_DATA_ACK: // Data byte in TWDR has been transmitted; ACK has been received
  31. TWDR = TWI_buf[TWI_bufPtr++];
  32. TWCR = (1<
  33. (1<
  34. (1<
  35. (0<
  36. TWI_busy = 1;
  37. break;
  38. case TWI_STX_DATA_NACK: // Data byte in TWDR has been transmitted; NACK has been received.
  39. // I.e. this could be the end of the transmission.
  40. if (TWI_bufPtr == TWI_msgSize) // Have we transceived all expected data?
  41. {
  42. TWI_statusReg.lastTransOK = TRUE; // Set status bits to completed successfully.
  43. }
  44. else // Master has sent a NACK before all data where sent.
  45. {
  46. TWI_state = TWSR; // Store TWI State as errormessage.
  47. }

  48. TWCR = (1<
  49. (1<
  50. (1<
  51. (0<

  52. TWI_busy = 0; // Transmit is finished, we are not busy anymore
  53. break;
  54. case TWI_SRX_GEN_ACK: // General call address has been received; ACK has been returned
  55. // case TWI_SRX_GEN_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
  56. TWI_statusReg.genAddressCall = TRUE;
  57. case TWI_SRX_ADR_ACK: // Own SLA+W has been received ACK has been returned
  58. // case TWI_SRX_ADR_ACK_M_ARB_LOST: // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
  59. // Dont need to clear TWI_S_statusRegister.generalAddressCall due to that it is the default state.
  60. TWI_statusReg.RxDataInBuf = TRUE;
  61. TWI_bufPtr = 0; // Set buffer pointer to first data location

  62. // Reset the TWI Interupt to wait for a new event.
  63. TWCR = (1<
  64. (1<
  65. (1<
  66. (0<
  67. TWI_busy = 1;

  68. break;
  69. case TWI_SRX_ADR_DATA_ACK: // Previously addressed with own SLA+W; data has been received; ACK has been returned
  70. case TWI_SRX_GEN_DATA_ACK: // Previously addressed with general call; data has been received; ACK has been returned
  71. TWI_buf[TWI_bufPtr++] = TWDR;
  72. TWI_statusReg.lastTransOK = TRUE; // Set flag transmission successfull.
  73. // Reset the TWI Interupt to wait for a new event.
  74. TWCR = (1<
  75. (1<
  76. (1<
  77. (0<
  78. TWI_busy = 1;
  79. break;
  80. case TWI_SRX_STOP_RESTART: // A STOP condition or repeated START condition has been received while still addressed as Slave
  81. // Enter not addressed mode and listen to address match
  82. TWCR = (1<
  83. (1<
  84. (1<
  85. (0<

  86. TWI_busy = 0; // We are waiting for a new address match, so we are not busy

  87. break;
  88. case TWI_SRX_ADR_DATA_NACK: // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
  89. case TWI_SRX_GEN_DATA_NACK: // Previously addressed with general call; data has been received; NOT ACK has been returned
  90. case TWI_STX_DATA_ACK_LAST_BYTE: // Last data byte in TWDR has been transmitted (TWEA = ??; ACK has been received
  91. // case TWI_NO_STATE // No relevant state information available; TWINT = ??
  92. case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition
  93. TWI_state = TWSR; //Store TWI State as errormessage, operation also clears noErrors bit
  94. TWCR = (1<
  95. break;
  96. default:
  97. TWI_state = TWSR; // Store TWI State as errormessage, operation also clears the Success bit.
  98. TWCR = (1<
  99. (1<
  100. (1<
  101. (0<

  102. TWI_busy = 0; // Unknown status, so we wait for a new address match that might be something we can handle
  103. }
  104. }
复制代码
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 
好资料啊  收下了 歇息
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表