NXP-JN516x的IIC总结JN516x的SI总线可以超过一个主设备,但是多个主设备不可以同时使用,为了避免这类操作,内部会有一个仲裁机制。当是能IIC时,DIO14会是时钟Pin,DIO15会是双向的数据Pin,但是这两个信号都可以被映射到DIO16和DIO17。时钟是根据外设时钟分频得到的,其要求系统的外部时钟源必须在16MHz以上。对于这个芯片的手册,没有提供寄存器版本,只有操作其库函数去配置其对应功能。
主设备涉及到的API函数如下:
vAHI_SiMasterConfigure
vAHI_SiMasterDisable
bAHI_SiMasterSetCmdReg
vAHI_SiMasterWriteSlaveAddr
vAHI_SiMasterWriteData8
u8AHI_SiMasterReadData8
bAHI_SiMasterPollBusy
bAHI_SiMasterPollTransferInProgress
bAHI_SiMasterCheckRxNack
bAHI_SiMasterPollArbitrationLost
1 初始化配置函数函数原型:
voidvAHI_SiMasterConfigure(bool_t bPulseSuppressionEnable ,bool_t bInterruptEnable ,uint8 u8PreScaler );
功能描述:
配置和使能IIC的主设备,再使用其他的主设备IIC的API函数之前,必须使用这个配置函数。若是想再使用完了IIC主设备,想关闭IIC功能则再后续可使用vAHI_SiMasterDisable()函数。
总线速度的是由16MHz的外设时钟通过分频系数分下来的,其使用的公式如下:
Operatingfrequency = 16/[( PreScaler + 1) x 5] MHz
这个PreScaler(分频系数)是一个8位的值。一个脉冲滤波的最小标准为62.5ns,不然会被滤波滤除。
参数:
bPulseSuppressionEnableEnable/disable pulse suppression filter:
TRUE - enable
FALSE - disable
bInterruptEnableEnable/disable Serial Interface interrupt:
TRUE - enable
FALSE - disable
u8PreScaler8-bit clock prescaler (see above)
2 关闭IIC主设备函数函数原型:
voidvAHI_SiMasterDisable(void);
功能描述:
禁用IIC主设备,如果后续想使能其功能可以调用vAHI_SiMasterConfigure()函数。
3 发送命令函数函数原型:
bool_tbAHI_SiMasterSetCmdReg(bool_t bSetSTA,bool_t bSetSTO ,bool_t bSetRD ,bool_t bSetWR ,bool_t bSetAckCtrl ,bool_t bSetIACK );
功能描述:
配置IIC总线命令和将主设备的缓存数据传送到总线上。传输命令有四个-开始,停止,写和读,这个函数将命令有序的组合在一起发送出去,有效的命令组合如下表所示:
file:///C:/Users/binyo/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
图1 有效命令组合
上述命令的组合在使用函数时会返回TRUE,其他的非上述组合命令是无效的,使用的时候会返回FALSE。
在调用完vAHI_SiMasterWriteSlaveAddr()函数后应该立即使用此函数,这样才能将目标从设备地址从缓存buffer发送到总线上;同样的,调用完vAHI_SiMasterWriteData()函数后应该立即使用此函数,这样才能将需要发送的数据从发送buffer中发送到总线上。
参数:
bSetSTA Generate START bit to gain control ofthe SI bus (must not be
enabled withSTOP bit):
E_AHI_SI_START_BIT
E_AHI_SI_NO_START_BIT
bSetSTO Generate STOP bit to release controlof the SI bus (must not
be enabled withSTART bit):
E_AHI_SI_STOP_BIT
E_AHI_SI_NO_STOP_BIT
bSetRD Read from slave (cannot be enabledwith slave write):
E_AHI_SI_SLAVE_READ
E_AHI_SI_NO_SLAVE_READ
bSetWR Write to slave (cannot be enabledwith slave read):
E_AHI_SI_SLAVE_WRITE
E_AHI_SI_NO_SLAVE_WRITE
bSetAckCtrl Send ACK or NACK to slave after each byteread:
E_AHI_SI_SEND_ACK(to indicate ready for next byte)
E_AHI_SI_SEND_NACK(to indicate no more data required)
bSetIACK Generate interrupt acknowledge(should not normally be
required asinterrupt is cleared by the interrupt handler):
E_AHI_SI_IRQ_ACK
E_AHI_SI_NO_IRQ_ACK(normally the required setting)
返回值:
TURE:表示发送命令合法;
FALSE;表示发送命令不合法(设备不会发生任何响应);
4 从设备地址写入函数函数原型:
voidvAHI_SiMasterWriteSlaveAddr(uint8 u8SlaveAddress ,bool_t bReadStatus );
功能描述:
设置IIC通信的从设备地址,必须指定从设备地址和需要的操作(读或者写),这个函数将上述内容写入到主设备的发送缓存中,再调用了bAHI_SiMasterSetCmdReg()函数以后这些内容会发送到总线上。
从设备地址可以是7位或者10位,两种模式如下:
7位模式,参数u8SlaveAddress必须是一个7位的从设备地址;
10位模式,参数u8SlaveAddress必须设置为011110xx,xx表示10位地址的最高两位,011110告诉从设备这是一个从地址命令,再下一个传输交互时会将剩下的8位地址传送出来,通过调用函数vAHI_SiMasterWriteData8()来实现。
参数:
u8SlaveAddress Slave address (see above)
bReadStatus Operation to perform on slave(read or write):
TRUE - configure a read
FALSE - configure a write
5 发送8位数据函数函数原型:
voidvAHI_SiMasterWriteData8(uint8 u8Out );
功能描述:
写一个8位的数据到发送缓存中,当调用bAHI_SiMasterSetCmdReg()函数时,该8位数据会发送到总线上。
参数:
u8Out 8 bits of data to transmit
6 读8位数据函数函数原型:
uint8u8AHI_SiMasterReadData8(void);
功能描述:
从总线上获取从设备发送出来的一个8位的的数据。
7 判断总线忙函数函数原型:
bool_tbAHI_SiMasterPollBusy(void);
功能描述:
检查总线是否忙碌,其他主设备是否在操作总线。
返回值:
TRUE:忙碌;
FALSE:不忙;
8 主设备发送是否完成函数函数原型:
bool_tbAHI_SiMasterPollTransferInProgress(void);
功能描述:
判断主设备发出的传送过程是否完成。
返回值:
TRUE:正在传送过程中;
FALSE:传送完成;
9 检查ACK函数函数原型:
bool_tbAHI_SiMasterCheckRxNack(void);
功能描述:
该函数检查主设备是否收到从设备发送出来的ACK或者NACK信号,如果一个NACK被接收到了,表示主设备应该停止向从设备发送数据。
返回值:
TRUE:收到从设备的NACK信号
FLASE:收到从设备的ACK信号
10 主设备仲裁函数函数原型:
bool_tbAHI_SiMasterPollArbitrationLost(void);
功能描述:
检查主设备是否失去了操作总线的能力。
返回值:
TURE:丢失操作总线权利;
FLASE:没有丢失权利;
操作实例配置时钟芯片SD2505(iic)从设备地址为0x32
IIC的函数编写:
1,使能IIC,并配置其速度为100k,不使能中断,使能滤波:
vAHI_SiMasterConfigure(TRUE,FLASE,31 );
2,发送7位的从设备地址,并写入或者读取到总线:
I2C_Send_Slaveaddress(unsignedchar addr,bool opration)
{
vAHI_SiMasterWriteSlaveAddr(addr,opration);//发送从设备地址0x32,并且写入操作(TRUE为读,FLASE为写)
bAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT,E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE ,E_AHI_SI_SEND_ACK , E_AHI_SI_NO_IRQ_ACK);//开始并且写
while(bAHI_SiMasterPollTransferInProgress();)//等待传输完成
while(bAHI_SiMasterCheckRxNack(););//等待从设备ACK信号
}
3,发送主设备的8位数据到总线上:
I2C_Send_8data(unsignedchar data)
{
vAHI_SiMasterWriteData8(data );//发送8位数据到缓存区
bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE ,E_AHI_SI_SEND_ACK , E_AHI_SI_NO_IRQ_ACK);//写命令
while(bAHI_SiMasterPollTransferInProgress();)//等待传输完成
while(bAHI_SiMasterCheckRxNack(););//等待从设备ACK信号
}
4,读取从设备的8位数据
I2C_Read_8data(boolACK)
{
Unsigned charvalue;
bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,E_AHI_SI_NO_STOP_BIT, E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE ,E_AHI_SI_SEND_ACK , E_AHI_SI_NO_IRQ_ACK);//读命令
value = u8AHI_SiMasterReadData8();
while(bAHI_SiMasterPollTransferInProgress();)//等待传输完成
bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE , ACK ,E_AHI_SI_NO_IRQ_ACK);//是否发送ACK命令(ACK= E_AHI_SI_SEND_ACK发送ACK给从设备,ACK= E_AHI_SI_SEND_NACK发送NACK给从设备)
}
5,发送停止信号
I2C_Stop()
{
bAHI_SiMasterSetCmdReg(E_AHI_SI_NO_START_BIT,E_AHI_SI_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE , ACK ,E_AHI_SI_NO_IRQ_ACK);//发送停止信号
}
配置芯片(倒计时中断配置):
1,开总线
vAHI_SiMasterConfigure(TRUE,FLASE ,31 );
2,允许写:
VoidWriteOn()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x10); //控制器寄存器2
I2C_Send_8data(0x80); //允许写1位置1
I2C_Stop();
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x0f); //控制器寄存器1
I2C_Send_8data(0x84); //允许写2位置1,允许写3位置1
I2C_Stop();
}
3,关闭写
Void WriteOff()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x10); //控制器寄存器2
I2C_Send_8data(0x00); //允许写1位置0
I2C_Stop();
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x0f); //控制器寄存器1
I2C_Send_8data(0x00); //允许写2位置0,允许写3位置0
I2C_Stop();
}
4,清除中断
Void Clear_Int()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x10); //控制器寄存器2
I2C_Send_8data(0x0f); //允许写1位置0
I2C_Stop();
}
5,开启倒计时中断
Void Enable_Int()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x10); //控制器寄存器2
I2C_Send_8data(0xf4); //允许写1位置0
I2C_Stop();
}
6,配置倒计时中断的时间基础(min)
VoidTimerbase_Set()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x11); //控制器寄存器3
I2C_Send_8data(0x20); //允许写1位置0
I2C_Stop();
}
7,配置倒计时计数值
Void Counter_Set(unsignedint count)
{
unsigned char temp1,temp2,temp3;
temp1= count &0xff;
temp2 = (count>> 8)&0xff;
temp3 = (count>> 16)&0xff;
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x12); //计数寄存器1;
I2C_Send_8data(temp1); //允许写1位置0
I2C_Stop();
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x13); //计数寄存器12
I2C_Send_8data(temp2); //允许写1位置0
I2C_Stop();
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x14); //计数寄存器12
I2C_Send_8data(temp3); //允许写1位置0
I2C_Stop();
}
|