IIC是很常见的通讯,我们先学会模拟IIC通讯,用单片机和QMA7981通讯来详解,
一:iic引脚为P3^3,P3^2,需要初始化为准双向口
P3M0 = 0x00; //设置P3.0~P3.7为双向口模式
P3M1 = 0x00;
/* I2C通信引脚定义 ,IIC通讯一共要使用2个io*/
sbit SDA = P3^3;
sbit SCL = P3^2;
二:IIC的时序,代码主要控制的就是这个时序,还要注意通讯速度。
1:延时函数,不同器件的iic通讯速率是不同的,qma7981是最快2.5us,即scl要大于2.5us转换一次电平,通讯才正常;
程序:Delay3us(); //延时3微秒
2:启动(START)SCL = 1; SDA为下降沿;但通常启动后也把SCL置低,为后面设置数据做准备,
3:停止(STOP)SCL = 1;SDA为上升沿;注意为了保证获得上升沿先给他置低,
4:应答(SACK)当单片机发出数据以后要等IIC从机应答,然后才继续下一步,应答即从机拉低SDA信号,
5:发送字节函数,一次发送8个位,用SDA脚发送。循环8次发送,发送是先发送BT7,然后BT6…BT0,先发最高位。多长发送组合好就是写命令了。
6:读取,我们读取从机返回的数据也是有时序的,数据也是通过SDA引脚读回来的,当然也读8个位,还是得循环。
但是实际使用中我们都是把一个个不同的功能拆分位不同的函数方便调用,这里有好几个时序和IIC的写重合,这样为了方便直接把读数据写为一个函数,其他部分流程复用写的。
7:读的时候需要主机停止传输,需要主机发送一个非应答信号;就是SDA=1;
三:时序的基本元素我们都写出来了,选择根据读和写的命令把这些元素组合起来,继续看此图。
1:iic写命令,有2个参数,寄存器地址和要发送的数据,注意寄存器地址有7位并且可以通过芯片上下拉做选择,是为了可以并联使用2个相同的芯片。
2: iic读命令,完整的读数据流程还是这图,注意读数据前需要发送一次写命令,只写地址和寄存器但需要加启动命令,之后才能读。
四:激活QMA7983属于工作模式,默认上电休眠。
QMA7983数据手册找到工作设置
虽然是国产芯片但就没有中文说明,翻译就是:
QMA7981有两种不同的操作模式,由寄存器(0x11) MODE_BIT控制。这些模式的主要目的是进行电源管理。模式可以通过I2C命令从一种模式转换到另一种模式,如下所示。系统上电后默认模式为待机模式。
看上图寄存器0X11默认值是0x40,改为0XC0;
五:读取QMA7983的ID号
即读0X00寄存器,读到的是0XE7,我们用例程给读出来,然后用串口打印出来。
这就是通过IO模拟IIC的方法。
六:硬件iic,比软件模拟简单,配置简单,使用方便。
1,配置允许访问I2CCFG寄存器
要在P_SW2中打开iic功能并配置管脚。默认是00000000,10110000,设置为0XB0;
程序;P_SW2 |= 0xB0; // EAXFR=1使能访问XFR I2C_S=11把I2C引脚映射到P3.2 P3.3引脚
2,配置I2CCFG寄存器(模式与速度)
主要要注意速度,QMA7981最大通讯速度为400K,在配置速度的时候不要超过400k就行,最低速的MSSPEED是63的值,代入公司计算,我们系统频率是35M,
IIC速度=35000000 ÷ 2 ÷ (130 × 2 + 4)≈ 135M
135M小于400M可以为最低速,MSSPEED配置为63,63的二进制是【11111】
程序: I2CCFG = 0xFF; //使能I2C主机模式,速度最低
3,配置为主机后要把状态清零
程序: I2CMSST = 0x00; // 状态清零
B6位是状态标志位,发送命令完成的时候会置1,注意必须软件清零。
这个判断每发一次就要调用,写成函数方便复用。
4,主机控制寄存器
各种状态都是可以通过I2CMSCR寄存器的MSCMD位控制
5,发送与接收,发送的话需要将发送的数据写到发送数据寄存器里面,需要配合控制寄存器使用。
6,等待应答,即是接收ACK命令
7,发送应答和非应答信号,判断状态寄存器最后一位,
8,iic写和读,就把上面各种命令组合起来。