江科大STM32入门——IIC通信笔记总结

wx:嵌入式工程师成长日记

(一)简介

  • STM32内部集成了硬件I2C收发电路,可以由硬件自动执行 时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担

  • 支持多主机

  • 支持7位/10位地址模式

  • 支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)

  • 支持DMA

多主机模式下,两个主机同时通讯占用总线就要发起总线仲裁。可变多主机模式,所有设备一视同仁,谁想当主机谁就站出来。

关于I2C地址,可以通过修改低位可变地址部分来避免地址冲突,也可以另外再开辟I2C总线,比较容易解决。

SCL:串行时钟线,传输CLK信号,一般是主设备向从设备提供

SDA:串行数据线,传输通信数据 I2C使用一个7bit的设备地址,一组总线最多和112个节点通信。最大通信数受限于地址空间及400pF的总线电容。

I2C总线广泛应用在 EEPROM 实时时钟 LCD 及其他芯片的接口

I2C允许相当大的工作电压范围,典型的电压基准为:+3.3V或+5V

常见的I2C总线 传输速率 的不同分为不同的模式:标准模式(100Kbit/s)、低速模式(10Kbit/s)、快速模式(400Kbit/s)、高速模式(3.4Mbit/s), 时钟频率可以被下降到零,即暂停通信。

(二)I2C框图

核心部分是数据寄存器和移位寄存器:

  • 当我们需要发送数据时,可以把一个字节数据写到数据寄存器DR,这个数据寄存器的值就会进一步转到移位寄存器里,在移位的过程中,就可以把下一个数据放到数据寄存器里等着了,一但前一个数据移位完成,下一个数据就可以无缝衔接,继续发送。其中数据寄存器转到移位寄存器时候,就会置状态寄存器的TXE位为1,表示发送数据寄存器为空。

  • 当我们需要接收时候,也是输入的数据一位一位的,从引脚移入到移位寄存器里,当一个字数据具收齐后,数据整体从移位寄存器转移到数据寄存器,同时置标志位RXNE,表示接收数据寄存器非空。这时候就可以把数据读出来了。

(三)I2C基本结构

(四)硬件I2C操作流程

1、主机发送

7位地址起始条件后的一个字节是寻址 ,10位地址起始条件后的两个字节都是寻址;STM32默认从模式,将硬件标志位置位,会因此转成主模式,表示有数据要发。

2、主机接收

设备地址:用于表示外设在总线上的唯一性,也就是同一个I2C总线上,不同的外设具有唯一的。

一个设备地址,也就是如果CPU要想访问某个外设,CPU只需向总线上发送这个外设的设备地址即可设备地址的有效位数为7位或者10位(极其少见),设备地址不包含读写位。

设备地址通常是7位

7bit设备地址 + 1bit读写位

起始位(S):在SCL为高电平时,SDA由高电平变为低电平。

结束位(P):在SCL为高电平时,SDA由低电平变为高电平。

复制代码
//IO方向设置#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

起始和结束信号:

复制代码
void IIC_Start(void){    SDA_OUT();//输出模式    IIC_SCL = 1;    IIC_SDA = 1;    delay_us(4);    IIC_SDA = 0;    delay_us(4);    IIC_SCL = 0;}

void IIC_Stop(void){    SDA_OUT();//SDA线输出模式    IIC_SCL = 0;    IIC_SDA = 0;    delay_us(4);    IIC_SCL = 1;    IIC_SDA = 1;    delay_us(4);}

发送字节:

复制代码
void IIC_Send_Byte(u8 txd){    u8 t;    SDA_OUT();    IIC_SCL = 0; //拉低时钟    for(t = 0; t < 8; t++){        if((txd&0x80)>>7){            IIC_SDA = 1;        }else{            IIC_SDA = 0;        }        txd <<=1; //左移7位后,拿到数据,右移1位,保证高位永远是高位        delay_us(2);        IIC_SCL = 1;        delay_us(2);        IIC_SCL = 0;//高电平期间数据保持不变        delay_us(2); //数据有效性    }}

接收字节:

复制代码
void IIC_Read_Byte(unsigned char ack){    unsigned char i,receive=0;	SDA_IN();        //SDA设置为输入    for(i = 0;i < 8; i++)	{        IIC_SCL=0;         delay_us(2);	IIC_SCL=1;        receive<<=1;        if(READ_SDA)receive++;   		delay_us(1);     }					     if (!ack)        IIC_NAck();        //发送nACK    else        IIC_Ack();         //发送ACK       return receive;}

应答信号:

复制代码
void IIC_NAck(void){    SDA_OUT();//sda线输出模式    IIC_SCL = 0;    IIC_SDA = 1;    delay_us(2);    IIC_SCL = 1;    delay_ms(2);    IIC_SCL = 0;}

void IIC_Ack(void){    SDA_OUT();//SDA线输出模式    IIC_SCL = 0;    IIC_SDA = 0;    delay_us(2);    IIC_SCL = 1;    delay_ms(2);    IIC_SCL = 0;}

应答(ACK):

I2C数据以字节(即8bits)为单位传输,每个字节传输完后都会有一个ACK应答信号。应答信号的时钟是由主设备产生的。

当采集IIC上的数据时,其时钟线SCL必须是高电平且SDA的数据必须保持稳定不变

在SCL为低电平的时候,SDA上的数据可以进行跳变

每8bit数据传输结束,需要一个ACK

起止信号都由MASTER发出,而ACK则可能由MASTER或者SLAVE来发出

(五)IIC传输流程

针对SCL低放高取:

相关推荐
双叶8364 小时前
(C语言)虚数运算(结构体教程)(指针解法)(C语言教程)
c语言·开发语言·数据结构·c++·算法·microsoft
有个人神神叨叨5 小时前
OpenAI发布的《Addendum to GPT-4o System Card: Native image generation》文件的详尽笔记
人工智能·笔记
安全方案6 小时前
精心整理-2024最新网络安全-信息安全全套资料(学习路线、教程笔记、工具软件、面试文档).zip
笔记·学习·web安全
Lhj06167 小时前
stm32 can 遥控帧的问题
stm32·单片机·嵌入式硬件
序属秋秋秋7 小时前
算法基础_基础算法【高精度 + 前缀和 + 差分 + 双指针】
c语言·c++·学习·算法
慵懒学者7 小时前
15 网络编程:三要素(IP地址、端口、协议)、UDP通信实现和TCP通信实现 (黑马Java视频笔记)
java·网络·笔记·tcp/ip·udp
想睡hhh7 小时前
c语言数据结构——八大排序算法实现
c语言·数据结构·排序算法
KeithTsui8 小时前
GCC RISCV 后端 -- 控制流(Control Flow)的一些理解
linux·c语言·开发语言·c++·算法
昊虹AI笔记8 小时前
STM32_HAL之程序编写、编译、烧写、上板测试初体验
stm32
三歪爱三玖9 小时前
【蓝桥杯】单片机设计与开发,速成备赛
单片机·职场和发展·蓝桥杯