IIC通信


《用CubeMX学习STM32》

注释 点击上面蓝字进入完整专栏,这个系列所有文章都会整合到这个专栏


6、STM32 I2C通信

前言: IIC协议简介

  维基百科的解释如下: I2C(Inter-Integrated Circuit)字面上的意思是积体电路之间,它其实是I2C Bus简称,所以中文应该叫集成电路总线,它是一种串行通讯汇流排,使用多主从架构,由飞利浦公司在1980年代为了让主机板、嵌入式系统或手机用以连接低速周边装置而发展。I2C的正确读法为“I平方C”("I-squared-C"),而“I二C”("I-two-C")则是另一种错误但被广泛使用的读法。自2006年10月1日起,使用I2C协定已经不需要支付专利费,但制造商仍然需要付费以取得I2C从属装置位址。
   我们需要了解的是 : I2C通信只需要两根线即可进行数据传输; 即串行数据线(SDA::Serial DAta)和串行时钟线(SCL::Serial CLock); IIC总线具有多主设备的优点, 就是有多个主机进行数据发送并且不会有混乱.

  IIC总线可以用简单、优雅四个字形容,很方便。下面是IIC的时序图:

IIC总共有三种信号:开始信号,结束信号,应答信号

说明:高电平为1,低电平为0

1、图中S即为起始信号: SCL处于1时, SDA由高变低↓—>Start

下面是STM32的这部分代码,每句话我基本上都加了注释,可以对照时序图看, 便于理解

2、图中末尾P为结束信号: SCL=1, SDA 由低变高↑

3、数据传送: 每次数据传送都是8个字节; SCL=1时, SDA的数据不可以变化, 只有SCL为低电平, 数据线的数据才可以变化;

3.1、 数据传输流程:SCL=0, —>开始数据传输, 传输完一位之后,—> SCL=1(拉高时钟线);===
下面接着循环, 直到传输完一个字节8位数据.

下面举个例子:

e.g.

传输1001 1100?

SCL=0 --> SDA=1 --> SCL=1 (先传送最高位MSB)

SCL=0 --> SDA=0 --> SCL=1

SCL=0 --> SDA=0 --> SCL=1

**Tips:**在IIC协议中,起始信号必须有. 因为IC必须知道什么时候开始了,才可以正确判断接受数据.

下面开始Cube配置+IAR编程


6.1 操作简介

  (1) 我所使用的STM32开发板板载了一个24C02的EEPROM存储芯片; 这个芯片就是通过IIC总线和单片机通信的;

  (2) 通过GPIO软件模拟IIC通信 , 实现对24C02芯片内部数据的读写操作 .

注:

  本次实验的代码是用的原子的底层代码, 修改了部分代码, 和Cube配置的工程以及HAL库函数匹配. 野火的例程没有看过,如果这个代码又有什么限制或者问题, 可以评论或者私信告诉我, 共同学习,感激不尽.

6.1 软件流程图

开机检测24C02--->主循环检测按键--->串口打印相关信息...


6.2 硬件接口

以我用的单片机为例:

   但是这里并没有用板子上的硬件 IIC, 只是用这两个对应的引脚做软件模拟 IIC


Step1 : STM32CubeMX配置

  • (1) 像前面那样配置好基础的东西[RCC--SYS--时钟树配置不变]

    • 还要配置 串口 和 按键 ; 时钟树的配置跟之前的博客都一样
    • Tips: Click the blue word to open the corresponding blog link
  • (2) 配置IIC通信用的两个引脚(SCL&SDA)

    • 两个引脚都配置为输出模式, 在程序中需要改变引脚方向, 那个时候直接操作寄存器改动引脚输入输出即可, 配置的时候先默认配置一个输出;

补充: 后面又加上了两个LED引脚, 用以做指示

  • (3) Project Manager and Generate Code


