Я пытаюсь связать 2 STM32 с I2C. Моя конфигурация выглядит следующим образом:
7-битный режим адресации (без двойного адреса, только OAR1)
100 кГц скорость
ACK включен (на подчиненном устройстве)
ACK отключен (на ведущем устройстве, поскольку между ведущим / ведомым в любой момент времени передается только 1 байт).
как на главном / на ведомом устройстве, в спецификации указано, что GPIOB (PB6) как SCL как AF, так и GPIOB (PB7) как SDA как AF, но PB8 и PB9 становятся логической 1 в Proteus, поэтому я использую PB8 и PB9.Адрес не совпадает. это из-за Протея?
Мастер-код:
#include "stm32f10x.h" // Device header
#include "delay.h"
void pinConfig(void);
void i2c_Master_Config(void);
void sendAdress();
int main() {
pinConfig();
i2c_Master_Config();
sendAdress();
while(1) {}
}
void pinConfig() {
RCC->APB1ENR |= 1<<21;//Enable I2C 1 clock
RCC->APB2ENR |= 1<<2;//Enable GPIOA clock
RCC->APB2ENR |= 1<<3;//Enable GPIOB clock
RCC->APB2ENR |= 1<<0;//Enable AFIO clock
GPIOB->CRH |= 0x000000FF; //SCL ve SDA AF Open Drain SCL => PB8
SDA =>PB9
}
void i2c_Master_Config() {
RCC->APB1ENR |= 1<<21; //I2C 1 Clock Enable.
I2C1->CR1 |= (1 << 15);
I2C1->CR1 &= ~(1 << 15);
I2C1->CR2 |= 0x08; //36 Mhz peripheral clock.
I2C1->CCR = 0x28; //100 khz clock
I2C1->TRISE = 0x09; //1/8MHZ= 125 ns => 1000ns/125ns =8 => 8+1=9
I2C1->CR1 |= (1<<0); //Peripheral enable.
}
void sendAdress() {
volatile int temp;
I2C1->CR1 |= 1<<8; //START bit.
while(!(I2C1->SR1 & (1<<0))); //wait until start flag is set
I2C1->DR = 0x0B; //7 bit adress.
while(!(I2C1->SR1 & (1<<1))); //wait until addr flag is set
temp = I2C1->SR2; //clear addr flag.
}
Код ведомого:
#include "stm32f10x.h" // Device header
void pinConfig(void);
void i2c_Slave_Config(void);
uint8_t data;
void I2C1_EV_IRQHandler() {
volatile int temp;
if(I2C1->SR1 &(1<<1)) { //wait until addr flag is set
temp = I2C1->SR1; //clear addr
temp = I2C1->SR2; //clear addr
GPIOA->BRR |= 1<<3;
}
}
int main() {
pinConfig();
i2c_Slave_Config();
while(1) {}
}
void pinConfig() {
RCC->APB1ENR |= 1<<21; //I2C 1 Clock enable.
RCC->APB2ENR |= 1<<2; //Enable GPIOA clock
RCC->APB2ENR |= 1<<3; //Enable GPIOB clock
RCC->APB2ENR |= 1<<0; //Enable AFIO clock
GPIOA->CRL |= 0x00002000; //PA3 led.
GPIOB->CRH |= 0x000000FF; //SCL ve SDA AF Open Drain SCL => PB8 SDA =>PB9
GPIOA->BSRR |= 1<<3; //Turn off the led.
}
void i2c_Slave_Config() {
RCC->APB1ENR |= 1<<21; //I2C 1 Clock Enable.
I2C1->CR1 |= (1 << 15);
I2C1->CR1 &= ~(1 << 15);
I2C1->CR2 |= 0x08;
I2C1->CCR = 0x28; //100 khz clock
I2C1->OAR1 &= ~(1<<15); //7-bit slave adress.
I2C1->CR2 |= 1<<9; //Interrupt enable.
NVIC->ISER[0] |= 1<<31; //i2c1 interrupt enable.
I2C1->OAR1 = (0x05 << 1); //Slave adress
I2C1->CR1 |= (1<<0); //Peripheral enable.
I2C1->CR1 |= 1<<10; //ACK bit.
}