AnsweredAssumed Answered

STM32F0 I2C AND UART SIMULTANEOUSLY

Question asked by R V on Sep 16, 2017
Latest reply on Sep 21, 2017 by R V

Hi All,

I am trying to interface a digital(I2C) pressure sensor with STM32F051R8T6(STM32F0 Discovery board). I basically want to read data from the sensor and display it on a serial terminal software(USB to TTL converter) using UART(to check the sensor). I tried UART first and was successful to send strings and display the same on terminal software. But, when I added the I2C part I couldn't send even a character through UART. What am I doing wrong here? or are there any other robust methods for this application.

Note:

1) I am using STANDARD PERIPHERAL LIBRARY

2) Pressure sensor address: 0x28

3) I2C on PB6 (SCL) & PB7 (SDA)

4) UART Rx (PA10) & Tx (PA9)

 

CODE:

 

 

//Includes
#include <stm32f0xx.h>
#include <stm32f0xx_gpio.h>
#include <stm32f0xx_i2c.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_usart.h>

 


//Declarations
#define PS_I2C I2C1
#define PS_PORT    GPIOB
#define PS_SCL GPIO_Pin_6
#define PS_SDA GPIO_Pin_7
#define PS_PIN_AF GPIO_AF_1
#define PS_ADDR (0x28)

 

 

//Private variables
int8_t Data[2] = {0,0};

 

//Function declaration
void gpio_init(void)
{
    GPIO_InitTypeDef GPIO;

 

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

 

    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);

 

    GPIO.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO.GPIO_Mode = GPIO_Mode_AF;
    GPIO.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO.GPIO_OType = GPIO_OType_PP;
    GPIO.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA,&GPIO);
}

 

void usart_init(void)
{
    USART_InitTypeDef USART;

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

 

    USART.USART_BaudRate = 115200;
    USART.USART_WordLength = USART_WordLength_8b;
    USART.USART_StopBits = USART_StopBits_1;
    USART.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART.USART_Parity = USART_Parity_No;
    USART.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

    USART_Init(USART1,&USART);
    //enable USART
    USART_Cmd(USART1,ENABLE);
}

 

char SendByte(uint8_t c)
{
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    USART_SendData(USART1,c);
}

 

void SendPacket(uint8_t *data, uint16_t length)
{
    uint16_t i;
    i = 0;
    while(i<length)
    {
        SendByte(data[i]);
        i++;
    }
}

 

 

 

void USART_clearscreen(void)
{
  char cmd1[5] = {0x1B, '[', '2', 'J', '\0'}; // Clear screen
  char cmd2[4] = {0x1B, '[', 'f', '\0'}; // Cursor home

 

  SendPacket(cmd1,5);
  SendPacket(cmd2,4);
}


// I2C setup for pressure sensor


void PSensor_Setup(void)
{
    GPIO_InitTypeDef GPIO;
    I2C_InitTypeDef I2C;

 

    //Set I2C1 clock to SYSCLK
    RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);

 

    //enable peripheral clock for I2C1 on APB1
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);

 

    //enable SDA, SCL and SMBA(if used) GPIO clocks
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);

 

    //Peripheral alternate function configuration
    GPIO_PinAFConfig(PS_PORT,PS_SCL,GPIO_AF_1);
    GPIO_PinAFConfig(PS_PORT,PS_SDA,GPIO_AF_1);

 

    //Configure the GPIO as per I2C requirement
    GPIO.GPIO_Pin = PS_SCL | PS_SDA;
    GPIO.GPIO_Mode = GPIO_Mode_AF;
    GPIO.GPIO_OType = GPIO_OType_OD;
    GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(PS_PORT,&GPIO);

 

    //I2C configuration
    I2C.I2C_Ack = I2C_Ack_Enable;
    I2C.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
    I2C.I2C_DigitalFilter = 0;
    I2C.I2C_Mode = I2C_Mode_I2C;
    I2C.I2C_OwnAddress1 = 0;
    I2C.I2C_Timing = 0x00310309;
    I2C_Init(PS_I2C,&I2C);

 

    //Enable I2C
    I2C_Cmd(PS_I2C,ENABLE);
}

 

// Function to read from pressure sensor

uint8_t Read_PSensor()
{
    char cNoOfBytes = 0;

 

    //Check if I2C peripheral isn't busy
    while(I2C_GetFlagStatus(PS_I2C,I2C_FLAG_BUSY) == SET);

 

    //Start I2C Read transfer for 1 byte, do not end transfer(SoftEnd_Mode)
    I2C_TransferHandling(PS_I2C,PS_ADDR,2,I2C_AutoEnd_Mode,I2C_Generate_Start_Read);

 

    //Read 2 bytes of data
    for(cNoOfBytes = 0; cNoOfBytes<2; cNoOfBytes++)
    {
        //Wait until RX register is full of data
        while(I2C_GetFlagStatus(PS_I2C,I2C_FLAG_RXNE) == RESET);

 

        //store in array "Data" pointer called from main
        Data[cNoOfBytes] = I2C_ReceiveData(PS_I2C);
    }

 

    //wait for the stop condition to be sent
    while(I2C_GetFlagStatus(PS_I2C,I2C_FLAG_STOPF) == RESET);

 

    //clear the stop flag for further transfers
    I2C_ClearFlag(PS_I2C,I2C_FLAG_STOPF);
    return 0;
}

 


int main(void)
{
    gpio_init();
    usart_init();
    PSensor_Setup();
    USART_clearscreen();
    int8_t FirstByte = 0;
    int8_t SecondByte = 0;

 

    while(1)
    {
        Read_PSensor();
        FirstByte = (Data[0]);

        SecondByte = (Data[1]);
        SendPacket("FirstByte: ",13);
        SendPacket(FirstByte,13);
        SendByte('\n');
        SendPacket("SecondByte: ",13);

        SendPacket(SecondByte,13);
        SendByte('\n');

        for(int i = 0; i<50000; i++);         //delay after one reading
    }
}

Outcomes