Step2 : IAR或Keil编程

  • (1) IIC部分代码

  • 我把我改过部分的底层代码分享在网盘里面
    链接:https://pan.baidu.com/s/17ogW2r-WzN9u-w511VzBJQ
    提取码:9m4v

    • .c文件放在 src 文件夹,.h文件复制到 Inc 文件夹

    • 在myiic.h里面有两句宏定义SDA_OUT()和SDA_IN(); 如果你用的是F4的板子是可以直接用的, 但是如果用的是F1的或者其他的, 这个宏定义要改一下, 因为不同的芯片寄存器的名字和操作不太一样. 如果有人用的F1在这里遇到困难可以评论或者私信我, 这里就不单独写了

说明 :24cxx文件是24CXX系列芯片的底层驱动文件, myiic文件是修改后的iic通信的驱动文件; 在主函数里面就是调用myiic里面的函数去实现通信的功能

部分底层代码分析

  大概说一下底层驱动, 24cxx文件是通过iic协议对24c02芯片通信的底层驱动,直接用就可以了。
  myiic文件是iic的关键.
  关于起始信号, 结束信号就不多说了
  在myiic.h中宏定义了SDA引脚的输入输出模式, 因为读数据的时候需要SDA这根线为输入模式, 往里面读数据
  关于应答信号之类的几个函数,有兴趣可以去了解一下具体的IIC的协议总结或者数据手册

发送字节函数
  

 IIC协议发送字节, 一个字节8位, 通过一个for循环发送;

txd是要发送的一个字节, IIC是先传输最高位, 所以让txd和0x80相与, 再右移7位

数据为1就给数据线(SDA)引脚写高电平, 然后txd左移一位,进入下一循环, 逐渐把8bits的数据发送完毕

读一个字节函数

 IIC发送数据是往外发送数据, 所以SDA为输出模式, 但是读取字节是把外面的读进来;
 举个形象一点的例子, 你的大脑就是24C02储存芯片, 你的身体器官就是IIC,即你的身体器官是通过IIC协议与外界进行数据交换的
 发送字节就是你用嘴巴给别人说话把你脑子里想的东西告诉别人;   而接收字节就是你通过眼睛读书, 把知识记到脑子里

 这样就很好理解了吧

  • (2) 按键部分

    • 新建一个文件Ctrl+N—>Ctrl+S保存为 key.c到Src文件夹 ; 再新建一个保存在Inc文件夹, 命名为key.h
    • 把.c和.h文件添加到工程中
      +

      • 写代码
#include "key.h"
#include "main.h" /*******************************************************************************************************【文件名称】   : key.c*【文件描述】   : 核心板板载按键驱动代码*【文件功能】   : 实现按键输入扫描功能*【主控芯片】   : STM432F407zg*【实验平台】   : STM32F4xx开发板*【编写环境】   : IAR 8.30.1*【编写时间】   : 2019-12-31*【作    者】   : 李剀(KevinLee)*【历史记录】   :   <1>  $【修改时间】$【修改内容】$【修改详情】$【修改人员】*******************************************************************************************************//*** @brief  按键处理函数* @param  mode:0,不支持连续按;1,支持连续按;* @retval 0: 没有任何按键按下     1: KEY0按下*                                 2: WKUP按下 WK_UP*/
uint8_t KEY_Scan(uint8_t mode)
{    static uint8_t key_up = 1;//按键按松开标志if (mode)key_up=1;  //支持连按          if (key_up && (KEY0 == 0 || WK_UP != 0)){HAL_Delay(10);//去抖动 key_up = 0;if(KEY0 == 0)return 1;else if(WK_UP != 0)return 2;}else if(KEY0 != 0 && WK_UP == 0)key_up = 1;return 0;// 无按键按下
}

key.h代码如下

