Пытаюсь разобраться с i2c. нужно подключить акселерометр.
проц master. сначала записывается 1 байт (адрес регистра акселерометра), потом читается содержимое этого регистра.
Проблема такая , непонятно почему, но происходит двойное чтение.
Если расписать по прерываниям, то будет так txd(0x01) txd(0x11) rxd(0x12) rxd(0x12) (В скобках код посылаемы в uart для отладки.)
Непонятно также
1. как "запускать" передачу
всмысле нужно ли сразу писать UCB3TXBUF
или подождать прерывания?
2. почему нет прерываний start и stop, они же разрешены.
Привожу код полностью:
Код
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void main()
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
ConfigurationTimer();
UART3Reset();
Configuration_i2c();
DelayMilliSec(100); //ждем когда устаканится питание
__enable_interrupt();
UCB3I2CSA = 0x18; // write acc это 0x30 >> 1
UCB3IE = UCNACKIE | UCSTPIE | UCSTTIE | UCTXIE | UCRXIE;
while(1)
{
UCB3CTL1 &= ~(UCTXNACK | UCTXSTP);
UCB3CTL1 |= UCTR | UCTXSTT;
// UCB3TXBUF = 0x0F; //адресс
DelayMilliSec(10);
CLEARWDT();
__low_power_mode_0();
} // ^^^ while 1
}
//---------------------------------------------------------------------------------------
void Configuration_i2c()
{
UCB3CTL1 = UCSWRST; // set USCI reset
UCB3CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB3CTL1 = UCSSEL__ACLK + UCTR + UCSWRST; // Aclk = 460800 Hz см startup.c
UCB3BR0 = 40;
UCB0BR1 = 0;
P10OUT &= ~BIT3; // питание ACC (light)
P10SEL |= BIT1 | BIT2;
UCB3CTL1 &= ~UCSWRST; // clear USCI reset
}
//---------------------------------------------------------------------------------------
// UCB3 i2c interrupt service routine
#pragma vector=USCI_B3_VECTOR
__interrupt void USCI_B3_isr(void)
{
char ifg, tmp;
LedROn();
ifg = UCB3IFG;
if(ifg & UCTXIFG) //txd
{
if(state_acc == 0) // ничего не передавали, отдадим адресс
{
UCB3TXBUF = 0x0F; //адрес регистра
UART3Tx(0x01);
state_acc = 1;
}
else
if(state_acc == 1) // передали адресс, переходим на чтение
{
UCB3CTL1 &= ~UCTR;
UCB3CTL1 |= UCTXSTT | UCTXNACK;
// UCB3CTL1 |= UCTXNACK;
UART3Tx(0x11);
state_acc = 2;
}
else
{
UART3Tx(0x21);
}
}
if(ifg & UCRXIFG) //rxd
{
DelayMilliSec(1);
tmp = UCB3RXBUF;
UART3Tx(0x12);
state_acc = 0;
UCB3CTL1 |= UCTXSTP;
}
if(ifg & UCSTTIFG)
UART3Tx(0x02);
if(ifg & UCSTPIFG)
UART3Tx(0x04);
if(ifg & UCNACKIFG)
{
UCB3CTL1 |= UCTXSTP;
state_acc = 0;
UART3Tx(0x05);
}
UCB3IFG = 0;
LedROff();
__low_power_mode_off_on_exit();
}