Исходник раба (частично/только i2c)
Непомню откуда качал пример, часть была сделана так.
Тут я просто пытаюсь поймать символ "a"/0x61 , и инвертировать состояние порта PB0
CODE
#include <avr/io.h>
#include <util/twi.h>
#include <avr/interrupt.h>
#define TWI_RX_BUFFER_SIZE 8
// receive buffer (incoming data)
static uint8_t i2crxbuffer[TWI_RX_BUFFER_SIZE];
static uint8_t i2crxindex;
uint8_t i2c_rxbuffer[TWI_RX_BUFFER_SIZE];
static void (*i2cSlaveReceive)(uint8_t receiveDataLength, uint8_t* recieveData);
void twi_init(uint8_t adress);
// I2C (TWI) interrupt service routine
SIGNAL(SIG_2WIRE_SERIAL)
{
switch (TWSR & 0xF8)
{
case TW_SR_SLA_ACK: // 0x60: own SLA+W has been received, ACK has been returned
case TW_SR_ARB_LOST_SLA_ACK: // 0x68: own SLA+W has been received, ACK has been returned
case TW_SR_GCALL_ACK: // 0x70: GCA+W has been received, ACK has been returned
case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: GCA+W has been received, ACK has been returned
i2crxindex = 0;
TWCR |= (1 << TWINT) | (1 << TWEA);
break;
case TW_SR_DATA_ACK: // 0x80: data byte has been received, ACK has been returned
case TW_SR_GCALL_DATA_ACK: // 0x90: data byte has been received, ACK has been returned
i2crxbuffer[i2crxindex++] = TWDR;
if(i2crxindex < TWI_RX_BUFFER_SIZE)
TWCR |= (1 << TWINT) | (1 << TWEA); // receive data byte and return ACK
else
TWCR |= (1 << TWINT); // receive data byte and return NACK
break;
case TW_SR_DATA_NACK: // 0x88: data byte has been received, NACK has been returned
case TW_SR_GCALL_DATA_NACK: // 0x98: data byte has been received, NACK has been returned
TWCR |= (1 << TWINT);
break;
case TW_SR_STOP: // 0xA0: STOP or REPSTART has been received while addressed as slave
TWCR |= (1 << TWINT) | (1 << TWEA); // switch to SR mode with SLA ACK
if (i2cSlaveReceive) i2cSlaveReceive(i2crxindex, i2crxbuffer); // i2c receive is complete, call i2cSlaveReceive
break;
case TW_BUS_ERROR: // 0x00: Bus error due to illegal start or stop condition
TWCR |= (1 << TWINT) | (1 << TWSTO) | (1 << TWEA); // reset internal hardware and release bus
break;
}
}
void twi_slave_setrxhandler(void (*i2cSlaveRx_func)(uint8_t receiveDataLength, uint8_t* recieveData))
{
i2cSlaveReceive = i2cSlaveRx_func;
}
void twi_init(uint8_t adress)
{
i2cSlaveReceive = 0;
TWAR = adress;
TWCR = (1 << TWIE) | (1 << TWEA) | (1 << TWEN);
sei();
}
void i2c_rxservice(uint8_t length, uint8_t* data)
{
uint8_t counter;
for (counter = 0; counter <= length; counter++)
i2c_rxbuffer[counter] = *data++;
switch (i2c_rxbuffer[0])
{
case 'a':
PORTB ^=0x01;
break;
default:
break;
}
}
int main( void )
{
DDRB =0x01;
twi_init(0xAA);
while(1)
{
twi_slave_setrxhandler(i2c_rxservice);
}
}
В протериусе через дебагер и2ц посылаю S- стартует, адрес - отвечает ACK, 0x61 - отвечает АСК, P - связь как и должно быть разрывается, но во время посылки 0x61 ничего не происходит.
Слышал что в протериусе отладчик кода есть сейчас попробую, может через него ошибки найду?
Причина редактирования: Уменьшение видимого размера цитаты исходника.