⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twi.c

📁 AVR的I2C驱动程序
💻 C
字号:
#include "twi.h"#include <avr/io.h>#include <avr/interrupt.h>volatile struct TWI_master_data *TWI_task_first = 0;volatile struct TWI_master_data *TWI_task_last = 0;volatile struct TWI_master_data *TWI_task_current = 0;volatile struct TWI_slave_data *TWI_slave_send = 0;volatile struct TWI_slave_data *TWI_slave_receive = 0;void TWI_initialize(){  TWDR = 0xFF;  TWSR = 0;  TWCR = (1 << TWEN) |  (1 << TWIE) | (0 << TWINT) |    (0 << TWEA) | (0 << TWSTA) | (0 << TWSTO) | (0 << TWWC);  sei ();}void TWI_master_initialize (unsigned scl_frequency){  TWBR = TWI_clock_frequency / (2 * scl_frequency) - 8;} voidTWI_slave_initialize (unsigned char own_address,		      struct TWI_slave_data *send,		      struct TWI_slave_data *receive){  TWAR = own_address;  TWI_slave_send = send;  TWI_slave_receive = receive;  TWCR |= (1 << TWEA) | (0 << TWIE);} void TWI_master (struct TWI_master_data *data){  if (TWI_task_first == 0)  {    TWI_task_first = TWI_task_last = TWI_task_current =      data;    TWCR |= (1 << TWSTA) | (1 << TWINT);  }  else  {    TWI_task_last->next = data;    TWI_task_last = data;  }}/* General TWI Master staus codes */#define TWI_START                  0x08#define TWI_REP_START              0x10#define TWI_ARB_LOST               0x38/* TWI Master Transmitter staus codes */#define TWI_MTX_ADR_ACK            0x18#define TWI_MTX_ADR_NACK           0x20#define TWI_MTX_DATA_ACK           0x28#define TWI_MTX_DATA_NACK          0x30/* TWI Master Receiver staus codes */#define TWI_MRX_ADR_ACK            0x40#define TWI_MRX_ADR_NACK           0x48#define TWI_MRX_DATA_ACK           0x50#define TWI_MRX_DATA_NACK          0x58/* TWI Slave Transmitter staus codes */#define TWI_STX_ADR_ACK            0xA8#define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0#define TWI_STX_DATA_ACK           0xB8#define TWI_STX_DATA_NACK          0xC0#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8/* TWI Slave Receiver staus codes */#define TWI_SRX_ADR_ACK            0x60#define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68#define TWI_SRX_GEN_ACK            0x70#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78#define TWI_SRX_ADR_DATA_ACK       0x80#define TWI_SRX_ADR_DATA_NACK      0x88#define TWI_SRX_GEN_DATA_ACK       0x90#define TWI_SRX_GEN_DATA_NACK      0x98#define TWI_SRX_STOP_RESTART       0xA0/* TWI Miscellaneous status codes */#define TWI_NO_STATE               0xF8#define TWI_BUS_ERROR              0x00ISR (TWI_vect){  static unsigned char string_index;  switch (TWSR)  {  case TWI_START:  case TWI_REP_START:    string_index = 0;  case TWI_MTX_ADR_ACK:  case TWI_MTX_DATA_ACK:    if (string_index < TWI_task_current->length)    {      TWDR = TWI_task_current->string[string_index++];      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(0 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    }    else    {      *TWI_task_current->flag = 0;      if (TWI_task_current != TWI_task_last)      {	TWI_task_current = TWI_task_current->next;	TWCR = (1 << TWEN) |	  (1 << TWIE) | (1 << TWINT) |	  (0 << TWEA) | (1 << TWSTA) | (0 << TWSTO) |	  (0 << TWWC);      }      else      {	TWI_task_first = TWI_task_last = TWI_task_current =	  0;	TWCR =	  (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 <<						      TWEA)	  | (0 << TWSTA) | (1 << TWSTO) | (0 << TWWC);      }    }    break;  case TWI_MRX_DATA_ACK:    TWI_task_current->string[string_index++] = TWDR;  case TWI_MRX_ADR_ACK:    if (string_index < (TWI_task_current->length - 1))    {      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    }    else    {      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(0 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    }    break;  case TWI_MRX_DATA_NACK:    TWI_task_current->string[string_index] = TWDR;    *TWI_task_current->flag = 0;    if (TWI_task_current != TWI_task_last)    {      TWI_task_current = TWI_task_current->next;      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(0 << TWEA) | (1 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    }    else    {      TWI_task_first = TWI_task_last = TWI_task_current = 0;      TWCR =	(1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 <<						    TWEA)	| (0 << TWSTA) | (1 << TWSTO) | (0 << TWWC);    }    break;  case TWI_ARB_LOST:    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (1 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_MTX_ADR_NACK:  case TWI_MRX_ADR_NACK:  case TWI_MTX_DATA_NACK:    TWI_task_first = TWI_task_current;    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (1 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_STX_ADR_ACK:    string_index = 0;    *TWI_slave_send->flag = 0xFF;  case TWI_STX_DATA_ACK:    if (string_index < TWI_slave_send->length)      TWDR = TWI_slave_send->string[string_index++];    else      TWDR = 0;    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_STX_DATA_NACK:    *TWI_slave_send->flag = 0;    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_SRX_GEN_ACK:  case TWI_SRX_ADR_ACK:    string_index = 0;    *TWI_slave_receive->flag = 0xFF;    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_SRX_ADR_DATA_ACK:  case TWI_SRX_GEN_DATA_ACK:    if (string_index < TWI_slave_receive->length)      TWI_slave_receive->string[string_index++] = TWDR;    if (string_index == TWI_slave_receive->length)      *TWI_slave_receive->flag = 0;    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  case TWI_SRX_STOP_RESTART:    *TWI_slave_receive->flag = 0;    TWI_slave_receive = TWI_slave_receive->next;    if (TWI_task_current == 0)      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    else      TWCR = (1 << TWEN) |	(1 << TWIE) | (1 << TWINT) |	(1 << TWEA) | (1 << TWSTA) | (0 << TWSTO) |	(0 << TWWC);    break;  case TWI_SRX_ADR_DATA_NACK:  case TWI_SRX_GEN_DATA_NACK:  case TWI_STX_DATA_ACK_LAST_BYTE:  case TWI_BUS_ERROR:  default:    TWCR = (1 << TWEN) |      (1 << TWIE) | (1 << TWINT) |      (1 << TWEA) | (0 << TWSTA) | (0 << TWSTO) |      (0 << TWWC);    break;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -