📄 i2c.c
字号:
}
if(slot>15)
{
return(0); //IRQ中断号0~15
}
I2C_n = n; //I2C接口号
if(n == 0) //设置I2C0接口
{
PINSEL0 = (PINSEL0 &(~0x0f0))|0x50; //设置I2C0管脚有效
SetISR(9,slot,(uint32)IRQ_I2C); //设置I2C0中断
}
else //设置I2C1接口的引脚和中断
{
PINSEL1 = (PINSEL1 &(~(0x0f<<2)))|(0x01<<2)|(0x01<<4); //设置I2C1管脚有效
SetISR(19,slot,(uint32)IRQ_I2C); //设置I2C1中断
}
if(MODE == 1) //I2C设置为主模式
{
if(I2C_n == 0)
{
I2C0SCLH = (Fpclk/Fi2c)/2; //设定I2C时钟
I2C0SCLL = (Fpclk/Fi2c)/2;
I2C0CONCLR = 0x2c;
I2C0CONSET = 0x40; //使能主I2C
}
else
{
I2C1SCLH = (Fpclk/Fi2c)/2; //设定I2C时钟
I2C1SCLL = (Fpclk/Fi2c)/2;
I2C1CONCLR = 0x2c;
I2C1CONSET = 0x40; //使能主I2C
}
}
else //I2C设置为从模式
{
*((volatile uint32 *)(&I2ADR) + (I2C_n*0x10000)) = Adr&0xfe; //设置从机地址
*((volatile uint32 *)(&I2C0CONSET) + (I2C_n*0x10000)) = 0x44; //使能从I2C
*((volatile uint32 *)(&I2C0CONCLR) + (I2C_n*0x10000)) = 0x28;
}
IRQEnable(); //打开IRQ中断
return(1);
}
/*********************************************************************************************************
**函数名称:uint8 I2C_SendByte(uint8 n,uint8 sla,uint8 dat)
**函数功能:向无子地址器件发送1字节数据
**入口参数:n 接口号0,1
** sla 器件地址
** dat 要发送的数据
**出口参数:返回值为0时表示出错,为1时表示操作正确
**说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式,程序死等待操作完成
********************************************************************************************************/
uint8 I2C_SendByte(uint8 n,uint8 sla,uint8 dat)
{
if((n!=0)&&(n!=1)) return(0);
/*参数设置*/
I2C_n = n; //I2C接口号
I2C_sla = sla; //写操作的器件地址
I2C_buf = &dat; //待发送的数据
I2C_num = 1; //发送1字节数据
I2C_suba_en = 0; //无子地址
I2C_end = 0;
*((volatile uint32 *)(&I2CONCLR) + (I2C_n*0x10000)) = 0x2c;
*((volatile uint32 *)(&I2CONSET) + (I2C_n*0x10000)) = 0x60; //设置为主机,并启动总线
while(I2C_end == 0);
if(I2C_end == 1) return(1);
else return(0);
}
/*********************************************************************************************************
**函数名称:uint8 I2C_RcvByte(uint8 n,uint8 sla,uint8 *dat)
**函数功能:向无子地址器件读取1字节数据
**入口参数:n 接口号0,1
** sla 器件地址
** dat 接受数据的指针变量
**出口参数:返回值为0时表示出错,为1时表示操作正确
**说明:使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式,程序死等待操作完成
********************************************************************************************************/
uint8 I2C_RcvByte(uint8 n,uint8 sla,uint8 *dat)
{
if((n!=0)&&(n!=1)) return(0);
/*参数设置*/
I2C_n = n; //I2C接口号
I2C_sla = sla+1; //读操作的器件地址
I2C_buf = dat;
I2C_num = 1; //读取字节数为1
I2C_suba_en = 0; //无子地址
I2C_end = 0;
*((volatile uint32 *)(&I2CONCLR) + (I2C_n*0x10000)) = 0x2c;
*((volatile uint32 *)(&I2CONSET) + (I2C_n*0x10000)) = 0x60; //设置为主机,并启动总线
while(I2C_end == 0);
if(I2C_end == 1) return(1);
else return(0);
}
/*********************************************************************************************************
**函数名称:uint8 I2C_ReadNByte(uint8 n,uint8 sla,uint32 suba_type,uint32 suba,uint8 *s,uint32 num)
**函数功能:从有子地址器件任意地址开始读取N字节数据
**入口参数:n 接口号0,1
** sla 器件从地址
** suba_type 子地址结构 1-单字节地址,2-双字节地址,3-8+X结构
** suba 器件子地址
** *s 数据接收缓冲区指针
** num 读取的个数
**出口参数:1 操作成功
** 0 操作失败
**说明:程序死等待操作完成
********************************************************************************************************/
uint8 I2C_ReadNByte(uint8 n,uint8 sla,uint32 suba_type,uint32 suba,uint8 *s,uint32 num)
{
if((n!=0)&&(n!=1)) return(0);
I2C_n = n; //I2C接口号
if(num > 0) /*判断num个数的格式*/
{
/*参数设置*/
if(suba_type == 1)
{
/*子地址为单字节*/
I2C_sla = sla + 1; //读器件的从地址,R=1
I2C_suba = suba; //器件子地址
I2C_suba_num = 1; //器件子地址为1字节
}
if(suba_type == 2)
{
/*子地址为2字节*/
I2C_sla = sla + 1; //读器件的从地址,R=1
I2C_suba = suba; //器件子地址
I2C_suba_num = 2; //器件子地址为2字节
}
if(suba_type == 3)
{
/*子地址结构为8+X*/ //如24C04/08/16的从地址中含有A8,A9,A10
I2C_sla = sla + ((suba>>7) & 0x0e) + 1; //读器件的从地址,R=1
I2C_suba = suba & 0x0ff; //器件子地址
I2C_suba_num = 1; //器件子地址为8+X
}
I2C_buf = s; //数据接收缓冲区指针
I2C_num = num; //要读取的个数
I2C_suba_en = 1; //有子地址读
I2C_end = 0; //
/*清除STA,SI,AA标志位*/
*((volatile uint32 *)(&I2CONCLR) + (I2C_n*0x10000)) = (1<<2)| //AA
(1<<3)| //SI
(1<<5); //STA
/*置位STA,启动I2C总线*/
*((volatile uint32 *)(&I2CONSET) + (I2C_n*0x10000)) = (1<<5)| //STA
(1<<6); //I2CEN
/*等待I2C操作完成*/
while(I2C_end == 0);
if(I2C_end == 1) return(1);
else return(0);
}
return(0);
}
/*********************************************************************************************************
**函数名称:uint8 I2C_WriteNByte(uint8 n,uint8 sla,uint8 suba_type,uint32 suba,uint8 *s,uint32 num)
**函数功能:向有子地址器件写入N字节数据
**入口参数:n 接口号0,1
** sla 器件从地址
** suba_type 子地址结构 1-单字节地址,2-双字节地址,3-8+X结构
** suba 器件子地址
** *s 数据发送缓冲区指针
** num 要写入的数据的个数
**出口参数:1 操作成功
** 0 操作失败
**说明:程序死等待操作完成
********************************************************************************************************/
uint8 I2C_WriteNByte(uint8 n,uint8 sla,uint8 suba_type,uint32 suba,uint8 *s,uint32 num)
{
if((n!=0)&&(n!=1)) return(0);
I2C_n = n; //I2C接口号
/*参数设置*/
if(num > 0) /*判断num个数的格式*/
{
if(suba_type == 1)
{
/*子地址为单字节*/
I2C_sla = sla; //写器件的从地址
I2C_suba = suba; //器件子地址
I2C_suba_num = 1; //器件子地址为1字节
}
if(suba_type == 2)
{
/*子地址为2字节*/
I2C_sla = sla; //写器件的从地址
I2C_suba = suba; //器件子地址
I2C_suba_num = 2; //器件子地址为2字节
}
if(suba_type == 3)
{
/*子地址结构为8+X*/
I2C_sla = sla + ((suba>>7) & 0x0e) ; //写器件的从地址
I2C_suba = suba & 0x0ff; //器件子地址
I2C_suba_num = 1; //器件子地址为8+X
}
I2C_buf = s; //数据发送缓冲区指针
I2C_num = num; //要发送的数据的个数
I2C_suba_en = 2; //有子地址,写操作
I2C_end = 0; //
/*清除STA,SI,AA标志位*/
*((volatile uint32 *)(&I2CONCLR) + (I2C_n*0x10000)) = (1<<2)| //AA
(1<<3)| //SI
(1<<5); //STA
/*置位STA,启动I2C总线*/
*((volatile uint32 *)(&I2CONSET) + (I2C_n*0x10000)) = (1<<5)| //STA
(1<<6); //I2CEN
/*等待I2C操作完成*/
while(I2C_end == 0);
if(I2C_end == 1) return(1);
else return(0);
}
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -