2019-08-24 01:25 AM
Hi I'm trying to configure stm32f103 as a master to write data to slave EEPROM chip. The master generates a start condition but slave doesn't acknowledge the address ( the address is mentioned in the datasheet though )
#include "stm32f10x.h" // Device header
#define SLAVEADDR 0b10100000
void clockConfig(void);
void I2CInit(void);
void sendByte(uint8_t mem_addr, uint8_t data);
void delayMs(uint32_t delay);
int main(void)
{
clockConfig();
I2CInit();
sendByte(0x00, 'H');
delayMs(10);
while(1)
{
}
}
void sendByte(uint8_t mem_addr, uint8_t data)
{
I2C2->CR1 |= I2C_CR1_START; // Generate start condition
while(!(I2C2->SR1 & I2C_SR1_SB)){} // Wait until start condition is sent
I2C2->DR = SLAVEADDR;
while(!(I2C2->SR1 & I2C_SR1_ADDR)){} // Wait until address phase completes
uint32_t temp;
temp = I2C2->SR2; // Clear ADDR
I2C2->DR = mem_addr; // EEPROM internal memory address
while(!(I2C2->SR1 & I2C_SR1_TXE)){}
I2C2->DR = data; // write value to the specified EEPROM address
while(!(I2C2->SR1 & I2C_SR1_BTF)){}
I2C2->CR1 |= I2C_CR1_STOP;
}
void I2CInit(void)
{
/*
Pinout
I2C2_SCL: PB10
I2C2_SDA: PB11
*/
// Enable clock access for port B
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
// configure I2C2
// Enable clock access for I2C2
RCC->APB1ENR |= RCC_APB1ENR_I2C2EN;
I2C2->CR1 |= 36; // APB1 clock frquency
I2C2->CCR |= 180; // 100KHz standard mode
I2C2->TRISE |= 37;
I2C2->CR1 |= I2C_CR1_ACK; // Enable ACKing
/* Unlock analog filters for a possible HIGH state */
GPIOB->CRH |= GPIO_CRH_CNF10_0 | GPIO_CRH_MODE10 |
GPIO_CRH_CNF11_0 | GPIO_CRH_MODE11; // general purpose output open drains
GPIOB->ODR |= GPIO_ODR_ODR10 | GPIO_ODR_ODR11;
GPIOB->ODR &= ~(GPIO_ODR_ODR10 | GPIO_ODR_ODR11);
GPIOB->ODR |= GPIO_ODR_ODR10 | GPIO_ODR_ODR11;
/* Software reset */
I2C2->CR1 |= I2C_CR1_SWRST;
I2C2->CR1 &= ~I2C_CR1_SWRST;
/* Configure SDA and SCL as AF open drains */
GPIOB->CRH |= GPIO_CRH_CNF10 | GPIO_CRH_MODE10 |
GPIO_CRH_CNF11 | GPIO_CRH_MODE11;
I2C2->CR1 |= I2C_CR1_PE;
}
void delayMs(uint32_t delay)
{
SysTick->LOAD = 72000-1;
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_CLKSOURCE | SysTick_CTRL_ENABLE;
for ( int i = 0; i < delay; i++)
while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG)){}
}
void clockConfig(void)
{
// HSE ON
RCC->CR |= 0x1<<16;
// wait unit HSE is ready
while(!(RCC->CR & (0x1<<17))){}
// PLL OFF
RCC->CR &= ~(0x1<<24);
//HSE clock not divided
RCC->CFGR &= ~(0x1<<17);
// PLL SRC = HSE
RCC->CFGR |= 0x1<<16;
// PLL MUL, x9
RCC->CFGR &= ~(0xF<<18);
RCC->CFGR |= 0x7<<18;
// PLL ON
RCC->CR |= 0x1<<24;
// wait until PLL is ready
while(!(RCC->CR & (0x1 << 25))){}
// choose PLL as Sys clock
RCC->CFGR &= ~(0x3);
RCC->CFGR |= 0x2;
// AHB prescaler x1
RCC->CFGR &= ~(0xF<<4);
// APB1 (36MHz max ) prescaler /2
RCC->CFGR &= ~(0x7<<8);
RCC->CFGR |= (0x4<<8);
// APB2(72MHz) prescaler x1
RCC->CFGR &= ~(0x7<<11);
}
ddress.
2019-08-26 05:47 AM
I used stm32L4xx controller for I2C interfacing, as I know I2C peripheral register should be accessed using 32bit access. you should try using 32 bit access.