NXP-JN516x的IIC总结
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 初始化配置函数
函数原型:
void vAHI_SiMasterConfigure(bool_t bPulseSuppressionEnable ,bool_t bInterruptEnable ,uint8 u8PreScaler );
功能描述:
配置和使能IIC的主设备,再使用其他的主设备IIC的API函数之前,必须使用这个配置函数。若是想再使用完了IIC主设备,想关闭IIC功能则再后续可使用vAHI_SiMasterDisable()函数。
总线速度的是由16MHz的外设时钟通过分频系数分下来的,其使用的公式如下:
Operating frequency = 16/[( PreScaler + 1) x 5] MHz
这个PreScaler(分频系数)是一个8位的值。一个脉冲滤波的最小标准为62.5ns,不然会被滤波滤除。
参数:
bPulseSuppressionEnable Enable/disable pulse suppression filter:
TRUE - enable
FALSE - disable
bInterruptEnable Enable/disable Serial Interface interrupt:
TRUE - enable
FALSE - disable
u8PreScaler 8-bit clock prescaler (see above)
2 关闭IIC主设备函数
函数原型:
void vAHI_SiMasterDisable(void);
功能描述:
禁用IIC主设备,如果后续想使能其功能可以调用vAHI_SiMasterConfigure()函数。
3 发送命令函数
函数原型:
bool_t bAHI_SiMasterSetCmdReg(bool_t bSetSTA ,bool_t bSetSTO ,bool_t bSetRD ,bool_t bSetWR ,bool_t bSetAckCtrl ,bool_t bSetIACK );
功能描述:
配置IIC总线命令和将主设备的缓存数据传送到总线上。传输命令有四个-开始,停止,写和读,这个函数将命令有序的组合在一起发送出去,有效的命令组合如下表所示:
图1 有效命令组合
上述命令的组合在使用函数时会返回TRUE,其他的非上述组合命令是无效的,使用的时候会返回FALSE。
在调用完vAHI_SiMasterWriteSlaveAddr()函数后应该立即使用此函数,这样才能将目标从设备地址从缓存buffer发送到总线上;同样的,调用完vAHI_SiMasterWriteData()函数后应该立即使用此函数,这样才能将需要发送的数据从发送buffer中发送到总线上。
参数:
bSetSTA Generate START bit to gain control of the SI bus (must not be
enabled with STOP bit):
E_AHI_SI_START_BIT
E_AHI_SI_NO_START_BIT
bSetSTO Generate STOP bit to release control of the SI bus (must not
be enabled with START bit):
E_AHI_SI_STOP_BIT
E_AHI_SI_NO_STOP_BIT
bSetRD Read from slave (cannot be enabled with slave write):
E_AHI_SI_SLAVE_READ
E_AHI_SI_NO_SLAVE_READ
bSetWR Write to slave (cannot be enabled with slave read):
E_AHI_SI_SLAVE_WRITE
E_AHI_SI_NO_SLAVE_WRITE
bSetAckCtrl Send ACK or NACK to slave after each byte read:
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 as interrupt is cleared by the interrupt handler):
E_AHI_SI_IRQ_ACK
E_AHI_SI_NO_IRQ_ACK (normally the required setting)
返回值:
TURE:表示发送命令合法;
FALSE;表示发送命令不合法(设备不会发生任何响应);
4 从设备地址写入函数
函数原型:
void vAHI_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位数据函数
函数原型:
void vAHI_SiMasterWriteData8(uint8 u8Out );
功能描述:
写一个8位的数据到发送缓存中,当调用bAHI_SiMasterSetCmdReg()函数时,该8位数据会发送到总线上。
参数:
u8Out 8 bits of data to transmit
6 读8位数据函数
函数原型:
uint8 u8AHI_SiMasterReadData8(void);
功能描述:
从总线上获取从设备发送出来的一个8位的的数据。
7 判断总线忙函数
函数原型:
bool_t bAHI_SiMasterPollBusy(void);
功能描述:
检查总线是否忙碌,其他主设备是否在操作总线。
返回值:
TRUE:忙碌;
FALSE:不忙;
8 主设备发送是否完成函数
函数原型:
bool_t bAHI_SiMasterPollTransferInProgress(void);
功能描述:
判断主设备发出的传送过程是否完成。
返回值:
TRUE:正在传送过程中;
FALSE:传送完成;
9 检查ACK函数
函数原型:
bool_t bAHI_SiMasterCheckRxNack(void);
功能描述:
该函数检查主设备是否收到从设备发送出来的ACK或者NACK信号,如果一个NACK被接收到了,表示主设备应该停止向从设备发送数据。
返回值:
TRUE:收到从设备的NACK信号
FLASE:收到从设备的ACK信号
10 主设备仲裁函数
函数原型:
bool_t bAHI_SiMasterPollArbitrationLost(void);
功能描述:
检查主设备是否失去了操作总线的能力。
返回值:
TURE:丢失操作总线权利;
FLASE:没有丢失权利;
操作实例
配置时钟芯片SD2505(iic)从设备地址为0x32
IIC的函数编写:
1,使能IIC,并配置其速度为100k,不使能中断,使能滤波:
vAHI_SiMasterConfigure(TRUE,FLASE ,31 );
2,发送7位的从设备地址,并写入或者读取到总线:
I2C_Send_Slaveaddress(unsigned char 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(unsigned char 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(bool ACK)
{
Unsigned char value;
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);//发送停止信号
}
配置芯片(倒计时中断配置):
- 开总线
vAHI_SiMasterConfigure(TRUE,FLASE ,31 );
2,允许写:
Void WriteOn()
{
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)
Void Timerbase_Set()
{
I2C_Send_Slaveaddress(0x32,FALSE);
I2C_Send_8data(0x11); //控制器寄存器3
I2C_Send_8data(0x20); //允许写1位置0
I2C_Stop();
}
7,配置倒计时计数值
Void Counter_Set(unsigned int 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();
}