STM32 LL库 I2C的个人笔记
I2C一直是特别常用的总线,之前用八位机的时候有好多是用单片机模拟的I2C或者类I2C,I2C两跟线,数据线和时钟线,在这里不做I2C时序的介绍(STM32手册里有,以及一些I2C的EPROM都会有很详细的介绍),这里只是对程序的笔记
打开官方例程的I2C的工程,工程名字是I2C_OneBoard_Communication_PollingAndIT,他用了一块板子I2C3做主机,I2C1做从机,打开工程后会看到一下两个函数
从以上函数,可以知道,当设置好器件地址和传送的数据宽度以及模式后,它直接发送了一个数组的数据,但是基本的I2C的操作逻辑是,器件地址 ->寄存器地址->数据,所以要对改工程进行修改。
看看它从机`中断里是怎么写的:
void I2C1_EV_IRQHandler(void)
{/* Check ADDR flag value in ISR register */if(LL_I2C_IsActiveFlag_ADDR(I2C1)){/* Verify the Address Match with the OWN Slave address */if(LL_I2C_GetAddressMatchCode(I2C1) == SLAVE_OWN_ADDRESS){/* Verify the transfer direction, a write direction, Slave enters receiver mode */if(LL_I2C_GetTransferDirection(I2C1) == LL_I2C_DIRECTION_WRITE){/* Clear ADDR flag value in ISR register */LL_I2C_ClearFlag_ADDR(I2C1);/* Enable Receive Interrupt */LL_I2C_EnableIT_RX(I2C1);}else{/* Clear ADDR flag value in ISR register */LL_I2C_ClearFlag_ADDR(I2C1);/* Call Error function */Error_Callback();}}else{/* Clear ADDR flag value in ISR register */LL_I2C_ClearFlag_ADDR(I2C1);/* Call Error function */Error_Callback();}}/* Check RXNE flag value in ISR register */else if(LL_I2C_IsActiveFlag_RXNE(I2C1)){/* Call function Slave Reception Callback */Slave_Reception_Callback();}/* Check STOP flag value in ISR register */else if(LL_I2C_IsActiveFlag_STOP(I2C1)){/* End of Transfer */LL_I2C_ClearFlag_STOP(I2C1);/* Call function Slave Complete Callback */Slave_Complete_Callback();}else{/* Call Error function */Error_Callback();}
}void Slave_Reception_Callback(void)
{/* Read character in Receive Data register.RXNE flag is cleared by reading data in RXDR register */aReceiveBuffer[ubReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
}/*看完整个代码后会发现,会更加清晰的了解I2C的工作流程,并且它读到数据之后,直接送到了寄存器里,其实这样也是未尝不可的,但是要是
做Arduino或者树莓派的从机的话,最好还是符合常规的写法*/
修改回调函数代码,并且在每次进入中断判断地址后是写之后,清除ubReceiveIndex的值
void Slave_Reception_Callback(void)
{if(ubReceiveIndex == 0)ubReceiveIndex = LL_I2C_ReceiveData8(I2C1); elseaReceiveBuffer[ubReceiveIndex] = LL_I2C_ReceiveData8(I2C1);
}
测试,并且在从机加入发数据的中断代码
从机中断代码
void I2C1_EV_IRQHandler(void)
{/* Check ADDR flag value in ISR register */if(LL_I2C_IsActiveFlag_ADDR(I2C1)){/* Verify the Address Match with the OWN Slave address */if(LL_I2C_GetAddressMatchCode(I2C1) == SLAVE_OWN_ADDRESS){/* Verify the transfer direction, a write direction, Slave enters receiver mode */if(LL_I2C_GetTransferDirection(I2C1) == LL_I2C_DIRECTION_WRITE){/* Clear ADDR flag value in ISR register */ubReceiveIndex =0; LL_I2C_ClearFlag_ADDR(I2C1);/* Enable Receive Interrupt */LL_I2C_EnableIT_RX(I2C1);}else{/* Clear ADDR flag value in ISR register */LL_I2C_ClearFlag_ADDR(I2C1);LL_I2C_ClearFlag_TXE(I2C1); LL_I2C_EnableIT_TX(I2C1);}}else{/* Clear ADDR flag value in ISR register */LL_I2C_ClearFlag_ADDR(I2C1);/* Call Error function */Error_Callback();}}/* Check RXNE flag value in ISR register */else if(LL_I2C_IsActiveFlag_TXIS(I2C1)){LL_I2C_TransmitData8(I2C1, aReceiveBuffer[ubReceiveIndex]);} else if(LL_I2C_IsActiveFlag_RXNE(I2C1)){/* Call function Slave Reception Callback */Slave_Reception_Callback();}/* Check STOP flag value in ISR register */else if(LL_I2C_IsActiveFlag_STOP(I2C1)){/* End of Transfer */LL_I2C_ClearFlag_STOP(I2C1);/* Call function Slave Complete Callback */Slave_Complete_Callback();}else{/* Call Error function */Error_Callback();}
}
主机代码
/*在从机地址为0x01的寄存器里写0xff,并且把它读出来*/LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);while(!LL_I2C_IsActiveFlag_TXIS(I2C3)){ } LL_I2C_TransmitData8(I2C3,0x01);while(!LL_I2C_IsActiveFlag_TXIS(I2C3)){ } LL_I2C_TransmitData8(I2C3,0xff);LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);while(!LL_I2C_IsActiveFlag_TXIS(I2C3)){ }LL_I2C_TransmitData8(I2C3,0x01);LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 1, LL_I2C_MODE_AUTOEND,LL_I2C_GENERATE_START_READ);while(!LL_I2C_IsActiveFlag_RXNE(I2C3)){ }test = LL_I2C_ReceiveData8(I2C3);
实验结果
STM32 LL库 I2C的个人笔记相关推荐
- STM32 HAL库开发学习笔记: USART1串口通讯(中断方式) IDE-STM32CubeIDE
STM32串口通讯有三种方式,分别为阻塞(轮询).中断.DMA.这里将用中断的方式开发. 笔者也是刚入门STM32 HAL库开发,该笔记致希望于能帮到初学者,文中配置步骤.代码.实验现象均是笔者实践可 ...
- STM32 HAL库学习笔记4-SPI
STM32 HAL库学习笔记4-SPI 前言 一.SPI协议简介 SPI物理层 SPI协议层 1.基本通讯过程 2. 通讯的起始和停止信号 3. 数据有效性 4. CPOL/CPHA 及通讯模式 二. ...
- STM32 HAL库学习笔记1-HAL库简介
STM32 HAL库学习笔记1-HAL库简介 HAL库 SPL 库 和 HAL 库两者相互独立,互不兼容.几种库的比较如下 目前几种库对不同芯片的支持情况如下 ST 中文官网上有一篇<关于ST库 ...
- USB学习笔记(5)STM32 USB库移植步骤
USB学习笔记(5)STM32 USB库移植步骤 本文是将官网的USB驱动库文件移植到自己的工程里面,实现USB功能的具体移植步骤说明,实现Custom_HID功能. 1.先准备一个工程模板 获取工程 ...
- [野火]STM32 F103 HAL库开发实战指南笔记之基础总结
1.本书配套的仿真器为 Fire-Debugger,遵循 ARM 公司的 CMSIS-DAP 标准,支持所有基于 Cortex-M 内核的单片机,常见的 M3.M4 和 M7 都可以完美支持.Fire ...
- STM32 HAL库学习笔记2 HAL库介绍
STM32 HAL库学习笔记2 HAL库介绍 CMSIS标准 一.再次认识HAL库 HAL库设计思想 HAL库实现方式 以GPIO模块为例 GPIO外设数据类型 GPIO外设接口函数 二.使用HAL库 ...
- [野火]STM32 F103 HAL库开发实战指南笔记之简单外设总结
1.GPIO编程总结 使能 GPIO 端口时钟: 初始化 GPIO 目标引脚为推挽输出模式: 编写简单测试程序,控制 GPIO 引脚输出高.低电平. 这部分宏控制 LED 亮灭的操作是直接向 BSRR ...
- 了解库开发,我们从STM32标准库开发学起
摘要:从STM32新建工程.编译下载程序出发,让新手由浅入深,尽享STM32标准库开发的乐趣. 自从CubeMX等图像配置软件的出现,同学们往往点几下鼠标就解决了单片机的配置问题.对于追求开发速度的业 ...
- STM32实现基于I2C的AHT20温湿度采集
STM32实现基于I2C的AHT20温湿度采集 I2C通信协议 软件I2C与 硬件I2C 代码实现 烧录 硬件连接 烧录并运行 参考 I2C通信协议 I2C协议简介 IC( Inter-- Integ ...
最新文章
- AI看电影看哭了...MIT科学家正在教AI感受电影中的喜怒哀乐
- 在Python中读取MATLAB的数据文件
- [html] 你有使用过MediaRecorder吗?说说它的运用场景有哪些?
- 如何在CISCO PIX上实现×××步骤?
- ES6-异步编程-Promise对象
- 新裝win7虚拟机设置记录-20180909
- 18. JavaScript event 对象
- 《图解算法》学习之算法复杂度、运行时间
- 你熟悉的矢量图形制作软件ai cc 2019 mac完美直装版——Illustrator CC 2019 for Mac 23.0.3
- 计算机安全泄露,哪些原因导致计算机信息泄露
- 餐馆点菜系统python程序_Python写一个自动点餐程序
- Unity获取组件的几种方式(拖拽法、标签法、名字法)
- istqb纸质证书_高大上但含金量极高的ISTQB认证考试容易过吗
- Layer For Mobile
- TensorFlow 学习指南:深度学习系统构建详解
- 什么是云计算的基本原理?具体的核心技术有哪些?
- 港科夜闻|香港科大线上校友日:趣味探索科学奥秘
- 小米VR nolo 安装调试简介
- 微信小程序:去掉button默认样式
- php解析pdf文本