Может поможет
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Sdl 18 июля 2003 г. 11:35
В ответ на: Помогите разобраться сTWI в ATMega8, с передачей всё ясно, а как принять байт не врублюсь, примерчик бы... отправлено Барсук 17 июля 2003 г. 17:01


// state machine
// ff - error bus
// 7f - OK

#define SLA_W 0x00
#define SLA_R 0x01
#define START_I2C ( ( 1 << TWINT) | ( 1 << TWSTA) | ( 1 << TWEN)| ( 1<< TWIE) )
#define STOP_I2C ( ( 1 << TWINT) | ( 1 << TWSTO) | ( 1 << TWEN) )
#define OUT_BYTE_I2C ( ( 1 << TWINT) | ( 1 << TWEN) | ( 1 << TWIE) )
#define IN_BYTE_I2C_ACK ( ( 1 << TWINT) | ( 1 << TWEN) | ( 1 << TWEA) | ( 1 << TWIE) )
#define IN_BYTE_I2C_NACK ( ( 1 << TWINT) | ( 1 << TWEN) | ( 1 << TWIE) )

// if rd_wr = 0 - write
void init_i2c_int( uchar rd_wr, uchar adr_chip, uchar adr_mem, uchar count_byte, uchar *buf)
{
clr_bit_reg( DDRC, PC4);
clr_bit_reg( DDRC, PC5);

clr_bit_reg( PORTC, PC4);
clr_bit_reg( PORTC, PC5);


TWAR = 0x00;
TWBR = 100; // 97 kHz
TWSR = 0x00;

adr_chip_i2c = adr_chip;
adr_mem_i2c = adr_mem;
len_i2c = count_byte;
ptr_i2c = buf;
direct_i2c_rd = rd_wr; // !0 - read
state_i2c = 1;

// START
_SEI(); // global interrupt enable
TWCR = START_I2C;
}

// EXIT 0 - OK
uchar wait_i2c(void)
{

while(1) {
if( state_i2c == 0x00 ) return( 0);
if( state_i2c == 0x7f ) return( 0x7f);
if( state_i2c == 0xFF ) return( 0xff);
} // while
}

#pragma vector= TWI_vect
__interrupt void interrupt_i2c( void)
{
uchar c;

c = TWSR;
// rs_out_232( state_i2c);
// 0 - start i2c bus call from main program (init_i2c_interrupt)
switch( state_i2c) {
case 1: // write byte adr_chip cmd SLA+W
if( !((c == 0x08) || (c == 0x10))) break; // not start
TWDR = adr_chip_i2c | SLA_W;
TWCR = OUT_BYTE_I2C;
state_i2c++;
return;
case 2: // write adr_mem
if( c != 0x18 ) break; // not write adr_chip
TWDR = adr_mem_i2c;
TWCR = OUT_BYTE_I2C;
state_i2c++;
return;
case 3: // write bytes data if write ops
if( c != 0x28 ) break; // not write adr_chip
if( direct_i2c_rd ){
// stop
TWCR = STOP_I2C;
state_i2c++;
while( ( get_bit_reg( TWCR, TWSTO))); // wait stop
TWCR = START_I2C; // start for read
return;
}
if ( !len_i2c ) {
// stop, end interrupt
TWCR = STOP_I2C;
state_i2c = 0x00; // OK
while( ( get_bit_reg( TWCR, TWSTO))); // wait stop
TWCR = (1 << TWINT); // end write
return;
}
TWDR = *ptr_i2c;
TWCR = OUT_BYTE_I2C;
len_i2c--;
ptr_i2c++;
return;
case 4:
if( !((c == 0x08) || (c == 0x10))) break;
TWDR = adr_chip_i2c | SLA_R;
TWCR = OUT_BYTE_I2C;
state_i2c++;
return;
case 5:
if( c != 0x40 ) break;
if ( !len_i2c )
{
// stop, end interrupt
TWCR = STOP_I2C;
state_i2c = 0x00; // OK
while( ( get_bit_reg( TWCR, TWSTO))); // wait stop
TWCR = (1 << TWINT); // end read
return;
}
if ( len_i2c == 1)
{
TWCR = IN_BYTE_I2C_NACK;
state_i2c+=2;
}
else
{
TWCR = IN_BYTE_I2C_ACK;
state_i2c++;
}
return;
case 6:
if( (c != 0x50) ) break;
*ptr_i2c = TWDR;
len_i2c--;
ptr_i2c++;
if ( len_i2c == 1)
{
TWCR = IN_BYTE_I2C_NACK;
state_i2c++;
}
else
{
TWCR = IN_BYTE_I2C_ACK;
}
return;
case 7:
if( (c != 0x58) ) break;
*ptr_i2c = TWDR;
TWCR = STOP_I2C;
state_i2c = 0x00;
while( ( get_bit_reg( TWCR, TWSTO))); // wait stop
TWCR = (1 << TWINT); // end read
return;

default:
TWCR = (1 << TWINT);
state_i2c = 0x7f;
return;

} //switch ( state_i2c)

TWCR = (1 << TWINT);
state_TWSR = c;
state_i2c = 0xff;
}

#pragma function=default


Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru