【发布时间】:2019-03-23 13:51:40
【问题描述】:
我正在尝试用 I2C 通信 2 个 STM32。我的配置如下:
7位寻址模式(无双地址,只有OAR1)
100khz 速度
ACK 启用(在从机上)
ACK 禁用(在主机上,因为任何时候在主机/从机之间只传输 1 个字节)
在主/从机上,使用 GPIOB (PB6) 作为 SCL 作为 AF,使用 GPIOB (PB7) 作为 SDA 作为 AF。问题出在哪里?
主码:
#include "stm32f10x.h" // Device header #include "delay.h"
void pinConfig(void);
void i2c_Master_Config(void);
void sendData(uint8_t data);
int main() {
delay_init();
pinConfig();
i2c_Master_Config();
while(1)
{
uint8_t butonState=GPIOA->IDR & 0x00001000;
sendData(0x68,butonState);
delay_ms(10);
}
}
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
GPIOA->CRL |= 0x00008000; //PA3 button pull-down
GPIOB->CRL = 0xFF000000; //SCL and SDA AF Open Drain SCL => PB6 SDA =>PB7
}
void i2c_Master_Config() {
I2C1->CR2 |=1<<5; //36 Mhz peripheral clock.
I2C1->CR2 |=1<<2; //36 Mhz peripheral clock.
I2C1->CCR =0x28;//100 khz clock
I2C1->TRISE =9;//1/8MHZ= 125 ns => 1000ns/125ns =8 => 8+1 =9
I2C1->CR1 |=(1<<0);//Peripheral enable..
}
void sendData(uint8_t data) {
volatile int temp;
while(I2C1->SR2 &(1<<1));//BUSY bit.
I2C1->CR1 |=1<<8;//START bit.
while(!(I2C1->SR1 & (1<<0))); //wait until start flag is set
I2C1->DR = slaveAdres<<1;//7 bit adress.
while(!(I2C1->SR1 &(1<<1)));//wait until addr flag is set
gecici=I2C1->SR2;//clear addr flag.
I2C1->DR = data;
while (!(I2C1->SR1 & (1<<7))){} //wait until txe is set
while (!(I2C1->SR1 & (1<<2)));//BTF(Byte transfer finished)=1 .
I2C1->CR1 |= 1<<9;//STOP bit.
I2C1->CR1 &=~(1<<0);//Peripheral disable.
}
从机代码:
#include "stm32f10x.h" // Device header
void pinConfig(void);
void i2c_Slave_Config(void);
uint8_t readData(void);
uint8_t data;
int main()
{
pinConfig();
i2c_Slave_Config();
while(1)
{
data=readData();
if(data==0)
GPIOB->BSRR |=1<<3;
else if(data==1)
GPIOB->BRR |=1<<3;
}
}
void pinConfig()
{
RCC->APB1ENR |=1<<21;//I2C 1 Clock Aktif.
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->CRL = 0xFF000000; //SCL and SDA AF Open Drain SCL => PB6 SDA =>PB7
GPIOA->BSRR |=1<<3;//Turn off the led.
}
void i2c_Slave_Config() {
RCC->APB1ENR |=1<<21;//I2C 1 Clock Enable.
I2C1->CR2 |=1<<5; //36 Mhz peripheral clock.
I2C1->CR2 |=1<<2; //36 Mhz peripheral clock.
I2C1->CCR =0x28;//100 khz clock
I2C1->OAR1 &=~(1<<15);//7-bit slave adress.
I2C1 ->CR1 |= 1<<10;//ACK enable.
//0x68 Slave Adress Configured.
I2C1 ->OAR1 &=~(1<<1);
I2C1 ->OAR1 &=~(1<<2);
I2C1 ->OAR1 &=~(1<<3);
I2C1 ->OAR1 &=~(1<<5);
I2C1 ->OAR1 |=(1<<4);
I2C1 ->OAR1 |=(1<<6);
I2C1 ->OAR1 |=(1<<7);
//0x68 Slave Adress Configured.
}
uint8_t readData()
{
volatile int temp;
uint8_t data;
I2C1->CR1 |=(1<<0);//Peripheral enable.
while(I2C1->SR2 &(1<<1));//BUSY bit.
I2C1->CR1 |=1<<8;//START bit.
while(!(I2C1->SR1 & (1<<0))); // wait until start flag is set.
while(!(I2C1->SR1 &(1<<1)));// wait until addr flag is set
temp=I2C1->SR2;//clear addr .
while (!(I2C1->SR1 & (1<<6))){} // wait until rxne is set
data=I2C1->DR;
while (!(I2C1->SR1 & (1<<4))){} // wait until STOPF is set
gecici=I2C1->SR1;
I2C1->SR1 |=1<<9;
I2C1->CR1 &=~(1<<0);//Peripheral disable.
return data;
}
地址不匹配。我没有看到示波器上的 SDA 和 SCL 信号有任何响应。我使用 4.7kohms 将 SCL 和 SDA 都拉到 3.3v 每一行。(STM32F103C6)。
【问题讨论】:
-
请注意编码。逐位设置地址不方便且繁琐。只需分配寄存器
I2C1->OAR1 = (0x68 << 1);,包括I2C_OAR1_ADDMODE在内的所有其他位都将被自动清除。