当前位置: 首页 > news >正文

STM32硬件I2C的注意事项

文章目录

  • 软件模拟I2C
  • 硬件的实现方式

最近在研究I2C的屏幕使用。
有两种使用方式,软件模拟I2C、硬件HAL使用I2C。

软件模拟I2C

发送数据是通过设置引脚的高低电平实现的。

/*引脚配置*/
#define OLED_W_SCL(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)(x))
#define OLED_W_SDA(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_7, (BitAction)(x))/*引脚初始化*/
void OLED_I2C_Init(void)
{// 先关闭 I2C1 避免 PB6/PB7 被干扰// RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOB, &GPIO_InitStructure);OLED_W_SCL(1);OLED_W_SDA(1);
}/*** @brief  I2C发送一个字节* @param  Byte 要发送的一个字节* @retval 无*/
void OLED_I2C_SendByte(uint8_t Byte)
{uint8_t i;for (i = 0; i < 8; i++){OLED_W_SDA(Byte & (0x80 >> i));OLED_W_SCL(1);OLED_W_SCL(0);}OLED_W_SCL(1);	//额外的一个时钟,不处理应答信号OLED_W_SCL(0);
}

硬件的实现方式

/*** @brief 向OLED发送指令*/
void OLED_SendCmd(uint8_t cmd) {static uint8_t sendBuffer[2] = {0};sendBuffer[1] = cmd;OLED_Send(sendBuffer, 2);
}/*** @brief 向OLED发送数据的函数* @param data 要发送的数据* @param len 要发送的数据长度* @return None* @note 此函数是移植本驱动时的重要函数 将本驱动库移植到其他平台时应根据实际情况修改此函数*/#define I2C_TIMEOUT 100  // 超时时间(单位:ms)
uint8_t OLED_Send(uint8_t *data, uint8_t len) {
//  HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDRESS, data, len, HAL_MAX_DELAY);HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDRESS, data, len, I2C_TIMEOUT);if (status != HAL_OK) {// 打印错误(如果你有串口)// printf("I2C Error: %d\n", status);// 重置 I2CI2C_Reset(&hi2c1);// 尝试重发一次status = HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDRESS, data, len, I2C_TIMEOUT);// 如果还是不行,返回失败if (status != HAL_OK) {return 0;  // 失败}}return 1;  // 成功}

HAL_I2C_Master_Transmit 会引起卡死的操作,所以要设置一下超时时间为100ms。
也不知道底层是怎么配置的。

驱动 IC 为 SSD1306,程序重启的时候需要重新配置一下I2C,不然对应的硬件端口会卡死。

http://www.lryc.cn/news/590373.html

相关文章:

  • c语言-数据结构-二叉树的遍历
  • 2025华为ODB卷-宜居星球改造计划200分-三语言题解
  • Jenkins credentials 增加了github credential 但是在Git SCM 凭证中不显示
  • Redis持久化RDB和AOF实现原理详细介绍
  • 将Android Studio创建的一个apk工程放到Android15源码中构建
  • mysql- 存储结构、存储函数,批量生成测试数据
  • ssl相关命令生成证书
  • 代码随想录算法训练营第五十天|图论part1
  • Python 日志轮换处理器的参数详解
  • watermark的作用
  • JS逆向 - YandexSmartCaptcha (worker线程)
  • Spring Boot 解决跨域问题
  • 基于SD-WAN的智慧高速解决方案:高效、低成本的智能交通实践
  • 高频面试雷区:Java Object六大核心方法源码剖析
  • socket和websocket的区别
  • python--杂识--20 sse与websocket区别
  • 【数据结构】栈与链表的区别
  • 构建足球实时比分APP:REST API与WebSocket接入方案详解
  • 【25】MFC入门到精通——MFC静态文本框 中字符串 连续输出 不覆盖先前的文本 换行输出
  • 基于深度学习的情感分析模型:从文本数据到模型部署
  • 推客系统开发:从零构建高并发社交平台的技术实践
  • 【前端】Vue3 前端项目实现动态显示当前系统时间
  • 每天一个前端小知识 Day 33 - 虚拟列表与长列表性能优化实践(Virtual Scroll)
  • Python 与JA3 库的应用
  • 接口幂等性设计:用Redis避免接口重复请求
  • 前端技术之---应用国际化(vue-i18n)
  • 中医文化学习软件,传承国粹精华
  • Java全栈面试实录:从电商支付到AIGC的深度技术考察
  • 什么是数据仓库?数据库与数据仓库有什么关系?
  • 基于WebRTC构建应用的可复用模块