大家好,
许多天来,我一直在努力让I2C在STM32F401CE上工作(在PROTEUS中模拟)。
USART工作得很好,但I2C还没有!我使用默认值,HSI 16MHz作为源时钟,没有预分频器。
我需要你的帮助
我初始化I2C1并发送启动条件的代码是:
void i2c1_init(){
// Enable clocks to the peripherals
RCC -> APB1ENR |= 1<<21; // Enable I2C1 clock
RCC -> AHB1ENR |= 1<<1; // Enable GPIOB clock
// set pins B6=SCL and B7=SDA to Alternate Function, Pull-up enabled, Open-Drain and high speed
GPIOB -> MODER = 2<<2*7 | 2<<2*6; //MODER7/6[1:0] = 10 => Alternate function mode
GPIOB -> OTYPER = 1<<1*7| 1<<1*6; // B6/7 = 1 => Output open-drain
GPIOB -> OSPEEDR = 3<<2*7 | 3<<2*6; // OSPEEDR7/6[1:0] = 11 => High speed
GPIOB -> PUPDR = 1<<2*7 | 1<<2*6; // PUPDR7/6[1:0] = 01 => Pull-up
GPIOB -> AFRL = (4 << 4*7) | (4 << 4*6); //AFRL7/6[3:0] = 0100 => AF4 (I2C1)
// initialization steps:
I2C1 -> CR1 |= 1<<15; // SWRST (bit15) = 1 => Enable the software reset
I2C1 -> CR1 &= ~(1<<15); // then immediately resetting the SWRST bit.
I2C1 -> CR2 = 16; // FREQ[5:0] (Bits 5:0) = 16 => Peripheral clock frequency = 16 MHz// other bits = 0 => Interrupts and DMA disabled
//I2C1 -> OAR1 = 0x30; // Own address in slave mode only
// set SCL clock: Thigh = Tlow = CCR * TPCLK1 (here TPCLK1 = 1/16 MHz)
// For 100kHz, Thigh = Tlow = 5uS => CCR = (5/0.0625) = 80
I2C1 -> CCR = 80; // F/S (Bit 15) = 0 => standard master mode// CCR[11:0] (Bits 11:0) = 80 => SCL clock = 100kHz
I2C1 -> TRISE |= 11; // TRISE[5:0] (Bits 5:0) = 9 => Maximum rise time in standard mode
I2C1 -> CR1 |= 1; // PE (bit0) = 1 => Enable the peripheral
}// send a start condition and slave address
void I2C1_Start(char address)
{
uint16_t reg; //I2C1->CR1 |= (1<<10>
I2C1 -> CR1 |= 1<<8; // START (Bit 8) = 1 => start generation (and enter master mode)
while(!(I2C1 -> SR1 & 1<<0)); // wait until SB (Bit 0) = 1 => Start condition generated
reg = I2C1 -> SR1; // MUST read SR1 reg first
// then send the address to clear SB bit
I2C1 -> DR = (address << 1) | 0x00; // write address in DR reg
while(!(I2C1 -> SR1 & 1<<1)); // wait until ADDR (Bit 1) = 1 => End of address transmission
// ADDR bit is cleared by software reading SR1 followed by reading SR2
reg = I2C1 -> SR1;
reg = I2C1 -> SR2; //In datasheet p499: TxE is not set during address phase ?!
//while(!(I2C1 -> SR1 & 1<<7 xss=removed> Data register empty }void main(){
i2c1_init();
I2C1_Start(0x60); for (;;) ;
}
附完整项目
请帮忙
编辑:
要构建代码,请在“periph.h”中去掉第33行的注释。
EDIT2(编辑2):
无需重复造轮子
只需搜索“stm32 F4 baremetal i2c”:
https://github.com/fcayci/stm32f4-bare-metal/blob/master/projects/i2c/i2c.c
一周热门 更多>