Доброго времени суток!
При попытке получения байта по I2C дебаггер зависает из-за нарушения арбитража, хотя я вроде все делаю правильно. Сделал последовательность - в дебаггере она сдвинута на бит вправо, а слева добавляется единица.
Код для работы с I2C на ATmega32A
Код:
|
#define I2CSLAVE_ADDR 0x4E
#define PORT_DDR 0xB0 // PORTB Settings
#define PORT_IN 0xB1 // Get PINB
#define PORT_OUT 0xB2 // Set PORTB
#define GET_ANALOG 0xAF // Get all analog inputs
...
void i2c_slave_action(unsigned char rw_status)
{
switch(regaddr) {
// PORT
case PORT_DDR:
if (rw_status == 0)
// read
regdata = DDRB;
else
// write
DDRB = regdata;
break;
case PORT_IN:
if (rw_status == 0)
// read
regdata = PINB;
break;
case PORT_OUT:
if (rw_status == 1)
// write
PORTB = regdata;
case GET_ANALOG:
if (rw_status == 0) {
regdata = 0b10101100;
//regdata = (analog_block % 2 == 0 ? analog_h[analog_block] : analog_l[analog_block]);
analog_block++;
if (analog_block › 15) analog_block = 0;
}
break;
}
}
ISR(TWI_vect)
{
static unsigned char i2c_state;
unsigned char twi_status;
// Disable Global Interrupt
cli();
// Get TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
twi_status=TWSR & 0xF8;
switch(twi_status) {
case TW_SR_SLA_ACK: // 0x60: SLA+W received, ACK returned
i2c_state=0; // Start I2C State for Register Address required
break;
case TW_SR_DATA_ACK: // 0x80: data received, ACK returned
if (i2c_state == 0) {
regaddr = TWDR; // Save data to the register address
i2c_state = 1;
} else {
regdata = TWDR; // Save to the register data
i2c_state = 2;
}
break;
case TW_SR_STOP: // 0xA0: stop or repeated start condition received while selected
if (i2c_state == 2) {
i2c_slave_action(1); // Call Write I2C Action (rw_status = 1)
i2c_state = 0; // Reset I2C State
analog_block = 0;
}
break;
case TW_ST_SLA_ACK: // 0xA8: SLA+R received, ACK returned
case TW_ST_DATA_ACK: // 0xB8: data transmitted, ACK received
if (i2c_state == 1) {
i2c_slave_action(0); // Call Read I2C Action (rw_status = 0)
TWDR = regdata; // Store data in TWDR register
i2c_state = 0; // Reset I2C State
}
break;
case TW_ST_DATA_NACK: // 0xC0: data transmitted, NACK received
case TW_ST_LAST_DATA: // 0xC8: last data byte transmitted, ACK received
case TW_BUS_ERROR: // 0x00: illegal start or stop condition
default:
i2c_state = 0; // Back to the Begining State
}
// Clear TWINT Flag
TWCR |= (1‹‹TWINT);
// Enable Global Interrupt
sei();
} |
Последовательность - regdata = 0b10101100; А команда - получение данных с АЦП. Последовательность создавалась для проверки.
Это баг дебаггера или что-то не так с кодом?