Trying to read data from accelerometer (MMA7660) with an LPC1343

Discussion in 'Embedded Systems and Microcontrollers' started by Biestly, May 29, 2014.

  1. Biestly

    Thread Starter New Member

    May 29, 2014
    1
    0
    Hello community,

    I'm working on my school project and therefor as the title says I'm trying to read data from the MMA7660 accelerometer with an LPC1343 over I2C connection.

    The project is about reading out the data of accelerometer and show the values with LEDs so that the uC-Board works as a level.

    I have everything configured as said in the data sheet and I also make the process for reading data over I2C (STA-Bit -> address... and so on).

    When I want to try it out the program is always stocked in the second while after sending the slave address of the accelerometer.
    Don't wonder, I use some of the LEDs for debugging :p
    I recognized that the status-byte after sending the slave address is 0... but thats not good...

    Can anyone of you help me out her?
    Thanks a lot!

    Here is the code:

    Code ( (Unknown Language)):
    1.  
    2. /*
    3.  * file Wasserwaage_LPC_1343
    4.  * author Patrick Gröller
    5.  * brief program the accelerator to show tha g-status with LEDs
    6.  * date 19-05-2014
    7.  */
    8.  
    9. //Accelerator slave adress = 0x4C
    10.  
    11. #include <LPC13xx.h>
    12. #include <type.h>
    13.  
    14. #define LATCH_EN (1<<2)
    15. #define LED1     (1<<4)  /* PIO1_4  */
    16. #define LED2     (1<<5)  /* PIO1_5  */
    17. #define LED3     (1<<6)  /* PIO1_6  */
    18. #define LED4     (1<<7)  /* PIO1_7  */
    19. #define LED5     (1<<8)  /* PIO1_8  */
    20. #define LED6     (1<<9)  /* PIO1_9  */
    21. #define LED7     (1<<10) /* PIO1_10 */
    22. #define LED8     (1<<11) /* PIO1_11 */
    23.  
    24. #define LED_GREEN_ENB (1<<0)
    25. #define LED_RED_EN    (1<<2)
    26.  
    27. #define MMA7660_DevAdr  0x4C
    28. #define MMA7660_XValue  0x00
    29.  
    30. volatile uint8_t I2CMasterBuffer[7];
    31.  
    32. void blinkDebug(int blinkanz, unsigned char LEDMask)
    33. {
    34.     int i, cnt;
    35.    
    36.     for (i=0; i<blinkanz; i++)
    37.     {
    38.         LPC_GPIO1->DATA |= LEDMask;
    39.         for(cnt=0;cnt<=3000000;cnt++);
    40.         LPC_GPIO1->DATA &= ~LEDMask;
    41.         for(cnt=0;cnt<=3000000;cnt++);
    42.     }
    43.    
    44. }
    45.  
    46. void LED_Config(void)
    47. {
    48.     SystemInit();                               /* Initialize clocks          */
    49.     LPC_IOCON->JTAG_nTRST_PIO1_2 |= (1<<0);     /* configure LED_RED_EN as IO pin */
    50.    
    51.     /* configure the direction of several IO pins */
    52.     LPC_GPIO3->DIR = LATCH_EN;
    53.     LPC_GPIO1->DIR = (LED_RED_EN | LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);
    54.     LPC_GPIO2->DIR = LED_GREEN_ENB;
    55.    
    56.     LPC_GPIO3->DATA = LATCH_EN;                 /* enable the Latch                   */
    57.     //LPC_GPIO2->DATA &= ~(LED_GREEN_ENB);      /* disable the Green LEDs - low active */
    58.     LPC_GPIO1->DATA |= (LED_RED_EN);            /* enable the Red LEDs - high active  */
    59.    
    60.     /* all other LEDs -> off */
    61.     LPC_GPIO1->DATA &= ~(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);
    62.    
    63.     blinkDebug(3, 0x010);   //DEBUG
    64. }
    65.  
    66. void I2C_Init(void)
    67. {
    68.     LPC_IOCON->PIO0_4 |= 0x00000001;
    69.     LPC_IOCON->PIO0_5 |= 0x00000001;
    70.    
    71.     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);    //Clock enable for I2C
    72.     LPC_SYSCON->PRESETCTRL |= (1<<1);       //de-asserts reset signal to I2C
    73.  
    74.     LPC_I2C->CONCLR = (1<<2);   /* Assert acknowledge Clear bit */
    75.     LPC_I2C->CONCLR = (1<<3);   /* I2C interrupt Clear bit */
    76.     LPC_I2C->CONCLR = (1<<5);   /* START flag clear */
    77.     LPC_I2C->CONSET = (1<<6);   /* I2C enable */
    78.    
    79.     blinkDebug(3, 0x020);   //DEBUG
    80. }
    81.  
    82. unsigned char readData_I2C(unsigned char addr, unsigned reg, unsigned data)
    83. {
    84.     int cnt;
    85.    
    86.     //MASTER transmitter mode
    87.     LPC_I2C->CONSET |= (1<<5);              /*  START condition */
    88.    
    89.     LPC_GPIO1->DATA |= LED8;   //DEBUG
    90.     for(cnt=0;cnt<=5000000;cnt++);  //DEBUG
    91.     while(!(LPC_I2C->CONSET & (1<<3)));     /* wait for SI Bit, till bus is free */
    92.     if (LPC_I2C->STAT != 0x08)              /* Status 0x08 bedeutet START condiction empfangen*/
    93.         return 11;  /* FALSE */
    94.     LPC_GPIO1->DATA &= ~LED8;    //DEBUG
    95.    
    96.     LPC_I2C->CONCLR = (1<<3);       /* Set SIC Bit for clearing SI in CONSET */
    97.    
    98.     LPC_I2C->DAT = (addr<<1);               /* slave address + 8. bit = 0 (8. Bit ist für R=1/W=0)*/
    99.    
    100.     LPC_GPIO1->DATA |= LED7;   //DEBUG
    101.     for(cnt=0;cnt<=5000000;cnt++);  //DEBUG
    102.     while(!(LPC_I2C->CONSET & (1<<3))); /* wait for interrupt (ACK Adresse + Write) */
    103.     if (LPC_I2C->STAT != 0x01)      /* Status 0x18 bedeutet Slave-Address + W empfangen!*/
    104.         LPC_GPIO1->DATA &= ~(LED1 | LED2 | LED3 | LED4 | LED5 | LED6 | LED7 | LED8);
    105.         LPC_GPIO1->DATA |= ((LPC_I2C->STAT)<<1);    //DEBUG
    106.         return 22;/* FALSE */
    107.     LPC_GPIO1->DATA &= ~LED7;    //DEBUG
    108.    
    109.     LPC_I2C->CONCLR = (1<<3);       /* Set SIC Bit for clearing SI in CONSET */
    110.    
    111.     LPC_I2C->DAT = reg ;        /* register address*/
    112.    
    113.     LPC_GPIO1->DATA |= LED6;   //DEBUG
    114.     for(cnt=0;cnt<=5000000;cnt++);  //DEBUG
    115.     while(!(LPC_I2C->CONSET & (1<<3))); /* wait for SI Bit */
    116.     if (LPC_I2C->STAT != 0x28)          /* möglicher Status code:*/
    117.         return 33;/* FALSE */               /* 0x28 Data + ACK recieved*/
    118.     /* 0x30 Data NOT ACK recieved*/
    119.     LPC_GPIO1->DATA &= ~LED6;    //DEBUG
    120.    
    121.     LPC_I2C->CONSET |= (1<<5);              /*  Repeated START condition */
    122.    
    123.     LPC_GPIO1->DATA |= LED5;    //DEBUG
    124.     for(cnt=0;cnt<=5000000;cnt++);  //DEBUG
    125.     while(!(LPC_I2C->CONSET & (1<<3)));     /* wait for SI Bit, till bus is free */
    126.     if (LPC_I2C->STAT != 0x10)              /* Status 0x08 bedeutet START condiction empfangen*/
    127.         return 44;  /* FALSE */
    128.     LPC_GPIO1->DATA &= ~LED5;    //DEBUG
    129.    
    130.     LPC_I2C->DAT = (addr<<1)+1 ;        /* slave address + 8. bit = 1 (8. Bit ist für R=1/W=0)*/
    131.    
    132.     LPC_I2C->CONCLR = (1<<3);           /* Set SIC Bit for clearing SI in CONSET */
    133.    
    134.     LPC_GPIO1->DATA |= LED4;    //DEBUG
    135.     for(cnt=0;cnt<=5000000;cnt++);  //DEBUG
    136.     while(!(LPC_I2C->CONSET & (1<<3))); /* wait for SI Bit (ACK Adresse + Write) */
    137.     if (LPC_I2C->STAT != 0x18)          /* möglicher Status code:*/
    138.         return 55;/* FALSE */               /* 0x40 SLA+R and ACK recieved*/
    139.     /* 0x48 SLA+R and no ACK recieved*/
    140.     LPC_GPIO1->DATA &= ~LED4;    //DEBUG
    141.    
    142.     data = LPC_I2C->DAT;
    143.    
    144.     LPC_I2C->CONCLR = (1<<3);           /* Set SIC Bit for clearing SI in CONSET */
    145.    
    146.     LPC_I2C->CONSET |= (1<<4);      /* STOP ausgeben */
    147.    
    148.     return 0;
    149. }
    150.  
    151. void I2C_IRQHandler(void){
    152.     int i = 0;
    153.     i++;
    154.    
    155.     uint8_t I2C_state;
    156.    
    157.     I2C_state = LPC_I2C->STAT; /* recent state */
    158.    
    159.     switch (I2C_state) {
    160.            
    161.         case 0x08:      /* a start condition is issued */
    162.             LPC_I2C->DAT = I2CMasterBuffer[0];
    163.             LPC_I2C->CONCLR = (1<<3) | (1<<5);   //interrupt clear bit & START flag clear bit
    164.             break;
    165.            
    166.         default:
    167.             LPC_I2C->CONCLR = (1<<3);    //Interrupt clear bit
    168.             break;
    169.     }
    170. }
    171.  
    172. int main (void)
    173. {
    174.     LED_Config();
    175.     I2C_Init();
    176.     unsigned char sensorValue = 0;
    177.     unsigned char I2C_Stat;
    178.    
    179.     while(1)
    180.     {
    181.         I2C_Stat = readData_I2C(MMA7660_DevAdr, MMA7660_XValue, sensorValue);
    182.        
    183.         if(I2C_Stat == 0 && sensorValue > 0)
    184.             LPC_GPIO1->DATA |= (LED1 | LED2);
    185.         //else
    186.           //  LPC_GPIO1->DATA |= (LED7 | LED8 | LED5);
    187.     }
    188.  
    189. }
    190.  
     
    Last edited by a moderator: May 29, 2014
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    Well THAT is a problem. If the slave doesn't ACK then it is not part of the transaction, and you can stop right there.

    I tried to check your readData_I2C() function but there is too much for me to understand there as I'm not familiar with the processor you are running.

    Sending the first slave address is crutial, what typically goes wrong is it gets shifted over a bit as the first byte is a 7 bit address and 1 read/write bit. Some manufacturers give the address as 7 bits, some as 8. Same with I2C library authors: some use 7 bits, some use 8.

    One good thing is I2C has no minimum speed, meaning you can send out a bit per hour and read the full bus transaction with a voltmeter or even a LED ;-).

    First off, keep working at that first ACK, nothing will work till that is there.
     
Loading...