STM32设置为I2C从机模式
目录
- STM32设置为I2C从机模式
- 前言
- 1 硬件连接
- 2 软件编程
- 3 运行测试
- 3.1 I2C连续写入
- 3.2 I2C连续读取
- 3.3 I2C单次读写测试
- 4 总结
前言
STM32的I2C作为主机的情况相信很多同学都用过,网上也有很多教程,但是作为从设备使用的例子应该不多,本文通过硬件和软件的层面,介绍如何把STM32设置为一个I2C从机。
1 硬件连接
测试芯片:STM32F103ZET6
测试方法:用一个USB转I2C的工具接到STM32的I2C引脚上,通过上位机工具进行读写操作。如果没有这个工具,也可以用另外一个stm32或者其他设备测试通讯,同时也可以借助示波器或者逻辑分析仪来辅助调试。
硬件连接:
STM32这边使用硬件I2C1(PB6、PB7),并外接上拉电阻。
2 软件编程
根据STM32数据参考手册,I2C作为从设备时发送和接收的流程如下:
测试例程:定义一个256字节的buffer用来存放I2C从机的数据,默认赋初值0-255,然后通过中断的方式实现I2C数据读写。
示例代码如下:
#include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_i2c.h" #include "misc.h" #define I2CSLAVE_ADDR 0x40 return i2c1_ram[adr]; } void Set_I2C1_Ram(uint8_t adr, uint8_t val) { i2c1_ram[adr] = val; return; } void I2C1_Ram_Init(void) { uint16_t i; for (i = 0; i SR1; I2C1->SR2; } /* STOPF Flag clear */ while((I2C1->SR1&I2C_SR1_STOPF) == I2C_SR1_STOPF) { I2C1->SR1; I2C1->CR1 |= 0x1; } } void I2C1_EV_IRQHandler(void) { uint8_t wert; uint32_t event; /* Reading last event */ event = I2C_GetLastEvent(I2C1); /* Event handle */ if(event == I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED) { // Master has sent the slave address to send data to the slave i2c1_mode = I2C1_MODE_SLAVE_ADR_WR; } else if(event == I2C_EVENT_SLAVE_BYTE_RECEIVED) { // Master has sent a byte to the slave wert = I2C_ReceiveData(I2C1); // Check address if(i2c1_mode == I2C1_MODE_SLAVE_ADR_WR) { i2c1_mode = I2C1_MODE_ADR_BYTE; // Set current ram address i2c1_ram_adr = wert; } else { i2c1_mode = I2C1_MODE_DATA_BYTE_WR; // Store data in RAM Set_I2C1_Ram(i2c1_ram_adr, wert); // Next ram adress i2c1_ram_adr++; } } else if(event == I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED) { // Master has sent the slave address to read data from the slave i2c1_mode = I2C1_MODE_SLAVE_ADR_RD; // Read data from RAM wert = Get_I2C1_Ram(i2c1_ram_adr); // Send data to the master I2C_SendData(I2C1, wert); // Next ram adress i2c1_ram_adr++; } else if(event == I2C_EVENT_SLAVE_BYTE_TRANSMITTED) { // Master wants to read another byte of data from the slave i2c1_mode = I2C1_MODE_DATA_BYTE_RD; // Read data from RAM wert = Get_I2C1_Ram(i2c1_ram_adr); // Send data to the master I2C_SendData(I2C1, wert); // Next ram adress i2c1_ram_adr++; } else if(event == I2C_EVENT_SLAVE_STOP_DETECTED) { // Master has STOP sent I2C1_ClearFlag(); i2c1_mode = I2C1_MODE_WAITING; } } void I2C1_ER_IRQHandler(void) { if (I2C_GetITStatus(I2C1, I2C_IT_AF)) { I2C_ClearITPendingBit(I2C1, I2C_IT_AF); } }
3 运行测试
3.1 I2C连续写入
通过上位机工具写入:
通过逻辑分析仪抓取波形:
3.2 I2C连续读取
通过上位机工具连续读取256字节:
通过逻辑分析仪抓取波形:
3.3 I2C单次读写测试
通过上位机工具读取原值,再写入新值,最后再读取新值:
通过逻辑分析仪抓取波形:
4 总结
通过上位机工具的测试以及逻辑分析仪的解析,STM32的硬件I2C从机通信正常且稳定,读写速度测试了100k和400k,没有发现问题,至此测试完成。
好了,关于STM32如何设置从机模式就介绍到这里,如果你们有什么问题,欢迎评论区留言。
需要完整源码工程的同学可以自行下载:源码下载地址
另外还有一篇HAL库版本的博客:STM32设置为I2C从机模式(HAL库版本)
如果这篇文章能够帮到你,就…懂的。