📄 i2cint.c
字号:
*/
U8 I2C_ReadNByte (U8 channel,U8 sla, U32 suba_type, U32 suba, U8 *s, U32 num,U16 timeout)
{
switch(channel)
{
case 0:
#if USE_I2C_CTRL0 == 1
if (num > 0) /* 判断num个数的合法性 */
{ /* 参数设置 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C0_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C0_suba = suba; /* 器件子地址 */
I2C0_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C0_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C0_suba = suba; /* 器件子地址 */
I2C0_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X*/
I2C0_sla = sla + ((suba >> 7 )& 0x0e) + 1; /* 读器件的从地址,R=1 */
I2C0_suba = suba & 0x0ff; /* 器件子地址 */
I2C0_suba_num = 1; /* 器件子地址为8+x */
}
I2C0_buf = s; /* 数据接收缓冲区指针 */
I2C0_num = num; /* 要读取的个数 */
I2C0_suba_en = 1; /* 有子地址读 */
while(os_sem_wait (wait_end0_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I20CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I20CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN */
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end0_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
case 1:
#if USE_I2C_CTRL1 == 1
if (num > 0) /* 判断num个数的合法性 */
{ /* 参数设置 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C1_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C1_suba = suba; /* 器件子地址 */
I2C1_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C1_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C1_suba = suba; /* 器件子地址 */
I2C1_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X*/
I2C1_sla = sla + ((suba >> 7 )& 0x0e) + 1; /* 读器件的从地址,R=1 */
I2C1_suba = suba & 0x0ff; /* 器件子地址 */
I2C1_suba_num = 1; /* 器件子地址为8+x */
}
I2C1_buf = s; /* 数据接收缓冲区指针 */
I2C1_num = num; /* 要读取的个数 */
I2C1_suba_en = 1; /* 有子地址读 */
while(os_sem_wait (wait_end1_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I21CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I21CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN */
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end1_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
case 2:
#if USE_I2C_CTRL2 == 1
if (num > 0) /* 判断num个数的合法性 */
{ /* 参数设置 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C2_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C2_suba = suba; /* 器件子地址 */
I2C2_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C2_sla = sla + 1; /* 读器件的从地址,R=1 */
I2C2_suba = suba; /* 器件子地址 */
I2C2_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X*/
I2C2_sla = sla + ((suba >> 7 )& 0x0e) + 1; /* 读器件的从地址,R=1 */
I2C2_suba = suba & 0x0ff; /* 器件子地址 */
I2C2_suba_num = 1; /* 器件子地址为8+x */
}
I2C2_buf = s; /* 数据接收缓冲区指针 */
I2C2_num = num; /* 要读取的个数 */
I2C2_suba_en = 1; /* 有子地址读 */
while(os_sem_wait (wait_end2_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I22CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I22CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN */
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end2_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
}
return __FALSE;
}
/*
*********************************************************************************************************
** 函数名称 :I2C_WriteNByte
** 函数功能 :向有子地址器件写入N字节数据
** 入口参数 : channel 通道 : 0--I2C0 1--I2C1 2--I2C2
** sla 器件从地址
** suba_type 子地址结构 1-单字节地址 3-8+X结构 2-双字节地址
** suba 器件内部物理地址
** *s 将要写入的数据的指针
** num 将要写入的数据的个数
** timeout 等待时间(以系统时间衡量)
** 出口参数 : TRUE 操作成功
** FALSE 操作失败
*********************************************************************************************************
*/
U8 I2C_WriteNByte(U8 channel, U8 sla, U8 suba_type, U32 suba, U8 *s, U32 num, U16 timeout)
{
switch(channel)
{
case 0:
#if USE_I2C_CTRL0 == 1
if (num > 0)/* 如果读取的个数为0,则返回错误 */
{ /* 设置参数 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C0_sla = sla; /* 读器件的从地址 */
I2C0_suba = suba; /* 器件子地址 */
I2C0_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C0_sla = sla; /* 读器件的从地址 */
I2C0_suba = suba; /* 器件子地址 */
I2C0_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X */
I2C0_sla = sla + ((suba >> 7 )& 0x0e); /* 读器件的从地址 */
I2C0_suba = suba & 0x0ff; /* 器件子地址 */
I2C0_suba_num = 1; /* 器件子地址为8+X */
}
I2C0_buf = s; /* 数据 */
I2C0_num = num; /* 数据个数 */
I2C0_suba_en = 2; /* 有子地址,写操作 */
while(os_sem_wait (wait_end0_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I20CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I20CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN*/
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end0_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
case 1:
#if USE_I2C_CTRL1 == 1
if (num > 0)/* 如果读取的个数为0,则返回错误 */
{ /* 设置参数 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C1_sla = sla; /* 读器件的从地址 */
I2C1_suba = suba; /* 器件子地址 */
I2C1_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C1_sla = sla; /* 读器件的从地址 */
I2C1_suba = suba; /* 器件子地址 */
I2C1_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X */
I2C1_sla = sla + ((suba >> 7 )& 0x0e); /* 读器件的从地址 */
I2C1_suba = suba & 0x0ff; /* 器件子地址 */
I2C1_suba_num = 1; /* 器件子地址为8+X */
}
I2C1_buf = s; /* 数据 */
I2C1_num = num; /* 数据个数 */
I2C1_suba_en = 2; /* 有子地址,写操作 */
while(os_sem_wait (wait_end1_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I21CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I21CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN*/
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end1_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
case 2:
#if USE_I2C_CTRL2 == 1
if (num > 0)/* 如果读取的个数为0,则返回错误 */
{ /* 设置参数 */
if (suba_type == 1)
{ /* 子地址为单字节 */
I2C2_sla = sla; /* 读器件的从地址 */
I2C2_suba = suba; /* 器件子地址 */
I2C2_suba_num = 1; /* 器件子地址为1字节 */
}
if (suba_type == 2)
{ /* 子地址为2字节 */
I2C2_sla = sla; /* 读器件的从地址 */
I2C2_suba = suba; /* 器件子地址 */
I2C2_suba_num = 2; /* 器件子地址为2字节 */
}
if (suba_type == 3)
{ /* 子地址结构为8+X */
I2C2_sla = sla + ((suba >> 7 )& 0x0e); /* 读器件的从地址 */
I2C2_suba = suba & 0x0ff; /* 器件子地址 */
I2C2_suba_num = 1; /* 器件子地址为8+X */
}
I2C2_buf = s; /* 数据 */
I2C2_num = num; /* 数据个数 */
I2C2_suba_en = 2; /* 有子地址,写操作 */
while(os_sem_wait (wait_end2_sem, 0) == OS_R_OK); //清令牌数
/* 清除STA,SI,AA标志位 */
I22CONCLR = (1 << 2)| /* AA */
(1 << 3)| /* SI */
(1 << 5); /* STA */
/* 置位STA,启动I2C总线 */
I22CONSET = (1 << 5)| /* STA */
(1 << 6); /* I2CEN*/
/* 等待I2C操作完成 */
if(os_sem_wait (wait_end2_sem, timeout) != OS_R_TMO)return __TRUE;
}
#endif
break;
}
return __FALSE;
}
/*
*********************************************************************************************************
** 函数名称 :__irq IRQ_I2C
** 函数名次 :硬件I2C中断服务程序。
** 入口参数 :无
** 出口参数 :无
** 说 明 :注意处理子地址为2字节的情况。
*********************************************************************************************************
*/
void __irq IRQ_I2C(void)
{
#if USE_I2C_CTRL0 == 1
/* 读取I2C状态寄存器I2DAT */
/* 按照全局变量的设置进行操作及设置软件标志 */
/* 清除中断逻辑,中断返回 */
if(I20CONSET & 1 << 3)
{
switch (I20STAT & 0xF8)
{ /* 根据状态码进行相应的处理 */
case 0x08: /* 已发送起始条件 */ /* 主发送和主接收都有 */
/* 装入SLA+W或者SLA+R */
if(I2C0_suba_en == 1)/* SLA+R */ /* 指定子地址读 */
{ I20DAT = I2C0_sla & 0xFE; /* 先写入地址 */
}
else /* SLA+W */
{ I20DAT = I2C0_sla; /* 否则直接发送从机地址 */
}
/* 清零SI位 */
I20CONCLR = (1 << 3)| /* SI */
(1 << 5); /* STA */
break;
case 0x10: /*已发送重复起始条件 */ /* 主发送和主接收都有 */
/* 装入SLA+W或者SLA+R */
I20DAT = I2C0_sla; /* 重起总线后,重发从地址 */
I20CONCLR = 0x28; /* 清零SI,STA */
break;
case 0x18:
case 0x28: /* 已发送I2DAT中的数据,已接收ACK */
if (I2C0_suba_en == 0)
{
if (I2C0_num > 0)
{ I20DAT = *I2C0_buf++;
I20CONCLR = 0x28; /* 清零SI,STA */
I2C0_num--;
}
else /* 没有数据发送了 */
{ /* 停止总线 */
I20CONSET = (1 << 4); /* STO */
I20CONCLR = 0x28; /* 清零SI,STA */
isr_sem_send (wait_end0_sem); /* 总线已经停止 */
}
}
if(I2C0_suba_en == 1) /* 若是指定地址读,则重新启动总线 */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -