0% found this document useful (0 votes)
72 views

#Include #Include #Include #Include #Include

This document defines functions for initializing and communicating over an I2C interface on an STM32 microcontroller. It initializes I2C1 and GPIO pins for I2C communication at 100kHz. It then defines functions for sending a start condition, writing and reading single bytes to/from a slave device, and sending a stop condition to release the I2C bus. These functions are used in main() to transmit one byte to and receive one byte from an I2C slave device with the address 0x4A.

Uploaded by

shiva1lu
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views

#Include #Include #Include #Include #Include

This document defines functions for initializing and communicating over an I2C interface on an STM32 microcontroller. It initializes I2C1 and GPIO pins for I2C communication at 100kHz. It then defines functions for sending a start condition, writing and reading single bytes to/from a slave device, and sending a stop condition to release the I2C bus. These functions are used in main() to transmit one byte to and receive one byte from an I2C slave device with the address 0x4A.

Uploaded by

shiva1lu
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 4

#include

#include
#include
#include
#include

"stm32f0xx_i2c.h"
"i2c.h"
"stm32f0xx.h"
"stm32f0xx_rcc.h"
"stm32f0xx_gpio.h"

// this slave address belongs to the STM32F4-Discovery board's


// CS43L22 Audio DAC
// connect PD4 to VDD in order to get the DAC out of reset and test the
I2C
// interface
#define SLAVE_ADDRESS 0x4A // the slave address (example)
void I2C1_init(void){
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
// enable APB1 peripheral clock for I2C1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// enable clock for SCL and SDA pins
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* setup SCL and SDA pins
* You can connect the I2C1 functions to two different
* pins:
* 1. SCL on PB6 or PA9
* 2. SDA on PB7 or PA10
*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // we are
going to use PB6 and PB9
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(GPIOA, &GPIO_InitStruct);
// init GPIOB
// Connect I2C1 pins to AF
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_I2C1);
// SCL

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_I2C1); // SDA


// configure 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_Disable;
//
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);

/* This function issues a start condition and


* transmits the slave address + R/W bit
*
* Parameters:
*
I2Cx --> the I2C peripheral e.g. I2C1
*
address --> the 7 bit slave address
*
direction --> the transmission direction can be:
*
I2C_Direction_Tranmitter for Master transmitter mode
*
I2C_Direction_Receiver for Master receiver
*/
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
// wait until I2C1 is not busy any more
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
// Send I2C1 START condition
I2C_GenerateSTART(I2Cx, ENABLE);
// 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);
/* wait for I2Cx 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));
}
else if(direction == I2C_Direction_Receiver){
while(!I2C_CheckEvent(I2Cx,
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
}
}

/* This function transmits one byte to the slave device


* Parameters:
*
I2Cx --> the I2C peripheral e.g. I2C1
*
data --> the data byte to be transmitted
*/
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
// wait for I2C1 EV8 --> last byte is still being transmitted
(last byte in SR, buffer empty), next byte can already be written
while(!I2C_CheckEvent(I2Cx,
I2C_EVENT_MASTER_BYTE_TRANSMITTING));
I2C_SendData(I2Cx, data);
}
/* This function reads one byte from the slave device
* and acknowledges the byte (requests another byte)
*/
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
// enable acknowledge of received 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;
}
/* This function reads one byte from the slave device
* and doesn't acknowledge the received data
* after that a STOP condition is transmitted
*/
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
// disable acknowledge of received data
// nack also generates stop condition after last byte received
// see reference manual for more info
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;
}
/* This function issues a stop condition and therefore
* releases the bus
*/
void I2C_stop(I2C_TypeDef* I2Cx){
// Send I2C1 STOP Condition after last byte has been transmitted
I2C_GenerateSTOP(I2Cx, ENABLE);
// wait for I2C1 EV8_2 --> byte has been transmitted
while(!I2C_CheckEvent(I2Cx,

I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
int main(void){
I2C1_init(); // initialize I2C peripheral
uint8_t received_data;
I2C_start(I2C1,
// start a transmission
I2C_write(I2C1,
I2C_stop(I2C1);

SLAVE_ADDRESS<<1, I2C_Direction_Transmitter);
in Master transmitter mode
0x01); // write one byte to the slave
// stop the transmission

I2C_start(I2C1, SLAVE_ADDRESS<<1, I2C_Direction_Receiver); //


start a transmission in Master receiver mode
received_data = I2C_read_nack(I2C1); // read one byte and don't
request another byte, stop transmission
while(1);
return 0;
}

You might also like