Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

Типа пример - ТВИ мастер

Отправлено zadolbala_politika 27 августа 2008 г. 14:36
В ответ на: Непонятки с TWI в Атмегах (+) отправлено urqa 27 августа 2008 г. 07:43


#include <ioavr.h>


#define TWI_TWBR 10

#define TWI_READ 1
#define TWI_WRITE 0

// ---------- General TWI Master status codes --------------
#define TWI_START 0x08
// START has been transmitted
#define TWI_REP_START 0x10
// Repeated START has been transmitted
#define TWI_ARB_LOST 0x38
// Arbitration lost

// ------------ TWI Master Transmitter status codes ---------
#define TWI_MTX_ADR_ACK 0x18
// SLA+W has been tramsmitted and ACK received
#define TWI_MTX_ADR_NACK 0x20
// SLA+W has been tramsmitted and NACK received
#define TWI_MTX_DATA_ACK 0x28
// Data byte has been tramsmitted and ACK received
#define TWI_MTX_DATA_NACK 0x30
// Data byte has been tramsmitted and NACK received

// -------------- TWI Master Receiver status codes -----------
#define TWI_MRX_ADR_ACK 0x40
// SLA+R has been tramsmitted and ACK received
#define TWI_MRX_ADR_NACK 0x48
// SLA+R has been tramsmitted and NACK received
#define TWI_MRX_DATA_ACK 0x50
// Data byte has been received and ACK tramsmitted
#define TWI_MRX_DATA_NACK 0x58
// Data byte has been received and NACK tramsmitted

// --------------- TWI Slave Transmitter status codes ---------
#define TWI_STX_ADR_ACK 0xA8
// Own SLA+R has been received; ACK has been returned
#define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0
// Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
#define TWI_STX_DATA_ACK 0xB8
// Data byte in TWDR has been transmitted; ACK has been received
#define TWI_STX_DATA_NACK 0xC0
// Data byte in TWDR has been transmitted; NOT ACK has been received
#define TWI_STX_DATA_ACK_LAST_BYTE 0xC8
// Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received

// ---------------- TWI Slave Receiver status codes ---------------
#define TWI_SRX_ADR_ACK 0x60
// Own SLA+W has been received ACK has been returned
#define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68
// Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
#define TWI_SRX_GEN_ACK 0x70
// General call address has been received; ACK has been returned
#define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78
// Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
#define TWI_SRX_ADR_DATA_ACK 0x80
// Previously addressed with own SLA+W; data has been received; ACK has been returned
#define TWI_SRX_ADR_DATA_NACK 0x88
// Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
#define TWI_SRX_GEN_DATA_ACK 0x90
// Previously addressed with general call; data has been received; ACK has been returned
#define TWI_SRX_GEN_DATA_NACK 0x98
// Previously addressed with general call; data has been received; NOT ACK has been returned
#define TWI_SRX_STOP_RESTART 0xA0
// A STOP condition or repeated START condition has been received while still addressed as Slave

// ------------------ TWI Miscellaneous status codes -------------
#define TWI_NO_STATE 0xF8
// No relevant state information available; TWINT = “0”
#define TWI_BUS_ERROR 0x00
// Bus error due to an illegal START or STOP condition

// values of TWI control register
#define TWI_CTRL_ACK ((1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA))
#define TWI_CTRL_NACK ((1<<TWEN)|(1<<TWIE)|(1<<TWINT))
#define TWI_CTRL_START ((1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA))
#define TWI_CTRL_STOP ((1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTO))

typedef enum {
IDLE = 0,
BUSY,
SUCCESS,
ARB_LOST,
ADDR_NACK,
DATA_NACK,
BUS_ERROR,
UNEXPECTED
} twi_state_t;

typedef struct {
volatile twi_state_t state;
unsigned char addr;
unsigned char nbytes_rd;
unsigned char nbytes_wr;
unsigned char *buf; // holds bytes to write and the bytes read from slave
} twi_message_t;


