This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Dear Sirs:
Found out that I have to use interrupts to send a slave address and one byte of data. So added interrupts to my simple example.
The program does send the slave address but never sends the data=200dec. If I put a break point at the top of the interrupt routine it will also send
a stop condition, otherwise it only sends the slave address. Appears to me it conforms to the example in the manual but still doesn't work right.
Any ideas, please?
Thanks, John
The code:
#include <msp430.h>
unsigned int TXByteCtr;
unsigned char *pTxData;
int A;
typedef unsigned char uint8;
/******************************************************************************
Test I2C MSP430FR5994
Simple I2C transmitter using interrupts. To be used to write to an electronic pot.
Transmits I2C TxData out P5.0 and P5.1
Originally from Dang
******************************************************************************/
int main(void)
{
int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
PM5CTL0 &=~LOCKLPM5; //disable GPIO power on default
UCB1CTL1 |= UCSWRST; // Enable SW reset
P5SEL0 |= BIT0 ; //UCB1SIMO
P5SEL0 |= BIT1 ; //UCB1SOMI
//P5SEL0 |= BIT3 ; //UCB1STE (slave tx enable)
P5SEL1 &= ~BIT0 ; //UCB1SIMO
P5SEL1 &= ~BIT1 ; //UCB1SOMI
//P5SEL1 &= ~BIT3 ; //UCB1STE (slave tx enable)
//UCMODE_3 sets I2C mode
UCB1CTLW0 |= (UCMST + UCMODE_3 + UCTR); // I2C Master, I2C, transmitter
UCB1CTLW1 = UCASTP_2 ; // Automatic stop assertion
UCB1BRW = 8; // fSCL = SMCLK/12 = ~100kHz
UCB1TBCNT =2; // 2 bytes data
//UCB1BR1 = 0;
UCB1I2CSA = 0x1; // Slave Address is 1ah
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt for UCB1IE
_enable_interrupts(); //global ie
TXByteCtr = 1; // Load TX byte counter
UCB1TXBUF = 200; // Load TX buffer with pot value
UCB1CTLW0 |= UCTXSTT; // I2C TX, start condition this transmits! UCTR is bit 4(0x10) of UCBxCTLW0
while (1)
{
// while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
// UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
// __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
A=A+1; // is TX'd
loop :
// UCB1TXBUF = TxData; // Load TX buffer new !!
for(i=0;i<10000;i++) //delay while sending
A=A+1;
}
}
//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count.
//
//------------------------------------------------------------------------------
//#pragma vector = USCI_B1_VECTOR
//__interrupt void isr_usci_b1(void){
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void){
static int IFlags;
IFlags = UCB1IFG;
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = 200; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
IFlags = UCB1IFG;
UCB1CTLW0 |= UCTXSTT; // I2C TX, start condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
}
else
{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
//__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
Hi John
Do the device go into the ISR of UCNACKIFG? Have see the ACK from the slave device after the correct address? If no may be something wrong with the slave device because the master have done its job.You can change other slave device for the test (for example you can use other launchpad as the slave device)
Best regards
Gary
You drug me across the finish, Gary:
Ran the example code on a different product and it worked correctly. Modified the example to send two bytes to a slave (3 bytes total incl slave adx).
This worked fine. Attached is a waveform.
The code is:
/* --COPYRIGHT--,BSD_EX
* Copyright (c) 2015, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* MSP430 CODE EXAMPLE DISCLAIMER
*
* MSP430 code examples are self-contained low-level programs that typically
* demonstrate a single peripheral function or device feature in a highly
* concise manner. For this the code may rely on the device's power-on default
* register values and settings such as the clock configuration and care must
* be taken when combining code from several examples to avoid potential side
* effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
* for an API functional library-approach to peripheral configuration.
*
* --/COPYRIGHT--*/
//******************************************************************************
// MSP430FR5x9x Demo - eUSCI_B1 I2C Master TX bytes to Multiple Slaves
//
// Description: This demo connects two MSP430's via the I2C bus.
// The master transmits to 4 different I2C slave addresses 0x0A,0x0B,0x0C&0x0D.
// Each slave address has a specific related data in the array TXData[].
// At the end of four I2C transactions the slave address rolls over and begins
// again at 0x0A.
// ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz
// Use with MSP430FR5x9x_eusciB1_i2c_multislave.c
//
// /|\ /|\
// MSP430FR5994 10k 10k MSP430FR5994
// slave | | master
// ----------------- | | -----------------
// -|XIN P7.0/UCB1SDA|<-|----+->|P7.0/UCB1SDA XIN|-
// | | | | |
// -|XOUT | | | XOUT|-
// | P7.1/UCB1SCL|<-+------>|P7.1/UCB1SCL |
// | | | |
//
// William Goh
// Texas Instruments Inc.
// October 2015
// Built with IAR Embedded Workbench V6.30 & Code Composer Studio V6.1
// Sends 3 bytes to write to an elect pot: slave adx (0x4c), command byte (0), data byte
//******************************************************************************
#include <msp430.h>
unsigned char TXData[] = { 0x0, 0x80, 0, 0 }; //only first two used
//const unsigned char SlaveAddress[] = { 0x4c, 0x0B, 0x0C, 0x0D };
volatile unsigned char TXByteCtr;
volatile unsigned char ByteCnt;
volatile unsigned char SlaveFlag = 0;
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
// Configure GPIO
P5SEL0 |= BIT0 | BIT1;
P5SEL1 &= ~(BIT0 | BIT1);
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Configure USCI_B1 for I2C mode
UCB1CTLW0 = UCSWRST; // put eUSCI_B in reset state
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK; // I2C master mode, SMCLK
UCB1BRW = 0x8; // baudrate = SMCLK / 8
UCB1CTLW0 &= ~UCSWRST; // clear reset register
UCB1IE |= UCTXIE0 | UCNACKIE; // transmit and NACK interrupt enable
SlaveFlag = 0; // Initialize SlaveFlag
while(1)
{
__delay_cycles(5000); // Delay between transmissions
UCB1I2CSA = 0x01a; // configure slave address MCSID bat U3=0x1a
TXByteCtr = 2; // Load TX byte counter
ByteCnt =0; //inc data byte counter for irq
while (UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB1CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is TX'd
TXData[1] = TXData[1] +1 ; // inc data for test!!!
// Change Slave address
/*
SlaveFlag++;
if (SlaveFlag > 3) // Roll over slave address
{
SlaveFlag = 0;
}
*/
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = EUSCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
UCB1CTLW0 |= UCTXSTT; // resend start if NACK
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: break; // Vector 22: RXIFG0
case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = TXData[ByteCnt]; // Load TX buffer
ByteCnt++; //inc the byte count
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
break;
case USCI_I2C_UCBCNTIFG: break; // Vector 26: BCNTIFG
case USCI_I2C_UCCLTOIFG: break; // Vector 28: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 30: 9th bit
default: break;
}
}
**Attention** This is a public forum