Jump to content
43oh

msp430g2553 i2c problem with hmc5883l magnetometer (GY-273)


Recommended Posts

Someone can helpme, i'm taking incorrect readings of a magnetometer

I believe with the problem are in my i2c code implementation.

/*
 * Print all printable characters on usb channel using UART mode of USCI module
 * the print is based in busy wait to transfer characters
 */
#include "msp/msp430g2553.h"
void configureDCO();
  
void configureUART();
void putc(char);
void print (const char[]);
void print (short);
void printStatus();
     
main() {
    configureDCO();
    configureUART();
    UCB0CTL1 = UCSWRST;  //Reset USCI
    UCB0CTL0 =          // USCI_B0 control register
        UCMST       // set master mode 
        | UCMODE_3  // I2C mode select
        | UCSYNC;   // synchronous
    UCB0CTL1 =      // UCSI_B0 control register
        UCSSEL_2    //select clock source, SMCLK
        | UCSWRST;
    UCB0I2CSA = 0x1e;   // write desired slave address to the UCBxI2CSA, magnetometer address
    
    // prescaler to generate 75 Hz (1MHz of SMCLK / 13981 of prescaler)
    UCB0BR0 = 0x9D;
    UCB0BR1 = 0x36;
    //configure ports
    P1SEL |= BIT6 | BIT7;
    P1SEL2|= BIT6 | BIT7;
    UCB0CTL1 &= ~UCSWRST; // Initializate USCI
    print("[system] I2C configured\r\n");
    // send start to transmit
    UCB0CTL1 |=
          UCTR      // setting UCTR for transmitter mode
        | UCTXSTT;  // setting UCTXSTT to generate START condition
    // point to register A ( address 0x00 )
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0x00; // load data to be trasmitted on UCBxTXBUF
    // write 0x78 in register A, mean of eight measurements, 75 Hz sample rate
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0x78; // load data to be trasmitted on UCBxTXBUF
    // point to register B ( address 0x01 )
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0x01; // load data to be trasmitted on UCBxTXBUF
    
    // write 0xa0 in register B, gain five
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0xa0; // load data to be trasmitted on UCBxTXBUF
    // point to mode register ( address 0x02 )
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0x02; // load data to be trasmitted on UCBxTXBUF
    // write 0x00 in mode register, continuous operation
    while ( !(IFG2 & UCB0TXIFG) ); // wait UCBxTXIFG are set, when set the buffer are empty
    UCB0TXBUF = 0x00; // load data to be trasmitted on UCBxTXBUF
    // send stop
    UCB0CTL1 |= UCTXSTP; // send stop
    while (UCB0CTL1 & UCTXSTP); // wait STOP condition is ack
    __delay_cycles(6000); // wait 6ms, until change the settings of magnetometer
    // send start to receive
    UCB0CTL1 &= ~UCTR;  // setting UCTR for receiver mode
    UCB0CTL1 |= UCTXSTT;    // setting UCTXSTT to generate START condition
    while (UCB0CTL1 & UCTXSTT);
    // infinit loop, show continually the measuread values
    while (true) {
        // allocate space to the measured values, (x,y,z) coordinates, high byte (h prefix), low byte (l prefix)
        char hx, lx, hz, lz, hy, ly;
        // receive data output X MSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        hx = UCB0RXBUF; // load data from buffer to local memory
        // receive data output X LSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        lx = UCB0RXBUF; // load data from buffer to local memory
        // receive data output Z MSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        hz = UCB0RXBUF; // load data from buffer to local memory
        // receive data output Z LSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        lz = UCB0RXBUF; // load data from buffer to local memory
        // receive data output Y MSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        hy = UCB0RXBUF; // load data from buffer to local memory
        // receive data output Y LSB register
        while (!(IFG2 & UCB0RXIFG) ); // wait UCBxRXIFG are set, when set read buffer are full
        ly = UCB0RXBUF; // load data from buffer to local memory
        // compose (x, y, z) values
        short x, y, z;
        x = (static_cast<short>(hx) << 8) | lx; // compose x MSB and LSB
        z = (static_cast<short>(hz) << 8) | lz; // compose z MSB and LSB
        y = (static_cast<short>(hy) << 8) | ly; // compose y MSB and LSB
        //print (x, y, z) measured values
        print("( ");
        print(x);
        print(", ");
        print(y);
        print(", ");
        print(z);
        print(" )");
        print("\r\n");
    }
}
void configureDCO() {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    // Set DCO to 1MHz
    BCSCTL1 = CALBC1_1MHZ;
    DCOCTL = CALDCO_1MHZ;
    __delay_cycles(1000000);
}
void configureUART() {
    UCA0CTL1 |= UCSWRST; // put USCI in reset mode
    // P1.1 = RXD, P1.2=TXD
    P1SEL  |= BIT1 | BIT2;
    P1SEL2 |= BIT1 | BIT2;
    UCA0CTL1 |= UCSSEL_3; // Use SMCLK
    // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13) 1MHz / 104
    UCA0BR0 = 104;
    UCA0BR1 = 0;
    UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1, correction for the fractional part ( the rest, 9600 - 1MHz / 104)
    UCA0CTL1 &= ~UCSWRST; // put USCI in operad mode (removing reset mode)
    /*End configuration hardware UART */
    print("[system] uart configured\r\n");
};
    
void putc(char ch) {
    while(!(IFG2 & UCA0TXIFG));
    UCA0TXBUF = ch;
}
void print (const char msg[]) {
    for (int i = 0; msg[i] != '\0'; ++i)
        putc(msg[i]);  
}
void print (short value) {
    if (value == 0) { putc('0'); return; }
    if (value < 0) {
        putc('-');
        value *= -1;
    }
    unsigned int size;
    char buffer[20];
    for (size = 0; value; ++size, value /= 10)
        buffer[size] = value % 10;
    while (size)
        putc(buffer[--size] + '0');
}
void printStatus() {
    print("Status:\n\r");
    #define __PRINT_STATUS(X, MSG) if (UCB0STAT & X) print(#MSG "! ");
    __PRINT_STATUS(UCNACKIFG, nack);
    __PRINT_STATUS(UCALIFG, arbitration lost);
    __PRINT_STATUS(UCGC, receive general call);
    __PRINT_STATUS(UCBBUSY, bus busy);
    __PRINT_STATUS(UCSCLLOW, SCL low);
    __PRINT_STATUS(UCSTPIFG, stop received);
    __PRINT_STATUS(UCSTTIFG, start received);
    print("done\n\r");
}

Please this is a old problem, someone can helpme?

David Kennedy S. Araujo

Computer Engineering Student (PUC GO)

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...