static twi_message_t *pm;

void twi_init( void )
{
// TWAR = addr;
TWBR = TWI_TWBR;
TWDR = 0xFF; // default content = SDA released
TWCR = TWI_CTRL_NACK;
}

void twi_start( twi_message_t *m )
{
if ( m->nbytes_rd == 0 && m->nbytes_wr == 0 )
return; // nothing to do
pm = m;
pm->state = BUSY;
TWCR = TWI_CTRL_START;
}

#pragma vector=TWI_vect
__interrupt void TWI_ISR(void)
{
static unsigned char wr_idx;
static unsigned char rd_idx;

switch ( TWSR )
{
case TWI_START: // START transmitted
wr_idx = rd_idx = 0;
if ( pm->nbytes_wr )
TWDR = ( pm->addr << 1 ) | TWI_WRITE;
else if ( pm->nbytes_rd )
TWDR = ( pm->addr << 1 ) | TWI_READ;
else
; // should not be here
TWCR = TWI_CTRL_NACK;
break;
case TWI_REP_START: // Repeated START transmitted
if ( pm->nbytes_rd )
TWDR = ( pm->addr << 1 ) | TWI_READ;
else
; // should not be here
TWCR = TWI_CTRL_NACK;
break;
case TWI_MTX_ADR_ACK: // SLA+W tramsmitted, ACK received
case TWI_MTX_DATA_ACK: // Data tramsmitted, ACK received
if ( wr_idx < pm->nbytes_wr )
TWDR = pm->buf[wr_idx++];
else if ( pm->nbytes_rd )
TWCR = TWI_CTRL_START; // Generate repeated START
else
{
pm->state = SUCCESS;
TWCR = TWI_CTRL_STOP; // All done
}
break;

////////////////////////////////// receiver states
case TWI_MRX_ADR_ACK: // SLA+R tramsmitted, ACK received
if ( pm->nbytes_rd == 1 ) // first byte is also the last
TWCR = TWI_CTRL_NACK; // don't acknowledge
else
TWCR = TWI_CTRL_ACK; // acknowledge all bytes but the last
break;
case TWI_MRX_DATA_ACK: // Data received, ACK tramsmitted
pm->buf[rd_idx++] = TWDR;
if ( rd_idx == pm->nbytes_rd - 1 ) // last byte
TWCR = TWI_CTRL_NACK; // don't acknowledge
else
TWCR = TWI_CTRL_ACK; // acknowledge all bytes but the last
break;
case TWI_MRX_DATA_NACK: // Last data received, NACK tramsmitted
pm->buf[rd_idx++] = TWDR;
// if ( rd_idx != pm->nbytes_rd )
// ; // should not be here
pm->state = SUCCESS;
TWCR = TWI_CTRL_STOP; // All done
break;

////////////////////////////////// NACKs

case TWI_MTX_ADR_NACK: // SLA+W tramsmitted, NACK received
case TWI_MRX_ADR_NACK: // SLA+R tramsmitted, NACK received
pm->state = ADDR_NACK;
pm->nbytes_wr = wr_idx;
pm->nbytes_rd = rd_idx;
TWCR = TWI_CTRL_STOP;
break;
case TWI_MTX_DATA_NACK: // Data byte has been tramsmitted and NACK received
pm->state = DATA_NACK;
pm->nbytes_wr = wr_idx;
pm->nbytes_rd = rd_idx;
TWCR = TWI_CTRL_STOP;
break;

////////////////////////////////// unexpected states
case TWI_ARB_LOST: // Arbitration lost
pm->state = ARB_LOST;
break;
case TWI_BUS_ERROR: // Bus error due to an illegal START or STOP condition
pm->state = BUS_ERROR;
pm->nbytes_wr = wr_idx;
pm->nbytes_rd = rd_idx;
TWCR = TWI_CTRL_STOP;
break;
default:
pm->state = UNEXPECTED;
break;
}
}



Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
сколько миллиампер в одном ампере ?:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru