📄 lpc214x test.c
字号:
}
}
}
break;
case 0x40: //已发送SLA+R,已接收ACK
if (I2CPara[1].BytesNum <= 1) //如果是最后一个字节
{
I2C1CONCLR = 1 << 2; //下次发送非应答信号
}
else
{
I2C1CONSET = 1 << 2; //下次发送应答信号
}
I2C1CONCLR = 0x28; //清零SI,STA
break;
case 0x20: //已发送SLA+W,已接收非应答
case 0x30: //已发送I2C1DAT中的数据,已接收非应答
case 0x38: //在SLA+R/W或数据字节中丢失仲裁
case 0x48: //已发送SLA+R,已接收非应答
I2C1CONCLR = 0x28;
I2CPara[1].End = 0xFF;
break;
case 0x50: //已接收数据字节,已返回ACK
*I2CPara[1].Buf++ = I2C1DAT;
I2CPara[1].BytesNum--;
if (I2CPara[1].BytesNum == 1)//接收最后一个字节
{
I2C1CONCLR = 0x2C; //STA,SI,AA = 0
}
else
{
I2C1CONSET = 0x04; //AA=1
I2C1CONCLR = 0x28;
}
break;
case 0x58: //已接收数据字节,已返回非应答
*I2CPara[1].Buf++ = I2C1DAT; //读取最后一字节数据
I2C1CONSET = 0x10; //结束总线
I2C1CONCLR = 0x28;
I2CPara[1].End = 1;
break;
default:
break;
}
VICVectAddr = 0x00; //中断处理结束
}
#endif //The #endif of #ifdef CPU_I2C1_EN
/****************************************************************************
* 函数名称 :CPU_I2C_Init() *
* 函数功能 :I2C1初始化 *
* 入口参数 :freq I2C总线频率(最大400K),单位:Hz *
* port I2C模块号 *
* mode I2C工作模式 *
* irq_pri I2C中断优先级 *
* addr I2C作为从机时的设备地址。用作主机时无效 *
* 出口参数 :无 *
*****************************************************************************/
void CPU_I2C_Init(INT8U port, INT32U freq, INT8U mode, INT8U irq_pri, INT8U addr)
{
if (freq > 400000) freq = 400000;
switch(port)
{
#ifdef CPU_I2C0_EN
case 0: //设置I2C0控制口有效
CPU_IO_SetP0Fnct(2,1); //SCL
CPU_IO_SetP0Fnct(3,1); //SDA
I2SCLH = (Fpclk/freq + 1) / 2; //设定I2C0时钟
I2SCLL = (Fpclk/freq)/2;
if(CPU_I2C_MASTER == mode)
{ //清除STAC、AAC和SIC位
I2CONSET = 0x40; //AA=0,主模式;I2EN=1,I2C使能
I2CONCLR = 0x2C;
}
else
{
I2ADR = addr & 0xFE; //设置从机地址
I2CONCLR = 0x28; //清除STAC和SIC位
I2CONSET = 0x44; //AA=1,从模式;I2EN=1,I2C使能
}
//设置I2C0中断允许
CPU_VIC_SetIntr(CPU_VECT_IRQ, CPU_I2C0_INT, irq_pri, (INT32U)CPU_I2C_IRQ0);
break;
#endif
#ifdef CPU_I2C1_EN
case 1:
CPU_IO_SetP0Fnct(11,3); //SCL
CPU_IO_SetP0Fnct(14,3); //SDA
I2C1SCLH = (Fpclk/freq + 1) / 2; //设定I2C1时钟
I2C1SCLL = (Fpclk/freq)/2;
if(CPU_I2C_MASTER == mode)
{
I2C1CONCLR = 0x2C; //清除STAC、AAC和SIC位
I2C1CONSET = 0x40; //AA=0,主模式;I2EN=1,I2C使能
}
else
{
I2C1ADR = addr & 0xFE; //设置从机地址
I2C1CONCLR = 0x28; //清除STAC和SIC位
I2C1CONSET = 0x44; //AA=1,从模式;I2EN=1,I2C使能
}
//设置I2C1中断允许
CPU_VIC_SetIntr(CPU_VECT_IRQ, CPU_I2C1_INT, irq_pri, (INT32U)CPU_I2C_IRQ1);
break;
#endif
default:
break;
}
}
/****************************************************************************
* 函数名称:CPU_I2C_WriteByte() *
* 函数功能:向无子地址器件发送1字节数据。 *
* 入口参数:port I2C器件编号 *
* sla 器件地址 *
* dat 要发送的数据 *
* 出口参数:返回值为0时表示出错,为1时表示操作正确,为2时表示I2C模块号错误。 *
* 说明: 使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式 *
*****************************************************************************/
INT8U CPU_I2C_WriteByte(INT8U port, INT8U sla, INT8U dat)
{
//参数设置
if(port <= 1)
{
I2CPara[port].SlAddr = sla; // 写操作的器件地址
I2CPara[port].Buf = &dat; // 待发送的数据
I2CPara[port].BytesNum = 1; // 发送1字节数据
I2CPara[port].SubAddrEn = 0; // 无子地址
I2CPara[port].End = 0;
if(port)
{
CPU_I2C1_MStart();
}
else
{
CPU_I2C0_MStart();
}
while(0 == I2CPara[port].End);
if(1 == I2CPara[port].End)
{
return(1);
}
else
{
return(0);
}
}
else
return(2);
}
/****************************************************************************
* 函数名称:CPU_I2C_ReadByte() *
* 函数功能:向无子地址器件读取1字节数据。 *
* 入口参数:sla 器件地址 *
* dat 接收数据的变量指针 *
* 出口参数:返回值为0时表示操作出错,为1时表示操作正确。 *
* 说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式 *
*****************************************************************************/
INT8U CPU_I2C_ReadByte(INT8U port, INT8U sla, INT8U *dat)
{
//参数设置
if(port <= 1)
{
I2CPara[port].SlAddr = sla+1; // 读操作的器件地址
I2CPara[port].Buf = dat;
I2CPara[port].BytesNum = 1;
I2CPara[port].SubAddrEn = 0; // 无子地址
I2CPara[port].End = 0;
if(port)
{
CPU_I2C1_MStart();
}
else
{
CPU_I2C0_MStart();
}
while(0 == I2CPara[port].End);
if(1 == I2CPara[port].End)
return(1);
else
return(0);
}
else
return(2);
}
/****************************************************************************
* 函数名称 :CPU_I2C_ReadNByte() *
* 函数功能 :从有子地址器件任意地址开始读取N字节数据 *
* 入口参数 :sla 器件从地址 *
* suba_type 子地址结构 1-单字节地址 2-8+X结构 2-双字节地址 *
* suba 器件内部子地址 *
* s 数据接收缓冲区指针 *
* num 读取的个数 *
* 出口参数 : TRUE 操作成功 *
* FALSE 操作失败 *
*****************************************************************************/
INT8U CPU_I2C_ReadNByte(INT8U port, INT8U sla, INT32U suba_type, INT32U suba, INT8U *s, INT32U num)
{
if(port > 1)
return(FALSE);
if (num > 0) //判断num个数的合法性
{ //参数设置
if (suba_type == 1)
{ //子地址为单字节
I2CPara[port].SlAddr = sla + 1; //读器件的从地址,R=1
I2CPara[port].SubAddr = suba; //器件子地址
I2CPara[port].SubAddrNum = 1; //器件子地址为1字节
}
if (suba_type == 2)
{ //子地址为2字节
I2CPara[port].SlAddr = sla + 1; //读器件的从地址,R=1
I2CPara[port].SubAddr = suba; //器件子地址
I2CPara[port].SubAddrNum = 2; //器件子地址为2字节
}
if (suba_type == 3)
{ //子地址结构为8+X*/
I2CPara[port].SlAddr = sla+((suba >>7)&0x0e)+1; //读器件的从地址,R=1
I2CPara[port].SubAddr = suba&0x0ff; //器件子地址
I2CPara[port].SubAddrNum = 1; //器件子地址为8+x
}
I2CPara[port].Buf = s; //数据接收缓冲区指针
I2CPara[port].BytesNum = num; //要读取的个数
I2CPara[port].SubAddrEn = 1; //有子地址读
I2CPara[port].End = 0;
if(port)
{
//清除STA,SI,AA标志位
I2C1CONCLR = (1 << 2)| //AA
(1 << 3)| //SI
(1 << 5); //STA
//置位STA,启动I2C总线
I2C1CONSET = (1 << 5)| //STA
(1 << 6); //I2CEN
}
else
{
//清除STA,SI,AA标志位
I2CONCLR = (1 << 2)| //AA
(1 << 3)| //SI
(1 << 5); //STA
//置位STA,启动I2C总线
I2CONSET = (1 << 5)| //STA
(1 << 6); //I2CEN
}
//等待I2C操作完成
while (I2CPara[port].End == 0);
if (I2CPara[port].End == 1)
return (TRUE);
else
return (FALSE);
}
return (FALSE);
}
/****************************************************************************
* 函数名称 :CPU_I2C_WriteNByte() *
* 函数功能 :向有子地址器件写入N字节数据 *
* 入口参数 :sla 器件从地址 *
* suba_type 子地址结构 1-单字节地址 3-8+X结构 2-双字节地址*
* suba 器件内部物理地址 *
* *s 将要写入的数据的指针 *
* num 将要写入的数据的个数 *
* 出口参数 :TRUE 操作成功 *
* FALSE 操作失败 *
*****************************************************************************/
INT8U CPU_I2C_WriteNByte(INT8U port, INT8U sla, INT8U suba_type, INT32U suba, INT8U *s, INT32U num)
{
if(port > 1)
return(FALSE);
if (num > 0)//如果读取的个数为0,则返回错误
{ //设置参数
if (suba_type == 1)
{ //子地址为单字节
I2CPara[port].SlAddr = sla; //读器件的从地址
I2CPara[port].SubAddr = suba; //器件子地址
I2CPara[port].SubAddrNum = 1; //器件子地址为1字节
}
if (suba_type == 2)
{ //子地址为2字节
I2CPara[port].SlAddr = sla; //读器件的从地址
I2CPara[port].SubAddr = suba; //器件子地址
I2CPara[port].SubAddrNum = 2; //器件子地址为2字节
}
if (suba_type == 3)
{ //子地址结构为8+X
I2CPara[port].SlAddr = sla + ((suba >> 7 )& 0x0e);//读器件的从地址
I2CPara[port].SubAddr = suba & 0x0ff; //器件子地址
I2CPara[port].SubAddrNum = 1; //器件子地址为8+X
}
I2CPara[port].Buf = s; //数据
I2CPara[port].BytesNum = num; //数据个数
I2CPara[port].SubAddrEn = 2; //有子地址,写操作
I2CPara[port].End = 0;
if(port)
{
//清除STA,SI,AA标志位
I2C1CONCLR = (1 << 2)| //AA
(1 << 3)| //SI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -