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.
SCL=0 --> SDA=1 --> SCL=1 (先传送最高位MSB)
SCL=0 --> SDA=0 --> SCL=1
SCL=0 --> SDA=0 --> SCL=1
…
**Tips:**在IIC协议中,起始信号必须有. 因为IC必须知道什么时候开始了,才可以正确判断接受数据.
下面开始Cube配置+IAR编程
(1) 我所使用的STM32开发板板载了一个24C02的EEPROM存储芯片; 这个芯片就是通过IIC总线和单片机通信的;
(2) 通过GPIO软件模拟IIC通信 , 实现对24C02芯片内部数据的读写操作 .
注:
但是这里并没有用板子上的硬件 IIC, 只是用这两个对应的引脚做软件模拟 IIC
补充: 后面又加上了两个LED引脚, 用以做指示
我把我改过部分的底层代码分享在网盘里面
链接: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里面的函数去实现通信的功能
发送字节函数
txd是要发送的一个字节, IIC是先传输最高位, 所以让txd和0x80相与, 再右移7位
数据为1就给数据线(SDA)引脚写高电平, 然后txd左移一位,进入下一循环, 逐渐把8bits的数据发送完毕
读一个字节函数
举个形象一点的例子, 你的大脑就是24C02储存芯片, 你的身体器官就是IIC,即你的身体器官是通过IIC协议与外界进行数据交换的
发送字节就是你用嘴巴给别人说话把你脑子里想的东西告诉别人; 而接收字节就是你通过眼睛读书, 把知识记到脑子里
这样就很好理解了吧
#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 2
uint8_t KEY_Scan(uint8_t); //按键扫描函数
#endif
① 包含头函数
② 自定义变量
③ 主函数变量定义
④ 初始化操作
/* 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)循环
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