Jump to content

bjbance

Members
  • Content Count

    11
  • Joined

  • Last visited

About bjbance

  • Rank
    Member

Profile Information

  • Gender
    Not Telling
  1. bjbance

    Questions on i2C with the G2553

    i'm really grasping at straws here. after going blind for a couple of days, there wasn't any improvement. So i started looking for code examples the I can learn from. Most of the code are for older versions that don't seem to work. Finally, I managed to find the thread below and copied the code of ucfknight. http://forum.43oh.com/topic/3216-need-help-with-i2c-using-msp430g2553/ I studied it and stripped the parts that I don't need and modified it for my application and ended with the code below for the master. #include <msp430.h> #include <msp430g2553.h> void InitializeI2c(void); void WriteI2c(char MpuReg, char Data); void ReadI2c(char MpuReg, char *Field, char ByteCnt); #define slave 0x48 // Slave Address #define False 0 #define True 1 // I2C char I2c_Tx; char AddSent; char Register; char ByteSent; char RepStart; char ReadWriteN; char *I2c_Rx_Field; signed char I2cByteCnt; /////////////////////// int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer char DATA[2]; char DATA2[2]; InitializeI2c(); WriteI2c(slave, 'A'); WriteI2c(slave, 'B'); WriteI2c(slave, 'A'); WriteI2c(slave, 'B'); WriteI2c(slave, 0x01); ReadI2c(slave,DATA,1); WriteI2c(slave, 0x02); ReadI2c(slave,DATA2,1); return 0; } void InitializeI2c(void) { P1SEL |= BIT6 + BIT7; // p1.6 SCL p1.7 SDA P1SEL2 |= BIT6 + BIT7; P1OUT |= BIT6 + BIT7; UCB0CTL1 |= UCSWRST; // ensure SWRST high before configuration UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Master, I^2C, Synchronous UCB0CTL1 = UCSSEL_2 + UCSWRST; // SMCLK, keep SWRST high UCB0BR0 = 12; UCB0BR1 = 0; UCB0I2CSA = slave; // Set Slave Address UCB0CTL1 &= ~UCSWRST; UCB0I2CIE = UCNACKIE; IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); IE2 |= UCB0TXIE + UCB0RXIE; } /////////////////////////////////////////////////////////////////////////// // WriteI2c Writes a single Byte to the Internal Register Address MpuReg / // / // Parameters: / // - MpuReg = Internal Register Address / // - Data = Byte to be written to MpuReg / /////////////////////////////////////////////////////////////////////////// void WriteI2c(char MpuReg, char Data) { // Reset variables prior to Start of Transmission AddSent = False; ReadWriteN = False; ByteSent = False; I2c_Tx = Data; // Load Byte to be written to MPU Register = MpuReg; // Load Internal Register Address UCB0CTL1 |= UCTR + UCTXSTT; // send I2C start condition __bis_SR_register(CPUOFF + GIE); } //////////////////////////////////////////////////////////////////////////////////////////////////////// // Read I2c Reads a user specified number of Bytes and stores them in the String pointed to by *Field / // / // Parameters: / // - MpuReg = Internal Register Address to be Read / // - *Field = Pointer to Storage String / // - ByteCnt = Number of Bytes to be Read / //////////////////////////////////////////////////////////////////////////////////////////////////////// void ReadI2c(char MpuReg, char *Field, char ByteCnt) { // Reset variables prior to Start of Transmission RepStart = False; AddSent = False; ReadWriteN = True; I2cByteCnt = ByteCnt; // Load number of byte to be read to Global variable I2c_Rx_Field = Field; // Copy pointer for String to be Read Register = MpuReg; // Load Internal Register Address UCB0CTL1 |= UCTR + UCTXSTT; // send I2C start condition __bis_SR_register(CPUOFF + GIE); } // USCIAB0TX Interrupt Service Routine #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void){ static unsigned char Index = 0; // If ReadWriteN = True // Read Operation if (ReadWriteN) { // Check if Internal Register Address and Repeated Start have been sent // If True Start to Read UCB0RXBUF if(RepStart == True && AddSent == True) { // If Index is not equal to last byte to read // Keep reading if(Index != I2cByteCnt-1) { *I2c_Rx_Field++ = UCB0RXBUF; Index++; } // Else Read Last byte and send stop condition else { *I2c_Rx_Field = UCB0RXBUF; UCB0CTL1 |= UCTXSTP; // send stop condition while(UCB0CTL1 & UCTXSTP); IFG2 &= ~UCB0RXIFG; Index = 0; __bic_SR_register_on_exit(CPUOFF); } } // Send the Register address Followed by the Repeated Start else { // If Register Address has not been sent. Send Register Address if(AddSent == False) { UCB0TXBUF = Register; AddSent = True; } // If Register Address have been sent. Send Repeated Start. else { IFG2 &= ~UCB0TXIFG; UCB0CTL1 &= ~UCTR; UCB0CTL1 |= UCTXSTT; RepStart = True; } } } // If ReadWriteN = False // Write Operation else { // Check if Register Address has been sent // If True Start Writing to UCB0TXBUF if(AddSent == True) { // Check if Data has been Written to UCB0TXBUF // If True the send STOP condition if(ByteSent == True) { UCB0CTL1 |= UCTXSTP; // send stop condition IFG2 &= ~UCB0TXIFG; // clear Tx flag __bic_SR_register_on_exit(CPUOFF); } // Else Write Data to UCB0TXBUF else { UCB0TXBUF = I2c_Tx; ByteSent = True; } } // If Register Address has not been sent. Send it else { UCB0TXBUF = Register; AddSent = True; } } } this code works well and can send data to the slave. But when I try to read from the slave, it hangs. I think I am not getting the correct response from the slave and the master ends up waiting indefinitely. So my code in the first post for the slave isn't correct (no wonder there). Examples for i2c slaves are even more difficult to find as more people tend to interface with i2c sensors. I hope someone can provide me with a working i2c slave example for reading that I can study. Btw, am i right in using 0x48 for writing and 0x49 for reading?
  2. bjbance

    Questions on i2C with the G2553

    Code for I2C Master //****************************************************************************** // MSP430G2xx3 Demo - USCI_B0 I2C Master TX single bytes to MSP430 Slave // // Description: This demo connects two MSP430's via the I2C bus. The master // transmits to the slave. This is the master code. It continuously // transmits 00h, 01h, ..., 0ffh and demonstrates how to implement an I2C // master transmitter sending a single byte using the USCI_B0 TX interrupt. // ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.2MHz // // /|\ /|\ // MSP430G2xx3 10k 10k MSP430G2xx3 // slave | | master // ----------------- | | ----------------- // -|XIN P1.7/UCB0SDA|<-|---+->|P1.7/UCB0SDA XIN|- // | | | | | // -|XOUT | | | XOUT|- // | P1.6/UCB0SCL|<-+----->|P1.6/UCB0SCL | // | | | | // // D. Dang // Texas Instruments Inc. // February 2011 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2553.h" #include <msp430.h> unsigned char TXData; unsigned char TXByteCtr; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // 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 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x48; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0TXIE; // Enable TX interrupt TXData = 0x00; // Holds TX data while (1) { TXByteCtr = 1; // Load TX byte counter while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data // is TX'd TXData++; // Increment data byte } } //------------------------------------------------------------------------------ // 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 = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = TXData; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } } Code for I2C Slave //****************************************************************************** // MSP430G2xx3 Demo - USCI_B0 I2C Slave RX single bytes from MSP430 Master // // Description: This demo connects two MSP430's via the I2C bus. The master // transmits to the slave. This is the slave code. The interrupt driven // data receiption is demonstrated using the USCI_B0 RX interrupt. // ACLK = n/a, MCLK = SMCLK = default DCO = ~1.2MHz // // /|\ /|\ // MSP430G2xx3 10k 10k MSP430G2xx3 // slave | | master // ----------------- | | ----------------- // -|XIN P1.7/UCB0SDA|<-|---+->|P1.7/UCB0SDA XIN|- // | | | | | // -|XOUT | | | XOUT|- // | P1.6/UCB0SCL|<-+----->|P1.6/UCB0SCL | // | | | | // D. Dang // Texas Instruments Inc. // February 2011 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2553.h" volatile unsigned char RXData; void main(void) { P1DIR |= 0x01; WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode UCB0I2COA = 0x48; // Own Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt while (1) { __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts __no_operation(); // Set breakpoint >>here<< and read } // RXData } // USCI_B0 Data ISR #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) { RXData = UCB0RXBUF; // Get RX data P1OUT ^= 0x01; if (RXData = 1) { UCB0TXBUF = 'A'; } else if (RXData = 2){ UCB0TXBUF = 'B'; } else{ UCB0TXBUF = 'C'; } __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } I've managed to make these two demos work(I added the P1.0 toggle to see if it works) but I cannot find good examples to actually retrieve data from the slave. From what I understand if correct, is I need to send two sequences in order to retrieve data from the slave. (I also added the if-else statement in the slave, I am just not sure if it is correct). To get the value 'A' I need to send the following: UCB0I2COA = 0x48; UCB0TXBUF = 0x01; then send, UCB0I2COA = 0x49; for read mode. I'm assuming that once the data is placed inside UCB0TXBUF, it will be retrieved once the master sends the address with read bit set high. is my code for the slave correct? is my approach for the master right? lastly, how do I handle the data being sent by the slave? i believe i should have a block like the one below. But from what I've read, there is no RX interrupt for I2C; this seems to be supported by the slave code using the TX interrupt to receive data from the master. #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) { Data = UCB0RXBUF; } I'd appreciate any input I can get.
  3. bjbance

    MSP430 and ACS712

    I'm using a module with an ACS712 hall-effect sensor to measure the current. the output of the ACS712 is measured by an ADC in the MSP. The ACS712 has an output range of 0-VCC (-5A to 5A) and should stay at VCC/2 at 0amps. I am powering the ACS712 from a 5V supply (although I think it might be possible to power it with 3.3V) and used a voltage divider (5k/10k) on the output side. The output seems to be ok since I am reading a value of 518 with no current running through it. The problem happens when begin to pass current through the sensor; just DC for the moment. I am using a pair of LED lights that draw roughly 100mA each. In one direction, the reading goes down to 515 when i add the first light and then 512 after adding the second. If I reverse the current, I get 521 when I add the first light, then ~007 after adding the second. If i remove the second light, the reading goes back to 521. I believe the problem is in the voltage divider. I've already gone down from 20k/40k to 5k/10k. Do i need to go down even further? Maybe 1k/2k? thanks ------------------------ edit nevermind. It was just an idiotic coding error. lol
  4. bjbance

    CCSv4 vs Energia

    yes. i think i will give energia a whirl after i finish my current project. i just wanted to know whether the energia executable we can download is a native application, or if it requires javaw.exe to be running. or does it come in two variants? i've also given up on av software a long time ago. :grin: i believe its because v4 is the one with the code limited free version, if I am recalling correctly. if v5 has the same, please kindly share the link. please enlighten us so that it can be reduced maybe to jaw slacking maybe. :grin: no, really. let's just share information without flaming
  5. bjbance

    CCSv4 vs Energia

    i'm currently limited to the G2 line so i guess cost doesn't apply to me yet. I also can't relate to the magic hand waving since i did not have any problem installing CCSv4 or do anything other than follow the installation prompts. so, which is which? the annoying thing i've encountered with CCS is when it eventually lags after an hour or two and i need to close and reopen it to get it back to normal. i've no experience with energia yet but i've seen a JAVA Arduiino IDE during a presentation. From what little I've seen, the coding style is a lot easier to learn and it got a lot of libraries so it you don't have to worry much when it comes to typical functions. on the downside, it seemed incredibly slow. just opening the program took longer than booting the computer. sometimes it did not load at all. opening files also seemed to take a lot longer than usual as well as connecting with the target device. it was not my computer and i was not operating it, it could have been his fault and not the program, but it left a bad impression on me.
  6. bjbance

    CCSv4 vs Energia

    Since I got my launchpad a few months ago, I've been using CCSv4. I admit, the learning curve was quite steep at first. But i eventually got the hang of it. I can now do some basic stuff like interfacing with an LCD, using timers, the ADC, uart, and the like. After I registered here, I noticed that there seems to be a lot of buzz about energia. It seems to me to be just another IDE. I would just like to ask if it would be better for me to switch to energia or just stick with CCS. What are the pros and cons. Thanks.
  7. bjbance

    Watchdog Timer Problems

    just an update to this problem. I've actually close to eliminating the variable array (reduced it down to 20), but the problem still persisted. just out of sheer luck, while reading someone else's ADC code which used interrupts when the conversion was done, i realized that I had the interrupt enabled even though I don't use it. After removing ADC10IE, the program worked. btw, i also realized why i went with the initial approach. I needed the entire set and not just the average. lol. So, I went with a smaller array (125 values) and might reduce it further (maybe down to 50) if needed.
  8. bjbance

    Watchdog Timer Problems

    wow. i've been having problems accessing 43oh, i think for the past 12 hours. the site just won't load even though other sites load. was it the same for you as well? thanks for the replies. i don't know where to start. 1. i didn't really think about hitting the RAM ceiling on the device. I gues my variable array is causing the problems i've been having. it would have been a lot more obvious when I scale it up to 1250. lol. i guess i'll just change my approach and multiply each value by 0.0008 and accumulate the samples in a single float variable. 2. i've also considered using a single variable for the flags, just like the registers, but decided to put it off for later. just because it is easier to look at for the moment. 3. with the getVoltage function inside the ISR. i was supposed to move it out of the ISR once it functions properly, but getting stuck meant i never got to that point. lol 4. i guess i really should put volatile on my global variables. lol thanks for the replies again. I'll modify the code and load it on my device when I get home.
  9. bjbance

    Watchdog Timer Problems

    #include <msp430g2553.h> #include "Nokia.h" unsigned int sample_counter; unsigned int global_counter; unsigned short flag_display; unsigned short flag_newbatch; unsigned short flag_connect; unsigned int value; unsigned int VAL[200] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; void initClock() { BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ; BCSCTL2= DIVS_0 + DIVM_0; } void initADC(void) { ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; ADC10CTL1 = INCH_3; ADC10AE0 |= 0x08; ADC10DTC0 = 0x01; } void initTimer() { CCR0 = 40000; CCTL0 |= 0x10; TACTL = TASSEL_2 + MC_1; // ------ PWM P1DIR |= 0x04; P1SEL |= 0x04; TACCR0 = 40000; TACCR1 = 39000; TACCTL1 = OUTMOD_3; // ------ PWM } void updateDisplay(void){ int volt; int tens; int ones; int deci; int ii; for (ii = 0; ii<200; ii++){ volt = VAL[ii]; } volt = volt/200; tens = volt/100; LCDLNum(tens, 48, 1); volt = (volt-(tens*100))*10; ones = volt/100; LCDLNum(ones, 60, 1); volt = (volt-(ones*100))*10; deci = volt/100; LCDLNum(deci, 72, 1); } void getVoltage(void) { unsigned int val; ADC10CTL0 |= ENC + ADC10SC; while (ADC10CTL1 & ADC10BUSY); val = ADC10MEM; VAL[sample_counter] = val; } void main(void) { WDTCTL = WDTPW+WDTHOLD; initClock(); initTimer(); initADC(); P2DIR = 0xFF; P2OUT = 0x00; global_counter = 0; sample_counter = 0; flag_display = 0; flag_connect = 0; value = 0; LCDinit(); LCDclear(); LCDgoto(0,1); LCDstring("Values:"); LCDLNum(1, 48, 1); LCDLNum(0, 60, 1); LCDLNum(0, 72, 1); _BIS_SR(GIE); while(1){ if (flag_display == 1) { flag_display = 0; updateDisplay(); } if (flag_connect == 1) { P1OUT |= 0x02; } } } #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer0_A0 (void) { int ii; if (sample_counter == 200){ sample_counter = 0; global_counter++; flag_display = 1; for (ii = 0; ii<200; ii++){ VAL[ii] = 0; } } else{ getVoltage(); sample_counter++; } } this is my code. the header file is just for the lcd connected to port 2.
  10. bjbance

    Watchdog Timer Problems

    Thanks for your reply. I already did that at the start of the program. And even if I declared it again later in the program, it still resets. Funny thing is it only happens when I use both the Timer and the ADC. When only one of them is used, the reset doesnt occur.
  11. bjbance

    Watchdog Timer Problems

    Hi. I've been playing withthe MSP430G2 for a few months now. I have a problem regarding the watchdog timer. The program I'm building is meant to measure the current being drawn on a line. I wanted to use the timer to initiate the ADC conversion so that I get evenly spaced samples at a conservative sample rate of 1250sps. My problem is the watchdog timer seems to kick-in and restart the program even though I've only turned it off using WDTPW + WDTHOLD at the start of the program. (I once deleted that line of code in another program and that was the behaviour, so I guess it is also what's happening now). If I removed the ADC conversion, the program behaves normally. And if I also removed the timer and just looped the ADC conversion, the program also works well. BTW, I have the ADC hooked up to P1.3 and I have CCR0 at 40k with MCLK running at 8Mhz. Hope someone can give me insights on how to solve this problem. Thanks
×