#背景
最近,在使用 STM32F030C8T6 做 I2C Slave 设备接口。在网上查了好多的资料,使用 STM32 硬件 I2C 的例程少之又少,对 STM32 硬件 I2C 的批判巨多,只能硬着头皮,自己一步一步摸索。
实际上,在这次硬件 I2C 调试之前,其实我已经通过 IO 模拟的方式实现了 I2C,但速率仅能实现 Standard-mode(up to 100 kbit/s)。对于 Fast-mode(up to 400 kbit/s),IO 模拟方式简直是无能为力。同时,由于 IO 模拟 I2C 时并没有充分的考虑架构,最终的实现结果是功能单一,客户满意度不好。
#I2C 实现方式
经过多次纠结和考虑,我决定采用Dummy Write + Register 方式进行 I2C 通讯。这样的好处,在于用户使用方便,对于后续的功能增加或需求变化,对客户接口完全无影响,只需要修改寄存器列表就 OK。这个也是参考了几个 I2C接口的芯片决定的。
####Dummy Write
Dummy Write 要求 Master 访问 Slave 时,必须发送两次的从机地址。同时对于 STM32 HAL 的 Slave Receive 或 Write ,都必须指定长度,因此,在 第一次写操作中, Master 发送了 寄存器地址和写入数据的长度。时序图如下图所示。
程序源码位于:https://github.com/CherryXiuHuaWoo/STM32F030C8-IIC-Slave 。
#记录各种坑爹
####第 1 次调试结果:总线挂了
第一次 Master Write 时,通讯完成。
第二次 Master Write 时,在 Address + Write 后, SDA 被置为 Low,导致总线被占用,无法再继续通讯。
####第 2 次调试结果:基本调通了 Write/Read
通过在每次地址中断回调函数HAL_I2C_AddrCallback处理完成后,增加 HAL_I2C_EnableListen_IT(&hi2c1),不再出现第一次调试问题,可反复通讯。
Bug 分析:
通过查看调用HAL_I2C_AddrCallback(hi2c, transferdirection, slaveaddrcode) 的代码部分。
发现,在I2C_ITAddrCplt 函数中,在调用 HAL_I2C_AddrCallback 回调函数前,有调用 I2C_Disable_IRQ(hi2c, I2C_XFER_LISTEN_IT)把中断关了!!!!!!之后也没有恢复中断,所以用户必须自行把中断打开!!!!!!
####第 3 次调试:DUMMYWrite 后,总线挂了
这个总线挂了是我还没有编写DuMMYWrite后的处理代码所导致。
####第 4 次调试:DUMMYWrtie 读写正常
读时序:
写时序:
关键字:STM32CUBEMX I2C Slave
引用地址:
【STM32CUBEMX】 I2C Slave 实现
推荐阅读最新更新时间:2024-11-10 15:58
PIC单片机的i2c的程序
#include pic.h #define uchar unsigned char #define uint unsigned int #define add 0xaa __CONFIG(0xc3e4); __CONFIG(0xffff); #define DS1302 RC2 //定义关掉DS1302时钟芯片,使RC4 RC3 IO口可以用于AT24C02控制。 const uchar ee_data ={1,2,3,3,2,1}; uchar read_data ; const uchar table ={0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f}; v
[单片机]
STM32CubeMx开发之路—3发送USART数据和printf重定向
运行环境 Windows10 STM32CubeMX___Version 5.0.0 Keil5(MDK5)___Version 5.15 简介 本例程主要讲解如何通过串口发送数据和重定向printf STM32CubeMx基本配置 基础配置过程请参考 STM32CubeMx(Keil5)开发之路—1配置第一个项目 STM32CubeMx USART1配置 1——点击USART1进行设置 2——模式选择Asynchronous异步传输 3——可以看到右边自动出现了Tx和Rx 4——可以自行设置波特率,停止位,校验位等参数 代码修改 1——选择main.c文件 2——在USER CODE中添加如下代码,重定向printf
[单片机]
STM32CubeMX:UART操作
UART共有三种操作方式,轮询方式、中断方式以及DMA方式。 芯片:STM32F103C8T6 应用管脚: 输出:PA0、PA1 USART1 配置界面 添加中断配置 添加DMA配置 代码应用 1.实现printf函数 /* USER CODE BEGIN 0 */ #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker- Libraries- Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTO
[单片机]
MSP430硬件I2C使用方法——以BH1710和AT24C
硬件的I2C控制器终于调出来了,这些天一直在钻死胡同,其实最好的参考资料还是TI官方提供的。代码参考了MSP430的User’s Guide和Application Note,下面提供IAR工程并做简要解释: 采用的芯片:MSP430F1611(USART0 Master方式) 设备地址:BH1710(写地址0x46,读地址0x47),AT24C02(写地址0xA0,读地址0xA1) 工程文件:(采取模块化方法,只需添加I2C文件并修改相应的器件模块即可) 接口电路: 一般情况下,大家在调试I2C设备时会首先考虑采用IO口模拟I2C总线的方法,这样的方法思路简单,只需要给出正确的时序即可。但是这样也有意想不到的问题,比如时
[单片机]
STM32CubeMX系列教程 5.0版本环境开发——2.Uart串行通信功能
1.搭建一个基本工程: 具体请参考我的上一篇内容搭建:https://www.cnblogs.com/Engineer-Lai/p/10072673.html 2.Uart协议简要: 分为通俗描述和概念性描述 通俗描述: 1. 对于单片机入门的人来说,首先我们要明白 我们唯一可控的对象是IO口,IO有两种状态 0和1. 有两种操作读和写(请务必确认自己明白并可以操控,我们便可继续) 2.在确认第一点后,硬件协议存在的意义是什么:A对象 把N个数据遵照特定的规则传给 B对象.(这里数据的单位是字节,一个字节由8个位组成) 3.接下来就是如何传数据的问题了,我们只有0和1可以表示。所以我们必须制定一套双方都遵循的可行游戏规则。
[单片机]
I2C总线学习—查缺补漏—应答信号ACK
IIC协议规定,当主机作为接收设备时,主机对最后一个字节不应答,以向发送设备(从设备)标识数据传送结束。这是因为每次传输都应得到应答信号后再进行下一个字节传送。如果此时接收机应答了,那它就接收的不是最后一个字节了。如果是最后一个字节,第9个时钟周期发送的是非应答信号(此时发送的不是应答信号就是非应答信号),最后发送停止信号。 并非每传输8位数据之后,都会有ACK信号,有以下3中例外 当从机不能响应从机地址时(例如它正忙于其他事而无法响应IIC总线的操作,或者这个地址没有对应的从机),在第9个SCL周期内SDA线没有拉低,即没有ACK信号。这时,主机发出一个P信号终止传输或者重新发出一个S信号开始
[单片机]
使用HAL库、STM32CubeMX和Keil 5开发入门教程(一)
本文转载自http://blog.csdn.net/charmingsun/article/details/50802267,本教程以点亮一盏LED灯为目的为大家演示用STM32CubeMX、Keil、ST-Link开发STM32程序的一般方法。 一、学习前的准备工作 硬件:一块STM32开发板,一个ST-Link;(我使用的开发板是NUCLEO-F411RE) 软件:装好ST-Link的驱动程序,装好STM32CubeMX,装好Keil; 文档:开发板的原理图、芯片的参考手册和HAL驱动说明书。 附: STM32F4xx HAL驱动说明书 二、创建一个新的STM32CubeMX工程 打开STM32CubeMX,然后单击
[单片机]
I2C总线键盘电路以及驱动程序设计
一、概述 本文介绍一种采用MAX7348 的串行I2C 总线的键盘电路以及驱动程序的设计。 I2C 需要连线少,仅需一条串行时钟线和一条串行数据线。允许多主机控制,具有裁决和同步功能,可随意添加或摘除总线上的子器件等诸多优点,所以已经被广泛应用。 二、MAX7348 MAX7348 是美国MAXIM 公司生产的2 线接口、低EMI 键盘开关和发声控制器,可监控多达40 个按键,可对按键去抖并保存在FIFO 中,去抖时间用户可在9 ~ 40ms 之间任意设置,MAX7348 自带的音调发生器在控制器的作用下可自动发出按键声和报警声,在发声期间,输出还可以设置为高电平或低电平,以驱动电子发声器、继电器或指示灯。
[电源管理]