Difference between revisions of "STM32F107VC/Using I²C"
From Teknologisk videncenter
m (→Software Examples) |
m (→Links) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=Keil MCBSTM32C board= | =Keil MCBSTM32C board= | ||
I²C bus connected to [[STM32F107VC]] [[STM32F107VC/GPIO|GPIO]] Port B SDA (Data) on pin 9 and SCL (Clock) on pin 8. | I²C bus connected to [[STM32F107VC]] [[STM32F107VC/GPIO|GPIO]] Port B SDA (Data) on pin 9 and SCL (Clock) on pin 8. | ||
+ | =I²C Operation= | ||
+ | *[[Media:I2C.pdf|I2C]] (Loads PDF - in danish) | ||
==Peripheral Addresses== | ==Peripheral Addresses== | ||
*[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00259166.pdf M24C64] EEPROM (Loads PDF) on Slave address 0x0 | *[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00259166.pdf M24C64] EEPROM (Loads PDF) on Slave address 0x0 | ||
*[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00135460.pdf LIS302DL] 3 Axis motion Sensor (Loads PDF) on Slave address 0x1C | *[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00135460.pdf LIS302DL] 3 Axis motion Sensor (Loads PDF) on Slave address 0x1C | ||
+ | *[http://www.cirrus.com/en/pubs/proDatasheet/CS42L52_F1.pdf CS42L52] Stereo CODEC (Loads PDF) on Slave address 0x94 | ||
+ | |||
==Software Examples== | ==Software Examples== | ||
*[http://mars.tekkom.dk/data/MotionSensor1.zip MotionSensor1.zip] (Not yet functional. Code works from Cold Reset - but not from Warm Reset) | *[http://mars.tekkom.dk/data/MotionSensor1.zip MotionSensor1.zip] (Not yet functional. Code works from Cold Reset - but not from Warm Reset) | ||
<source lang=c> | <source lang=c> | ||
− | |||
− | |||
− | |||
/******************************************************************************* | /******************************************************************************* | ||
* I2C communication status * | * I2C communication status * | ||
Line 36: | Line 37: | ||
/* Enable clock for I2C1, GPIOB and AFIO */ | /* Enable clock for I2C1, GPIOB and AFIO */ | ||
− | |||
RCC->APB2ENR |= (1 << 3) | (1 << 0); // | RCC->APB2ENR |= (1 << 3) | (1 << 0); // | ||
RCC->APB1ENR |= (1 << 21); | RCC->APB1ENR |= (1 << 21); | ||
Line 49: | Line 49: | ||
/* Configure I2C peripheral */ | /* Configure I2C peripheral */ | ||
− | I2C1->CR1 = 0x0001; // PE - Peripheral Enable | + | I2C1->CR1 = 0x0001; // PE - Peripheral Enable |
− | I2C1->CR2 = 0x0024; | + | I2C1->CR2 = 0x0024; // Freq 36 MHz |
− | I2C1->CR1 = 0x0000; // PE Disable | + | I2C1->CR1 = 0x0000; // PE Disable |
− | I2C1->TRISE = 0x0025; | + | I2C1->TRISE = 0x0025; //Time Rise - program when PE=0 |
− | I2C1->CCR = 0x00B4; | + | I2C1->CCR = 0x00B4; // 0x005A = 400 KHz (36MHz / 90) 0x00B4 = 200 KHz |
I2C1->CR1 |= 0x0401; | I2C1->CR1 |= 0x0401; | ||
I2C1->OAR1 = 0x40A0; | I2C1->OAR1 = 0x40A0; | ||
− | |||
− | |||
− | |||
− | |||
} | } | ||
Line 147: | Line 143: | ||
} | } | ||
+ | unsigned short int I2C_getword(unsigned char address, unsigned char cmd) { | ||
+ | unsigned short int uw; | ||
+ | //unsigned short int uw2; | ||
+ | I2C_Start(); // Initial Start bit sequence | ||
+ | I2C_Addr(address); // Address I2C Device. (Base address is Write Address) | ||
+ | I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read) | ||
+ | I2C_Start(); // Repeated start bit sequence | ||
+ | I2C_Addr(address+1); // Address I2C Device. (Base address + 1 is Read Address) | ||
+ | uw = I2C_Read(1) << 8; // Read MSB without Acknowledge | ||
+ | uw |= I2C_Read(0); // Read LSB with Acknowledge | ||
+ | I2C_Stop(); // Stop I2C transfer | ||
+ | return( uw ); | ||
+ | } | ||
void I2C_putbyte(unsigned char address, unsigned char cmd, unsigned char data) { | void I2C_putbyte(unsigned char address, unsigned char cmd, unsigned char data) { | ||
I2C_Start(); // Initial Start bit sequence | I2C_Start(); // Initial Start bit sequence | ||
Line 153: | Line 162: | ||
I2C_Write(data); // Transfer Data to I2C device | I2C_Write(data); // Transfer Data to I2C device | ||
I2C_Stop(); // Stop I2C transfer | I2C_Stop(); // Stop I2C transfer | ||
+ | } | ||
+ | |||
+ | int I2C_getbytearray(unsigned char address, unsigned char cmd, int number, unsigned char *data) { | ||
+ | int count; | ||
+ | I2C_Start(); // Initial Start bit sequence | ||
+ | I2C_Addr(address); // Address I2C Device. (Base address is Write Address) | ||
+ | I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read) | ||
+ | I2C_Start(); // Repeated start bit sequence | ||
+ | I2C_Addr(address+1); // Address I2C Device. (Base address + 1 is Read Address) | ||
+ | // Read number - 1 bytes with Acknowledge | ||
+ | for ( count=0; count < number - 2; count++ ) { | ||
+ | data[count] = I2C_Read(1); // Read with Acknowledge | ||
+ | } | ||
+ | data[count] = I2C_Read(0); // Last byte without Acknowledge | ||
+ | I2C_Stop(); // Stop I2C transfer | ||
+ | return( count+1 ); | ||
} | } | ||
</source> | </source> | ||
Line 158: | Line 183: | ||
=Links= | =Links= | ||
*[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00209826.pdf STM32F10xxx I2C optimized examples] Application Note (Loads PDF) | *[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00209826.pdf STM32F10xxx I2C optimized examples] Application Note (Loads PDF) | ||
+ | *[http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/i2c-bus.html Articles regarding I²C] | ||
+ | [[Category:Elektronik]][[Category:Embedded]][[Category:ARM]] |
Latest revision as of 09:34, 3 January 2012
Contents
Keil MCBSTM32C board
I²C bus connected to STM32F107VC GPIO Port B SDA (Data) on pin 9 and SCL (Clock) on pin 8.
I²C Operation
- I2C (Loads PDF - in danish)
Peripheral Addresses
- M24C64 EEPROM (Loads PDF) on Slave address 0x0
- LIS302DL 3 Axis motion Sensor (Loads PDF) on Slave address 0x1C
- CS42L52 Stereo CODEC (Loads PDF) on Slave address 0x94
Software Examples
- MotionSensor1.zip (Not yet functional. Code works from Cold Reset - but not from Warm Reset)
/*******************************************************************************
* I2C communication status *
* Parameter: *
* Return: status *
*******************************************************************************/
static __inline unsigned int I2C_sr (void) {
unsigned int sr;
sr = I2C1->SR1;
sr |= I2C1->SR2 << 16;
return (sr);
}
/************************ Exported functions **********************************/
/*******************************************************************************
* Initialize I2C interface in master mode *
* Parameter: *
* Return: *
*******************************************************************************/
void I2C_Init (void) {
unsigned int tout;
/* Enable clock for I2C1, GPIOB and AFIO */
RCC->APB2ENR |= (1 << 3) | (1 << 0); //
RCC->APB1ENR |= (1 << 21);
/* I2C1 pins remapped, use PB8, PB9 */
AFIO->MAPR |= 0x00000002; // Remap=1: (SCL/PB8, SDA/PB9)
GPIOB->CRH |= 0x000000FF; // Alternate IO PB8 and PB9
I2C1->CR1 = 0x8000; /* Reset I2C peripheral */
for (tout = 1000000; tout; tout--);
I2C1->CR1 = 0x0000;
/* Configure I2C peripheral */
I2C1->CR1 = 0x0001; // PE - Peripheral Enable
I2C1->CR2 = 0x0024; // Freq 36 MHz
I2C1->CR1 = 0x0000; // PE Disable
I2C1->TRISE = 0x0025; //Time Rise - program when PE=0
I2C1->CCR = 0x00B4; // 0x005A = 400 KHz (36MHz / 90) 0x00B4 = 200 KHz
I2C1->CR1 |= 0x0401;
I2C1->OAR1 = 0x40A0;
}
/*******************************************************************************
* Generate start condition on I2C bus *
* Parameter: *
* Return: *
*******************************************************************************/
void I2C_Start (void) {
if ( I2C1->CR1 & ( 1 << 10 ) ) {
I2C1->CR1 &= ~(1 << 10 );
}
I2C1->CR1 |= 0x0100; //start genneration when bus free
while (!(I2C_sr() & 0x0001));
}
/*******************************************************************************
* Generate stop condition on I2C bus *
* Parameter: *
* Return: *
*******************************************************************************/
void I2C_Stop (void) {
I2C1->CR1 |= 0x0200;
while (I2C_sr() & 0x00020000); /* Wait until BUSY bit reset */
}
/*******************************************************************************
* Write address on I2C interface *
* Parameter: adr: address to be written *
* Return: *
*******************************************************************************/
void I2C_Addr (unsigned char adr) {
I2C1->DR = adr;
while (!(I2C_sr() & 0x0002)); //Addr sent
}
/*******************************************************************************
* Write a byte to I2C interface *
* Parameter: c: data to be written *
* Return: *
*******************************************************************************/
void I2C_Write (unsigned char c) {
I2C1->DR = c;
while (!(I2C_sr() & 0x00000004)); /* Wait until BTF bit set */
}
/*******************************************************************************
* Read a byte from I2C interface *
* Parameter: *
* Return: read data *
*******************************************************************************/
unsigned char I2C_Read (int ack) {
/* Enable/disable Master acknowledge */
if (ack) I2C1->CR1 |= 0x0400;
else I2C1->CR1 &= ~0x0400;
while (!(I2C_sr() & 0x00000040)); /* Wait until RxNE bit set */
return (I2C1->DR);
}
/******************************************************************************/
unsigned char I2C_getbyte(unsigned char address, unsigned char cmd) {
unsigned char uc;
I2C_Start(); // Initial Start bit sequence
I2C_Addr(address); // Address I2C Device. (Base address is Write Address)
I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read)
I2C_Start(); // Repeated start bit sequence
I2C_Addr(address+1); // Address I2C Device. (Base address + 1 is Read Address)
uc = I2C_Read(0); // Read 1 byte without Acknowledge
I2C_Stop(); // Stop I2C transfer
return( uc );
}
unsigned short int I2C_getword(unsigned char address, unsigned char cmd) {
unsigned short int uw;
//unsigned short int uw2;
I2C_Start(); // Initial Start bit sequence
I2C_Addr(address); // Address I2C Device. (Base address is Write Address)
I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read)
I2C_Start(); // Repeated start bit sequence
I2C_Addr(address+1); // Address I2C Device. (Base address + 1 is Read Address)
uw = I2C_Read(1) << 8; // Read MSB without Acknowledge
uw |= I2C_Read(0); // Read LSB with Acknowledge
I2C_Stop(); // Stop I2C transfer
return( uw );
}
void I2C_putbyte(unsigned char address, unsigned char cmd, unsigned char data) {
I2C_Start(); // Initial Start bit sequence
I2C_Addr(address); // Address I2C Device. (Base address is Write Address)
I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read)
I2C_Write(data); // Transfer Data to I2C device
I2C_Stop(); // Stop I2C transfer
}
int I2C_getbytearray(unsigned char address, unsigned char cmd, int number, unsigned char *data) {
int count;
I2C_Start(); // Initial Start bit sequence
I2C_Addr(address); // Address I2C Device. (Base address is Write Address)
I2C_Write(cmd); // Transfer Command to I2C Device (Register to be Read)
I2C_Start(); // Repeated start bit sequence
I2C_Addr(address+1); // Address I2C Device. (Base address + 1 is Read Address)
// Read number - 1 bytes with Acknowledge
for ( count=0; count < number - 2; count++ ) {
data[count] = I2C_Read(1); // Read with Acknowledge
}
data[count] = I2C_Read(0); // Last byte without Acknowledge
I2C_Stop(); // Stop I2C transfer
return( count+1 );
}
Links
- STM32F10xxx I2C optimized examples Application Note (Loads PDF)
- Articles regarding I²C