文章目录
IO拓展件:PCF8574T
开发板:STM32F429
参考:
1、[正点原子]《STM32F429 开发指南(HAL 库版)》
2、STM32CubeMX使用之I2C通讯
1、理论基础
1.1、物理层特点
- “总线”指多个设备共用的信号线。在I2C 通讯总线中,支持多个主机及多个从机
- 一个 I2C 有两条总线, 数据线 (SDA) 用来表示数据,时钟线 (SCL)用于数据收发同步。
- 每个连接到总线的设备都有一个独立的地址
从机地址可以是 7位或 10 位 - 总线通过上拉电阻接到电源。
当 I2C 设备空闲时,会输出高阻态,当所有设备都空闲时,由上拉电阻把总线拉成高电平 - 具有仲裁机制 (开漏输出:线与,低电平有效)
多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线 - 三种传输模式
标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s - 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制
- 主机Master 从机Slave
1.2、通信过程
1.2.1、通讯起始和停止信号
- 空闲时 sda和scl都是高电平
- 起始位s 停止位p
1.2.2、有效数据
- scl为高电平时数据有效
- 每次数据传输都以字节为单位,每次传输的字节数不受限制
- scl 1 sda 1 表示1
- scl 1 sda 0 表示0
1.2.3、读写过程
- 主机写数据到从机 (应答ACK)
DATA数据包的大小为 8 位
- 从机写数据到主机
主机等待从机的应答
1.3、IIC架构
- 数据寄存器 DR
- 地址寄存器OAR1
- 第二地址寄存器OAR2
- 校验寄存器PEC
- 控制寄存器CR1/2
- 状态寄存器SR1/2
- 控制寄存器CCR
2、工程建立(硬件iic)
ST公司实现了硬件的iic,但据说用着不方便,可以参考第3节软件实现
2.1、配置步骤
- RCC
设置外部晶振、PLL、主频 - 调试口
选择调试模式,选择调试IO口 - IO分配
打开相应外设开关 - IIC参数
设置速率、地址、主从、时序
2.2、cubemx具体配置
- 选择开漏模式(一般只有这个选项)
- 参数设置
3、应用(软件iic)
- 利用EEPROM 24C02 测试
- 这里先用标准库
3.1、原理图
3.2、端口模式+位带操作
端口模式设置
GPIO 端口模式寄存器 (GPIOx_MODER) (x = A…I)
- 3(二进制11),将11左移10位,取反再与,使MODER5的10、11位寄存器清零
0左移10位,使配置位10为0;即配置端口5为输入模式
1左移10位,即配置位10为1;即配置端口5为输出模式
#define SDA_IN() {
GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=0<<5*2;} //PH5输入模式
#define SDA_OUT() {
GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=1<<5*2;} //PH5输出模式
位带操作
stm32之bit-band(位带)操作
3.3、iic头文件
- 代码均来自正点原子,只是改了一点点
#ifndef _MYIIC_H
#define _MYIIC_H
#include "main.h"
#include "stm32f4xx_hal_gpio.h"
//IO口位带操作
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO方向设置
#define SDA_IN() {
GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=0<<5*2;} //PH5输入模式
#define SDA_OUT() {
GPIOH->MODER&=~(3<<(5*2));GPIOH->MODER|=1<<5*2;} //PH5输出模式
//IO口地址映射
#define GPIOH_ODR_Addr (GPIOH_BASE+20) //0x40021C14
#define GPIOH_IDR_Addr (GPIOH_BASE+16) //0x40021C10
//IO操作
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n) //输出 gpio_writepin
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n) //输入 gpio_readpin
#define IIC_SCL PHout(4) //SCL
#define IIC_SDA PHout(5) //SDA
#define READ_SDA PHin(5) //输入SDA
#define CPU_FREQUENCY_MHZ 180 // STM32时钟主频 用于微秒级延时
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void