亲爱的观众朋友,我是你们的今天的代班DJ~,不对,中年好友。今天讲讲I2C总线,在抖音上搜了下,说SPI、I2C、UART是三大电子通讯协议,咱是菜鸟,等哪天真成工程师了,再回过头来看看总结得对不对。 I2C是飞利浦公司1980年代初设计的(80后大叔),全称是Inter-Integrated Circuit,中文叫集成电路总线,速率呢基本是低速,100Kbps,400Kbps,3.4Mbps,5Mbps。 物理特点说说,两根线搞定所有,一般两线是开漏输出,然后线路配两个上拉电阻,线路上默认是高电平。支持主从、多主从模式,有冲突检测机制,为得就是两根线上可以挂很多主和从设备,但同时只能一个主占用线路并和一个从设备(所有设备要求7位编号唯一)进行通信。然后再着重说说,这两根线呢,一根是SCL(Serial Clock),一根是SDA(Seriol Data自嗨扩写),SCL给时钟信号,SDA按位给数据信号。它俩的一组合给出开始与结束信号。SCL高电平时,SDA给出一个下拉变位信号,代表开始占位了。再在SCL高电平时,给出一个上拉信号,Say Bye! 灵魂画师登场:
I2C和SPI不一样的呢,它的协议还定义了时序,直白点每次传8位,第9位是应答,需要强行拉低电平才行。数据意义呢,先传7位地址+1位方向(写0/读1),再传地址,再传数据。 这里提一下,NUC970读的流程是用先写指令向从发送地址,再发开始符,再读,再确认,再结束。 芯片说明来,我们说说NUC970这款芯片对I2C的支持。支持两个I2C通道。 然后呢,照常,PG0,PG1是I2C0,PG2,PG3|PH2,PH3|PI3,PI4作为I2C1,当然这仨只有一个可以设置为I2C1。 按顺序,要设置端口为I2C,就先把引脚设置为I2C,往对接寄存器里写0x8(MFB_GPG0|SYS_GPG_MFPL[3:0]) 然后使能I2C时钟,CLK_PCLKEN1[0]与CLK_PCLKEN1[1]。
然后呢就是写、读操作。 写时序呢,先开始信号,写入地址+写位,再写入数据,停止。 具体的写操作比时序复杂点, 先写值将时钟频率调整为100kbit/s或400kbit/s。这里的公式是32Mhz/5*目标 -1 。 再写一次传递的字节数,最大为4,从高位开始传。 再设置I2C_EN=1 非软件控制模式。 将地址写到I2C[15:8],将值写到I2C[7:0]。 设置启动位与写位。 等待中断或者I2C_TIP变为0(传输结束)
读时序:先开始信号,写入地址+写位,再写入读地址,重给启动信号,写入地址+读位,启动读,发送不确认位,再结束。(这边案例只读了一个字节,不知道连续的字节读取会怎么样)。 继续将分频数写到寄存器里。 设置写字节数为0x00,i2C_EN=1。 写入地址+写位,设置启动和写标志 等待中断或者I2C_TIP变为0; 读取CSR中的反馈寄存器,应该为0,再写入读取地址,设置启动和写标志; 等待中断或者I2C_TIP变为0; 发送结束位置。 写入地址+读位,设置启动和写位; 等待中断或者I2C_TIP变为0; 设置读位,设置NACK,设置停止位; 从RXR[7:0]中读取字节。
另外,NUC970支持软件模式,说白了手动操作SCL与SDA电平。配置的话是把I2C_EN设置为0,然后操作SDW与SCW位。这边就不多说了。
寄存器说明说明下比较重要的寄存器。 I2Cn_CSR Control and Status Register ACK、BUSY、AL、TIP、Tx_num、IF、IE、I2C_EN I2Cn_DIVIDER Clock Prescale Register DIVIDER I2Cn_CMDR Command Register START、STOP、READ、WRITE、ACK I2Cn_SWR Software Control Register SDR SCR SDW SCW I2Cn_RXR Data Receiver Register 当下只使用了0-7位! I2Cn_TXR Data Transmit Register 已使用了0-31位
|