stm32 的 I2C 故障
I2C failure with stm32
我有一个关于 I2C 的问题,我在互联网上看到了一些关于我的问题的主题,但没有解决方案,我希望你能帮助我解决这个问题。
问题:
I2C 发送地址后,SR1 寄存器中的ADDR 标志位没有设置,但同时AF 标志位(确认失败)被设置。我不使用 std 外设库,我使用 stm32f429I-Discovery 套件和 AT24C256。
它卡在 while (!(I2C1->SR1 & 0x0002));
行,我找不到解决办法。请帮助我。
/* Includes ------------------------------------------------------------------*/
#include "main.h"
int main(void)
{
int slave_adress = 0x50; // eeprom adress
int word_adress = 0x01; // I want to write in this register adress in eeprom.
int data = 0x30; // the data I want to write
RCC->AHB1ENR |= 1<<1; //enable port B
RCC->APB1ENR |= 1<<21; // enable i2c_1
GPIOB->MODER = 0x82000; // made PB6-I2C1_CLK ve PB9-I2C_SDA pins as alternate function
GPIOB->AFR[0] = 0x4000000; // made pb6 as af4 (i2c1_scl)
GPIOB->AFR[1] = 0x40; // made pb9 as af4 (i2c1_sda)
GPIOB->OTYPER |= 0x240; //made PB6 and PB9 as open drain
GPIOB->PUPDR = 0x00;
I2C1->CR2 = 0x0010; // made 16MHz clock hsi
I2C1->CCR = 0x0050; ////SM Mod, duty=0 pclk=16mhz
I2C1->TRISE = 0x0011; //1000 ns / 62.5 ns = 16 + 1
I2C1->CR1 = 0x0001; //enable I2C
I2C1->CR1 |= 1<<8; //I2C Start
while (!(I2C1->SR1 & 0x0001));// //wait for start bit,
I2C1->DR = slave_adress; // Write to I2C Address register
while (!(I2C1->SR1 & 0x0002)); ///////////////it stucks here///////////////////////////
I2C1->DR = word_adress; // (EV8_1 – reference manual)
while (!(I2C1->SR1 & (1<<7))); // Wait TxE bit set
}
我解决了问题,我的错误是关于初始化,工作代码如下(我使用 HAL 函数只提供时钟):
#define eeprom_adress 0xA0
uint8_t data = 0x56;
int main(void)
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIOB->MODER |= 0x82000;
GPIOB->OTYPER |= 0x0240;
GPIOB->OSPEEDR|= 0xC30C0;
GPIOB->PUPDR |= 0x41000;
GPIOB->AFR[0] |= 0x4000000;
GPIOB->AFR[1] |= 0x0040;
__HAL_RCC_I2C1_CLK_ENABLE();
I2C1->OAR1 |= 0x4000;
I2C1->CR2 |= 0x0003;
I2C1->CCR |= 0x0010;
I2C1->TRISE |= 0x004;
I2C1->CR1 |= 0x0001; //i2c yi enable ettim
I2C1-> CR1|=1<<8; //start bitini ver
while(!(I2C1->SR1 & 0x0001)); // start bitini bekliyoz
I2C1->DR = eeprom_adress; // slave cihazin adresini yazdik
//HAL_Delay(4);
while(!(I2C1->SR1 & 0x0002)); // ADRES GITTIMI
while(!(I2C1->SR2 & 0x0001)); // MSL ICIN BEKLE
I2C1->DR = 0x01;
while(!(I2C1->SR1 & 0x0080));
I2C1->DR = 0x56;
while(!(I2C1->SR1 & 0x0080)); // txe nin bosalmasini bekle
while(!(I2C1->SR1 & 0x0004)); // btf yi bekliyoz
I2C1->CR1 |= 1<<9; // stop bit
}
我有一个关于 I2C 的问题,我在互联网上看到了一些关于我的问题的主题,但没有解决方案,我希望你能帮助我解决这个问题。
问题: I2C 发送地址后,SR1 寄存器中的ADDR 标志位没有设置,但同时AF 标志位(确认失败)被设置。我不使用 std 外设库,我使用 stm32f429I-Discovery 套件和 AT24C256。
它卡在 while (!(I2C1->SR1 & 0x0002));
行,我找不到解决办法。请帮助我。
/* Includes ------------------------------------------------------------------*/
#include "main.h"
int main(void)
{
int slave_adress = 0x50; // eeprom adress
int word_adress = 0x01; // I want to write in this register adress in eeprom.
int data = 0x30; // the data I want to write
RCC->AHB1ENR |= 1<<1; //enable port B
RCC->APB1ENR |= 1<<21; // enable i2c_1
GPIOB->MODER = 0x82000; // made PB6-I2C1_CLK ve PB9-I2C_SDA pins as alternate function
GPIOB->AFR[0] = 0x4000000; // made pb6 as af4 (i2c1_scl)
GPIOB->AFR[1] = 0x40; // made pb9 as af4 (i2c1_sda)
GPIOB->OTYPER |= 0x240; //made PB6 and PB9 as open drain
GPIOB->PUPDR = 0x00;
I2C1->CR2 = 0x0010; // made 16MHz clock hsi
I2C1->CCR = 0x0050; ////SM Mod, duty=0 pclk=16mhz
I2C1->TRISE = 0x0011; //1000 ns / 62.5 ns = 16 + 1
I2C1->CR1 = 0x0001; //enable I2C
I2C1->CR1 |= 1<<8; //I2C Start
while (!(I2C1->SR1 & 0x0001));// //wait for start bit,
I2C1->DR = slave_adress; // Write to I2C Address register
while (!(I2C1->SR1 & 0x0002)); ///////////////it stucks here///////////////////////////
I2C1->DR = word_adress; // (EV8_1 – reference manual)
while (!(I2C1->SR1 & (1<<7))); // Wait TxE bit set
}
我解决了问题,我的错误是关于初始化,工作代码如下(我使用 HAL 函数只提供时钟):
#define eeprom_adress 0xA0
uint8_t data = 0x56;
int main(void)
{
HAL_Init();
SystemClock_Config();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIOB->MODER |= 0x82000;
GPIOB->OTYPER |= 0x0240;
GPIOB->OSPEEDR|= 0xC30C0;
GPIOB->PUPDR |= 0x41000;
GPIOB->AFR[0] |= 0x4000000;
GPIOB->AFR[1] |= 0x0040;
__HAL_RCC_I2C1_CLK_ENABLE();
I2C1->OAR1 |= 0x4000;
I2C1->CR2 |= 0x0003;
I2C1->CCR |= 0x0010;
I2C1->TRISE |= 0x004;
I2C1->CR1 |= 0x0001; //i2c yi enable ettim
I2C1-> CR1|=1<<8; //start bitini ver
while(!(I2C1->SR1 & 0x0001)); // start bitini bekliyoz
I2C1->DR = eeprom_adress; // slave cihazin adresini yazdik
//HAL_Delay(4);
while(!(I2C1->SR1 & 0x0002)); // ADRES GITTIMI
while(!(I2C1->SR2 & 0x0001)); // MSL ICIN BEKLE
I2C1->DR = 0x01;
while(!(I2C1->SR1 & 0x0080));
I2C1->DR = 0x56;
while(!(I2C1->SR1 & 0x0080)); // txe nin bosalmasini bekle
while(!(I2C1->SR1 & 0x0004)); // btf yi bekliyoz
I2C1->CR1 |= 1<<9; // stop bit
}