Проблема решена. Но появилась другая . Когда повесили на шину второе устройство начались проблемы если работать с одним устройством все нормально лишь изредка прявляться проблемы с флагом освобождения линии 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--;
}
}
}