Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

msp430g2553 i2c problem with hmc5883l magnetometer (GY-273)

$
0
0

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)


Viewing all articles
Browse latest Browse all 2077

Trending Articles