#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/*******************************************************************************************************【文件名称】   : key.h*【文件描述】   : 核心板板载按键驱动代码*【文件功能】   : 实现按键输入扫描功能*【主控芯片】   : STM432F407zg*【实验平台】   : STM32F4xx开发板*【编写环境】   : IAR 8.30.1*【编写时间】   : 2019-12-31*【作    者】   : 李剀(KevinLee)*【历史记录】   :   <1>  $【修改时间】$【修改内容】$【修改详情】$【修改人员】*******************************************************************************************************/#define KEY0    HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)  //PE4
#define WK_UP   HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin)  //PA0#define KEY0_PRES      1   // 宏定义按键按下的键值
#define WKUP_PRES       2uint8_t KEY_Scan(uint8_t);         //按键扫描函数    #endif
  • (3) 串口重定向printf

    • 参考第三节: 串口通信(用CubeMX学习STM32);
  • (4) main.c文件

    包含头函数

    自定义变量

    • TEXT_Buffer数组存放的是等会要写入24c02芯片的数据

    主函数变量定义

    • key用于获取扫描按键值; datatemp数组作为传输数据的暂存地点

    初始化操作

    • 在/ USER CODE BEGIN 2 /下, 先初始化IIC, 在测试串口, 并用串口打印提示信息, 然后检测存储芯片是否存在
  /* USER CODE BEGIN 2 */AT24CXX_Init(); //IIC初始化printf("Usart is Ok!!!\n");printf("***************************\n");printf("**    STM32 IIC TEST     **\n");printf("**      Kevin_8_Lee      **\n");printf("** KEY0:Write  WKUP:Read **\n"); // 打印提示信息; KEY0按下写数据;WKUP按下读数据printf("***************************\n");// 检测24C02芯片是否存在while(AT24CXX_Check()){printf("未检测到24C02!\n");HAL_Delay(500);HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin); // LED0闪烁}printf("24C02 Ready!\n");/* USER CODE END 2 */

while(1)循环

  • 循环进行安检扫描, 如果KEY0按下, 就把之前定义的一个字符串数组的数据写入24C02, 如果检测到WKUP按键按下就把24C02内部的数据读取出来并打印在串口
  while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */key = KEY_Scan(0);  // 按键扫描获取键值// 如果KEY0按下,则向24C02芯片写入指定数据if (key == KEY0_PRES){printf("开始写入24C02...\n");AT24CXX_Write(0,(uint8_t *)TEXT_Buffer,SIZE);printf("传输完成\n\n");}// 如果WKUP按键按下,则从24C02芯片读出数据, 并打印在串口if (key == WKUP_PRES){printf("开始读24C02......\n");AT24CXX_Read(0,datatemp,SIZE);printf("读取到的数据为 : %s", datatemp);}// 下面的是进行一定的延时, 保证上面扫描安全运行, 同事// 以LED闪烁提示系统正在运行i++;HAL_Delay(10);if (i == 20){HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);i = 0;}}/* USER CODE END 3 */

实际效果

串口助手打印出的结果:


2020年4月19日2020年4月19日18:00:01补充:完整工程链接—>IIC通信


Don’t ever let somebody tell you, you can’t do something!!!


Author : 李光辉
date : Sun Apr 19 16:28:12 CST 2020
blog ID: Kevin_8_Lee
blog site : https://blog.csdn.net/Kevin_8_Lee

