AnsweredAssumed Answered

interrupt and dma for i2c - stm32f4 discovery

Question asked by armoun.mohamad on Apr 11, 2014
hi guys ,  i wrote  program and it works, and i can gather the data of adxl345(accelerometer) in each axis. but i think for more optimization and make may micro more free it would be better to use INTERRUPT and DMA for i2c , do any body knows something about interrupt and dma in i2c.
any idea would be grate , thanks


here is my code :


i2c for communication with adxl345 accelerometer using discovery boar(STM32F407VG) PB6-PB7    --- mohamad_armoon@yahoo.com
 
#include <stm32f4xx.h>
#define DEVICE (0x53)
 
 
/******************************/
char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
/******************************/
 
 
void Delay(__IO uint32_t nCount);
void init_usart(void);
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction);
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
void I2C_stop(I2C_TypeDef* I2Cx);
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx);
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx);
void inti_RCC()
{
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        /******************************************************/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
}
void LED_STATUS()
{
  GPIO_InitTypeDef GPIO_InitStructure;
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
 
}
 
void init_I2C1(void){
 
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStruct;
 
     
 
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // we are going to use PB6 and PB7
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;           // set pins to alternate function
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;      // set GPIO speed
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;         // set output to open drain --> the line has to be only pulled low, not driven high
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;           // enable pull up resistors
    GPIO_Init(GPIOB, &GPIO_InitStruct);                 // init GPIOB
 
    // Connect I2C1 pins to AF 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); // SCL
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA
 
    // configure I2C1
        I2C_DeInit(I2C1);
    I2C_InitStruct.I2C_ClockSpeed = 100000;         // 100kHz
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;         // I2C mode
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standard
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;          // own address, not relevant in master mode
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;        // disable acknowledge when reading (can be changed later on)
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
    I2C_Init(I2C1, &I2C_InitStruct);                // init I2C1
 
    // enable I2C1
    I2C_Cmd(I2C1, ENABLE);
        //DMA_Cmd(DMA1_Stream5,ENABLE);
        //DMA_Cmd(
}
 
void writeTo(uint8_t address,uint8_t value)
{
  I2C_start(I2C1, 0xA6, I2C_Direction_Transmitter);
  I2C_write(I2C1,address);
  I2C_write(I2C1,value);
  I2C_stop(I2C1);
}
 
void setup()
{
   writeTo(DATA_FORMAT, 0x01);
   writeTo(POWER_CTL, 0x08);
}
 
uint8_t buffer[10];
void ReadFromAccel(uint8_t address)
{
  I2C_start(I2C1, 0xA6 , I2C_Direction_Transmitter);
  I2C_write(I2C1,address);
  I2C_stop(I2C1);
}

 
 
int main()
{
  inti_RCC();
  LED_STATUS();
 
  init_I2C1();
  init_usart();
  setup();
    GPIO_SetBits(GPIOD, GPIO_Pin_12);
     
      
  while(1)
  {
    ReadFromAccel(DATAX0);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    buffer[0] = I2C_read_nack(I2C1);
    USART_SendData(USART2,'*');
    Delay(0xFFFF);
    USART_SendData(USART2,buffer[0]);
     
 
    ReadFromAccel(DATAX1);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    buffer[1] = I2C_read_nack(I2C1);
    USART_SendData(USART2,buffer[1]);
    Delay(0xFFFFa);
     
    /*******************************************/
     
    ReadFromAccel(DATAY0);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    buffer[0] = I2C_read_nack(I2C1);;
    USART_SendData(USART2,buffer[0]);
     
 
    ReadFromAccel(DATAY1);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    I2C_memory = I2C_read_nack(I2C1);
    USART_SendData(USART2,I2C_memory);
    Delay(0xFFFFa);
     
/*********************************************/   
     
   ReadFromAccel(DATAZ0);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    I2C_memory = I2C_read_nack(I2C1);
    USART_SendData(USART2,I2C_memory);
  
    ReadFromAccel(DATAZ1);
    I2C_start(I2C1,0xA7 , I2C_Direction_Receiver);
    I2C_memory = I2C_read_nack(I2C1);
    //I2C_stop(I2C1);
    USART_SendData(USART2,I2C_memory);
    Delay(0xFFFFa);
     
  }
}
 
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction)
{
  while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
   
        // Send I2C1 START condition
    I2C_GenerateSTART(I2Cx, ENABLE);
    // wait until I2C1 is not busy anymore
     
     
 
    // wait for I2C1 EV5 --> Slave has acknowledged start condition
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
 
    // Send slave Address for write
    I2C_Send7bitAddress(I2Cx, address, direction);
       // I2C_AcknowledgeConfig(I2C1, ENABLE);
    /* wait for I2C1 EV6, check if
     * either Slave has acknowledged Master transmitter or
     * Master receiver mode, depending on the transmission
     * direction
     */
        if(direction == I2C_Direction_Transmitter){
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
                GPIO_SetBits(GPIOD, GPIO_Pin_13);
    }
    else if(direction == I2C_Direction_Receiver){
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    }
}
 
 
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
    I2C_SendData(I2Cx, data);
         
    // wait for I2C1 EV8_2 --> byte has been transmitted
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
 
void I2C_stop(I2C_TypeDef* I2Cx)
{
    // Send I2C1 STOP Condition
    I2C_GenerateSTOP(I2Cx, ENABLE);
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
    // disable acknowledge of received data
    // nack also generates stop condition after last byte received
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
    I2C_GenerateSTOP(I2Cx, ENABLE);
    // wait until one byte has been received
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    // read data from I2C data register and return data byte
    uint8_t data = I2C_ReceiveData(I2Cx);
    return data;
}
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
    // enable acknowledge of recieved data
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    // wait until one byte has been received
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    // read data from I2C data register and return data byte
    uint8_t data = I2C_ReceiveData(I2Cx);
    return data;
}
 
 
 
void init_usart(void){
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
       
     
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
     
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
 
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure);
 
    USART_Cmd(USART2, ENABLE);
 
}
void Delay(__IO uint32_t nCount)
{
  while(nCount--)
  {
     
  }
}

Outcomes