|
MSP430g2553 +lis302dl, проблема записи/чтения в регистров lis302dl |
|
|
|
Jan 27 2014, 07:41
|
Группа: Участник
Сообщений: 13
Регистрация: 27-01-14
Пользователь №: 80 202

|
Проблема заключается в следующем если читаю регистр имени устройства возвращает все правильно статусный тоже правильно возвращает . но вот если попытаться записать в статустный то не записывается. Работаю по I2C.
|
|
|
|
|
 |
Ответов
(1 - 3)
|
Jan 30 2014, 09:32
|
Группа: Участник
Сообщений: 13
Регистрация: 27-01-14
Пользователь №: 80 202

|
Проблема решена. Но появилась другая . Когда повесили на шину второе устройство начались проблемы если работать с одним устройством все нормально лишь изредка прявляться проблемы с флагом освобождения линии UCB0STAT & UCBBUSY , но вот если устройства два то зависание происходит фактически сразу. код программы привожу ниже . main.c
Код [spoiler]#include "msp430g2553.h" #include "intrinsics.h" #include "clock.h" #include "ADC.h" #include "I2C.h" #include "UART.h" #include "TI_USCI_I2C_master.h" #define addr1 0x1C #define addr2 0x1D unsigned char array1[6]={0x1f,0x1f,0x1f,0x1f,0x1f,0x1f}; unsigned char XYZ1[5]={0x1f,0x1f,0x1f,0x1f,0x1f}; unsigned char XYZ2[5]={0x1f,0x1f,0x1f,0x1f,0x1f}; unsigned char outdata[]={00,00}; void Init_timerA1(unsigned int time); void Init_timerA0(unsigned int time); volatile unsigned char ctnTA0=0, // счетчик пррерываний от таймера А0 ctnTA1=0, //счетчик пррерываний от таймера А1 fup=0, // flag преданого сообщения сбрасываться когда сообщение офф ctnOutPut=0;// длинна входящего сообщения unsigned int Sxyz=0;
unsigned char adrX=0xA9, adrY=0xAB, adrZ=0xAD;
// ???????? WATCHDOG
unsigned char calculateCheckSum( unsigned char * buffer, unsigned char length); inline void StopShim() { ctnOutPut=0; fup=0;// TA1CTL = 0; // сбросить флаг остановить шим P3SEL &= ~BIT3; P3OUT &= ~BIT3;
}
inline void GetAccelometrData1() { TI_USCI_I2C_transmitinit(addr1,0x02); // initialize USCI while ( TI_USCI_I2C_notready() ); // wait for bus to be free TI_USCI_I2C_transmit(1,&adrX); // transmit the first 3 bytes TI_USCI_I2C_receiveinit(addr1,0x02); while ( TI_USCI_I2C_notready() ); TI_USCI_I2C_receive(5,XYZ1); }
inline void GetAccelometrData2() { TI_USCI_I2C_transmitinit(addr2,0x02); // initialize USCI while ( TI_USCI_I2C_notready() ); // wait for bus to be free TI_USCI_I2C_transmit(1,&adrX); // transmit the first 3 bytes TI_USCI_I2C_receiveinit(addr2,0x02); while ( TI_USCI_I2C_notready() ); TI_USCI_I2C_receive(5,XYZ2); }
inline void DataPreparation() { Sxyz=XYZ1[0]+XYZ1[2]+XYZ1[4]+XYZ2[0]+XYZ2[2]+XYZ2[4]; outdata[0]=Sxyz; outdata[1]=Sxyz>>8; outdata[1]&= 0xF0; outdata[1]|=calculateCheckSum(outdata ,2); // ADCRead=ADC_read(); // outdata[0]=ADCRead; // outdata[1]=ADCRead>>8; // outdata[1]&= 0xF0; // outdata[1]|=calculateCheckSum(outdata ,2);
}
inline void UartDataOutput() {
P3SEL|=BIT3 ; freq (111); for ( unsigned char i = 0; i < 30; i++); fup=1; //флаг выданого сообщения ctnTA0=0; uart_send(outdata[0]); uart_send(outdata[1]);
}
unsigned char calculateCheckSum( unsigned char * buffer, unsigned char length) { unsigned char checksum = length % 0x10;
for ( unsigned char i = 0; i < length; i++) { checksum += buffer[i] >> 4; checksum %= 0x10; checksum += buffer[i] & 0x0F; checksum %= 0x10; }
return checksum; }
void main(void) {
unsigned int outd=0, ADCRead=0; unsigned char i1; WDTCTL = WDTPW + WDTHOLD; // Stop WDT { // Init unused ports here, enable pull up P3DIR |= BIT3; // BIT6 ????? P3SEL|=BIT3;
P2IES &= ~BIT1; // возрастающий фронт P2IE |= BIT1; // разрешение прерывания P2IFG &= ~BIT1; // очищаем флаг прерывания // P1DIR &= ~(BIT0 | BIT5 | BIT7); // P1REN |= BIT0 | BIT5 | BIT7; // P1OUT |= BIT0 | BIT5 | BIT7; P1SEL|=BIT6+BIT7; P1SEL2|=BIT6+BIT7; Set_DCO(80); P3DIR &= ~(BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT6 | BIT7); P3REN |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 |BIT7; P3OUT |= BIT0 | BIT1 | BIT2 | BIT4 | BIT5 | BIT7;
// ADC_init(); __enable_interrupt();
} unsigned char array2[2]={0xA0,0x47};
UCB0CTL1 |= UCTXSTP;//stop TI_USCI_I2C_transmitinit(addr1,0x02); //установка регистра while ( TI_USCI_I2C_notready() )}} // запись врегистр TI_USCI_I2C_transmit(2,array2); TI_USCI_I2C_receiveinit(addr1,0x02); while ( TI_USCI_I2C_notready() ); TI_USCI_I2C_receive(5,array1); UCB0CTL1 |= UCTXSTP;//stop TI_USCI_I2C_transmitinit(addr1,0x02); //установка регистра while ( TI_USCI_I2C_notready() ); // запись врегистр TI_USCI_I2C_transmit(2,array2); TI_USCI_I2C_receiveinit(addr1,0x02); while ( TI_USCI_I2C_notready() ); TI_USCI_I2C_receive(5,array1);
Init_timerA0(75); // таймер выдачи сообщ uart_setup();
while(1) { switch(ctnTA0) { case 19: GetAccelometrData1(); GetAccelometrData2(); DataPreparation(); break; case 20: UartDataOutput(); break; default: break; }
if (ctnOutPut==8) { StopShim(); } } }
#pragma vector=PORT2_VECTOR __interrupt void P2_iterrupt(void){ TA1R = 0;
if ((P2IES & BIT1) == 0) { freq (136); // устанавливаем частоту bit 1 1.17 } else { freq (74);// устанавливаем частоту bit 1 2.047 } // сброс прерывания P2IES ^= BIT1; P2IFG &= ~BIT1; } #pragma vector=TIMER0_A0_VECTOR // Timer1 A0 interrupt service routine
__interrupt void Timer0_A0 (void) { ctnTA0++;// таймер отправки сообщений if (fup==1) ctnOutPut++; }[/spoiler]
Код текст файла библиотеки которую использую
#include "msp430g2553.h" // device specific header
#include "TI_USCI_I2C_master.h"
signed char byteCtr; unsigned char *TI_receive_field; unsigned char *TI_transmit_field;
//------------------------------------------------------------------------------ // void TI_USCI_I2C_receiveinit(unsigned char slave_address, // unsigned char prescale) // // This function initializes the USCI module for master-receive operation. // // IN: unsigned char slave_address => Slave Address // unsigned char prescale => SCL clock adjustment //----------------------------------------------------------------------------- void TI_USCI_I2C_receiveinit(unsigned char slave_address, unsigned char prescale){ P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0 P3SEL2 |= SDA_PIN + SCL_PIN; UCB0CTL1 = UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = prescale; // set prescaler UCB0BR1 = 0; UCB0I2CSA = slave_address; // set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0I2CIE = UCNACKIE; IE2 = UCB0RXIE; // Enable RX interrupt }
//------------------------------------------------------------------------------ // void TI_USCI_I2C_transmitinit(unsigned char slave_address, // unsigned char prescale) // // This function initializes the USCI module for master-transmit operation. // // IN: unsigned char slave_address => Slave Address // unsigned char prescale => SCL clock adjustment //------------------------------------------------------------------------------ void TI_USCI_I2C_transmitinit(unsigned char slave_address, unsigned char prescale){ P3SEL |= SDA_PIN + SCL_PIN; P3SEL2 |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0 UCB0CTL1 = UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = prescale; // set prescaler UCB0BR1 = 0; UCB0I2CSA = slave_address; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0I2CIE = UCNACKIE; IE2 = UCB0TXIE; // Enable TX ready interrupt }
//------------------------------------------------------------------------------ // void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field) // // This function is used to start an I2C commuincation in master-receiver mode. // // IN: unsigned char byteCount => number of bytes that should be read // unsigned char *field => array variable used to store received data //------------------------------------------------------------------------------ void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field){ TI_receive_field = field; if ( byteCount == 1 ){ byteCtr = 0; __disable_interrupt(); UCB0CTL1 |= UCTXSTT; // I2C start condition while (UCB0CTL1 & UCTXSTT); // Start condition sent? UCB0CTL1 |= UCTXSTP; // I2C stop condition __enable_interrupt(); } else if ( byteCount > 1 ) { byteCtr = byteCount - 2; UCB0CTL1 |= UCTXSTT; // I2C start condition } else while (1); // illegal parameter }
//------------------------------------------------------------------------------ // void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field) // // This function is used to start an I2C commuincation in master-transmit mode. // // IN: unsigned char byteCount => number of bytes that should be transmitted // unsigned char *field => array variable. Its content will be sent. //------------------------------------------------------------------------------ void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field){ TI_transmit_field = field; byteCtr = byteCount; UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition }
//------------------------------------------------------------------------------ // unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address) // // This function is used to look for a slave address on the I2C bus. // // IN: unsigned char slave_address => Slave Address // OUT: unsigned char => 0: address was not found, // 1: address found //------------------------------------------------------------------------------ unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address){ unsigned char ie2_bak, slaveadr_bak, ucb0i2cie, returnValue; ucb0i2cie = UCB0I2CIE; // restore old UCB0I2CIE ie2_bak = IE2; // store IE2 register slaveadr_bak = UCB0I2CSA; // store old slave address UCB0I2CIE &= ~ UCNACKIE; // no NACK interrupt UCB0I2CSA = slave_address; // set slave address IE2 &= ~(UCB0TXIE + UCB0RXIE); // no RX or TX interrupts __disable_interrupt(); UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX, start condition while (UCB0CTL1 & UCTXSTP); // wait for STOP condition returnValue = !(UCB0STAT & UCNACKIFG); __enable_interrupt(); IE2 = ie2_bak; // restore IE2 UCB0I2CSA = slaveadr_bak; // restore old slave address UCB0I2CIE = ucb0i2cie; // restore old UCB0CTL1 return returnValue; // return whether or not // a NACK occured }
//------------------------------------------------------------------------------ // unsigned char TI_USCI_I2C_notready() // // This function is used to check if there is commuincation in progress. // // OUT: unsigned char => 0: I2C bus is idle, // 1: communication is in progress //------------------------------------------------------------------------------ unsigned char TI_USCI_I2C_notready(){ return (UCB0STAT & UCBBUSY); }
#pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { if (UCB0STAT & UCNACKIFG){ // send STOP if slave sends NACK UCB0CTL1 |= UCTXSTP; UCB0STAT &= ~UCNACKIFG; }
}
#pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (IFG2 & UCB0RXIFG){ if ( byteCtr == 0 ){ UCB0CTL1 |= UCTXSTP; // I2C stop condition *TI_receive_field = UCB0RXBUF; TI_receive_field++; } else { *TI_receive_field = UCB0RXBUF; TI_receive_field++; byteCtr--; } } else { if (byteCtr == 0){ UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag } else { UCB0TXBUF = *TI_transmit_field; TI_transmit_field++; byteCtr--; } } }
Сообщение отредактировал A_lex_sander - Jan 30 2014, 09:34
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|