Other Parts Discussed in Thread: TMP101, TMP100
Hello,
First of all let me begin by saying I am very, very new to this. I am taking a class for the first time using MCUs and I am very much confused. I don't find the forums or the support community much help at all yet (because a lot of it is over my head) and I'm hoping that I can really get some help for a beginner. I have some very basic questions for the project I am working on, dealing with the TMP101 temp sensor. Please help by answering questions in a way that a beginner could understand. Also, a response "just read the datasheet" won't help much because I have read a great deal of both datasheets (TMP101 and MSP430) and a lot of it is still Greek to me :)
Ok, so I am hooking up the MCU and the TMP101 in a MASTER/Slave configuration.1.) When wiring the TMP101, what do I wire ADD0 (pin5) to. It says in the TMP101 datasheet that a slave address must be set in the software, which it is (see Code below). This is done when UCB012CSA = 0x49. Now according to the datasheet, this is required when ADD0 is FLOAT, or is not connected. So I did this because I left pin5 unconnected. This was just example code I had copied and originally it was set at 0x48 which makes more sense because this is for just connecting to one device but it says ADD0 has to be 0 so I'm not exactly sure what that means. Does setting it to 0x48 assume the msb is 0? But then I'm back to the original question as to what do I wire pin5 to?
Hope I didn't make that more confusing than it is but as you can tell, I am pretty confused. Second question is, does the ALERT pin (pin3) need to be wired to anything? According to the datasheet, it has something to do with SMBus? So I assume if using I2C, it is unused? At first I had Vdd going to it (with a 10k pull up resistor, I also had SCL and SDA wired with 10k pull up resistors), then I just completely removed power to it and had no difference in output (although the output is not what I wanted either way).
Ok, so here is my code that I got from some ti example code. Basically, what I think it is supposed to do is if a temp is greater than 28 deg. C, the LED is turned on. If not, the LED is turned off. I changed the one thing I mentioned before (UCB012CSA = 0x49 instead of 0x48) and added a bunch of comments to help me understand it better but other than that it is the same example code. It is not working as it supposed to; the LED turns on no matter what (even after switching the logic) so I am lost at what to do. Please help, and remember I am very new to this.
Code:
/******************************************************************************
// CC430F613x Demo - USCI_B0 I2C Master RX single bytes from MSP430 Slave
//
// Description: This demo connects two MSP430's via the I2C bus. The master
// reads from the slave. This is the MASTER CODE. The data from the slave
// transmitter begins at 0 and increments with each transfer. The received
// data is in R5 and is checked for validity. If the received data is
// incorrect, the CPU is trapped and the P1.0 LED will stay on. The USCI_B0
// RX interrupt is used to know when new data has been received.
// ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz
// Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
//******************************************************************************
#include
"cc430x613x.h"
#define
RED_LED BIT6
#define
GRN_LED BIT0
unsigned
int RxByteCtr;
unsigned
int RxWord = 0;
//volatile unsigned char RxBuffer[1]; // Allocate 128 byte of RAM
void
main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Stop WDT
P1OUT = 0xFF;
//Enables Port 1 Output as 1111 1111 (binary) //Outputs are all high
// P2OUT |= BIT6 +BIT7;
P3OUT = 0;
//Port 3 Output is low
P1DIR |= GRN_LED;
//OR'd with all 1's ?
P3DIR |= RED_LED;
//Don't understand the purpose of this and above line. //Pg 305 Family UsersGuide
PMAPPWD = 0x02D52;
// Get write-access to port mapping registers
//Same as PMAPKEYID-Chapter 9 FamilyUsersGuide
//0x02D52 must be used to have access
P2MAP6 = PM_UCB0SDA;
// Map UCB0SDA output to P2.6
//USCI_B0 I2C data (open drain and direction controlled by USCI)
//page 323 FamilyUsersGuide
P2MAP7 = PM_UCB0SCL;
// Map UCB0SCL output to P2.7
//USCI_B0 I2C clock
PMAPPWD = 0;
// Mapping complete, lock port mapping registers with an invalid key (anything other than 0x02D52)
P2SEL |= BIT6 + BIT7;
// Assign I2C pins to USCI_B0 By OR'ing.
UCB0CTL1 |= UCSWRST;
// Enable software reset //Would rewriting this as UCSWRST = 1 accomplish the same thing?
//pg. 523 of the Family Users Guide
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
// UCMST Selects Master Mode, UCSYNC is bit 0-enables Synchronous Mode
//UCMODE_3 selects I2C mode-11 binary which is equal to 3, but not sure how this works. Does the synchronous mode
// automatically synchronize it? Is the UCMODEx just not even needed? pg.522 FUG
UCB0CTL1 = UCSSEL_2 + UCSWRST;
// Use SMCLK, keep SW reset Note: In FUG, the 0 bit for UCB0CTL0 and UCB0CTL1
//are already 1?
UCB0BR0 = 12;
// fSCL = SMCLK/12 = ~100kHz //SMCLK runs at apprx. 1MHZ, which would actually be fSCL=83.3kHz
//Don't understand the purpose of setting it to this frequency. Timing issue?
UCB0BR1 = 0;
//UCB0BR0 and UCB0BR1 work together to form a prescaler value, not sure how it works Pg 523 of FUG
UCB0I2CSA = 0x49;
// Set slave address //UCB0I2CSA is the Slave Address Register pg. 525 FUG
//The master must first address slave devices via a slave address byte. 0x48 corresponds
//to the slave address 0100 1000 given in Table 12 of the TMP101 datasheet pg 8. The datasheet
//indicates that up to 3 devices can be connected but we are using just one so ADD0=0.
UCB0CTL1 &= ~UCSWRST;
// Clear software reset, resume operation//Would UCSWRST=0 be same thing?-I think it can only be 1.
UCB0IE |= UCRXIE;
// Enable RX interrupt
TA1CTL = TASSEL_2 + MC_2;
// ACLK, upmode, clear TAR ---This should be SMCLK? Why Upmode? Pg 370 FUG
while (1)
{
RxByteCtr = 2;
// Load RX byte counter //Why 2?
UCB0CTL1 |= UCTXSTT;
// I2C start condition //Is there supposed to be a NACK before (Bit 3 of UCB0CTL1 Register pg. 523 FUG)
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0, enable interrupts //LMP0 --Table 1-2 Operation Modes pg. 32 FUG
// Remain in LPM0 until all data
// is RX'd
if
(RxWord < 28) // >28C? //So this is the temperature?
P1OUT |= 0x01;
// Yes, P1.0 = 1
else
P1OUT &= ~0x01;
// No, P1.0 = 0
__disable_interrupt();
TA1CCTL0 = CCIE;
__bis_SR_register(CPUOFF + GIE);
// Enter LPM0, enable interrupts
TA1CCTL0 &= ~CCIE;
// Remain in LPM0 until TACCR0 ----WHAT DOES THIS MEAN???
// interrupt occurs
TA1CCTL0 &= ~CCIE;
//____________________________________________^^^^^^^
}
}
// The USCIAB0TX_ISR is structured such that it can be used to receive any
// 2+ number of bytes by pre-loading RxByteCtr with the byte count.
#pragma
vector = USCI_B0_VECTOR
__interrupt
void USCI_B0_ISR(void)
{
RxByteCtr--;
// Decrement RX byte counter
if
(RxByteCtr)
{
RxWord = (unsigned int) UCB0RXBUF ; // Get received byte
if (RxByteCtr == 1) // Only one byte left?
UCB0CTL1 |= UCTXSTP;
// Generate I2C stop condition
}
else
{
RxWord |= UCB0RXBUF;
// Get final received byte,
// Combine MSB and LSB
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
}
}
// Timer A0 interrupt service routine
#pragma
vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF);
// Exit LPM0
}