第六节:STM32基于HAL库的IIC通信相关推荐

  1. STM32 (基于HAL库) 硬件IIC读写任意AT24CXX芯片

    HAL任意AT24Cxx芯片读写: 原理我就不讲了,直接实操: 一.配置 1.使用STM32CUBEMX进行引脚配置,IIC配置如下: 2.利用串口进行数据查看,串口配置如下: 3.时钟我们选择最高7 ...

  2. 正点原子STM32(基于HAL库)0

    目录 开发环境搭建与使用 常用开发工具简介 MDK 安装 仿真器驱动安装 CH340 USB 虚拟串口驱动安装 使用MDK5 编译例程 使用串口下载程序 使用DAP 下载与调试程序 使用DAP 下载程 ...

  3. 正点原子STM32(基于HAL库)5

    目录 SRAM 实验 存储器简介 SRAM 方案简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 内存管理实验 内存管理简介 硬件设计 程序设计 程序流程图 程序解析 下载验证 SD 卡实验 ...

  4. 【STM32】HAL库——串口DMA通信(三)

    前期准备: STM32CubeMX STM32RCT6核心板 IDE Keil(MDK-ARM) 关于DMA 1. 什么是DMA? DMA(Direct Memory Access,直接存储器访问) ...

  5. 正点原子STM32(基于HAL库)3

    目录 高级定时器实验 高级定时器简介 高级定时器输出指定个数PWM 实验 高级定时器输出指定个数PWM原理 TIM1/TIM8 寄存器 硬件设计 课堂源码(输出指定个数PWM灯就闪几次) 程序设计 下 ...

  6. 正点原子STM32(基于HAL库)4

    目录 ADC 实验 ADC 简介 单通道ADC 采集实验 ADC 寄存器 硬件设计 程序设计 下载验证 单通道ADC 采集(DMA 读取)实验 ADC & DMA 寄存器 硬件设计 程序设计 ...

  7. STM32基于HAL库自由启动和关闭定时器:

    最近在利用hal库做STM32的按键消抖的时候采用进入外部中断后开启10ms定时器中断的方式,但是要求进入定时器中断后就关闭定时器,也就相应需要开启和关闭定时器的函数,然后遇到了一个兄台发布的问题及解 ...

  8. [笔记]STM32基于HAL库的SDIO+FATFS文件系统

    1.背景 要用到Bootloader升级,APP部分要写运行日志.所以在Bootloader部分的FATFS要做裁剪,裁剪到只剩只读的操作就可以了,而APP端做可读可写. 2.开发板 用的是野火的ST ...

  9. STM32机器人控制开发教程No.1驱动电机(基于HAL库)

    01 前言 本教程使用的机器人控制板拥有4个带编码器的电机接口,4个舵机接口,串口通信接口.SWD下载调试接口.航模遥控接口.USB5V输出接口以及方便与树莓派直接连接的40PIN接口等,板载资源丰富 ...

  10. STM32 串口DMA接收 Openmv / K210 整数、小数字符串数据 (基于HAL库)

    目录 前言 一.工程配置 二.串口DMA部分代码 1.源文件UART_DMA.c 2.头文件UART_DMA.h 3.stm32f1xx_it.c的修改 4.串口收发DMA测试 三.字符串数字提取代码 ...

最新文章

  1. HarmonyOS Java工程目录结构
  2. 指针都没搞懂,还能算得上 C++ 老司机?
  3. XDR3020 WiFi6 11ax使用体验 11ax性能数据
  4. Java开发:(执行系统(例cmd)命令)Runtime.getRuntime().exec()参数解释
  5. HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求
  6. 利用局域网性能测试仪保障企业网络环境
  7. 转换汇编到shellcode的过程
  8. Web前端开发面试考点指南
  9. [INS-20802] Oracle Net Configuration Assistant failed
  10. PHP5.3, PHP5.4, PHP5.5新特性
  11. 【build your own xxx】实现你自己的bind函数
  12. mysql java.util.date_jdbc-java.sql.date和java.util.date之间转换
  13. 解析 PowerJob 的序列化方案
  14. JavaScript 的call 与 apply
  15. 哲理短文一则:揭示最好的成功法则
  16. java string 数组 个数,Java - 定义一个接收String的方法,并返回一个整数数组,其中包含每个元音的数量...
  17. 为什么烂软件大行其道而好软件无人问津?
  18. 2022年华为杯中国研究生数学建模竞赛A题思路
  19. android 平板键盘布局,7款Android平板输入法横向评测,安卓平板软件HD/THD下载
  20. tp5小程序生成二维码保存到七牛云

热门文章

  1. 透过用户思维谈程序员的进阶之路
  2. 从源代码安装PostgreSQL10.1
  3. STL - queue(队列)
  4. 关于英文系统中的中文乱码的更改
  5. 关于 WCF Binding 中 OpenTimeout, CloseTimeout, SendTimeout, ReceiveTimeout 的解释
  6. 每个程序员都必须搞懂的抽象类和接口的含义以及区别
  7. 数据切分——Mysql分区表的建立及性能分析
  8. 算法与数据结构(二)三元组矩阵行列式的计算(用递归)
  9. 谜题35:一分钟又一分钟
  10. hadoop 3.x 配置历史服务器