📄 i2cint.c
字号:
/*
---------------------------------------------------------------------------------------------------------
*********************************************************************************************************
** 文件名称 : I2CINT.c
** 功能说明 : Luminary硬件I2C中断方式软件包。
** 使用说明 : 主程序要配置好I2C总线接口(I2C引脚功能和I2C中断,并已使能I2C主模式)
*********************************************************************************************************
---------------------------------------------------------------------------------------------------------
*/
#include "include.h"
#define uchar unsigned char
#define ulong unsigned long
/*******************************************************************************************
** 中断中的状态
*******************************************************************************************/
#define STATE_IDLE 0 /* 总线空闲状态 */
#define STATE_WRITE_ONE 1 /* 写单个字节状态 */
#define STATE_WRITE_NEXT 2 /* 写下一个字节状态 */
#define STATE_WRITE_FINAL 3 /* 写最后一个字节状态 */
#define STATE_READ_ONE 4 /* 读单个字节状态 */
#define STATE_READ_FIRST 5 /* 读第一个字节状态 */
#define STATE_READ_NEXT 6 /* 读下一个字节状态 */
#define STATE_READ_FINAL 7 /* 读最后一个字节状态 */
#define STATE_READ_WAIT 8 /* 读字节等待状态 */
/*******************************************************************************************
** 全局变量定义
*******************************************************************************************/
static volatile uchar I2C_sla; /* I2C器件从地址 */
static volatile ulong I2C_suba; /* I2C器件内部子地址 */
static volatile uchar I2C_suba_num; /* I2C子地址字节数 */
static volatile uchar *I2C_buf; /* 数据缓冲区指针 */
static volatile ulong I2C_num; /* 要读取/写入的数据个数 */
static volatile uchar I2C_opt; /* I2c读写操作,0为读操作,1为写操作 */
static volatile uchar I2C_state = STATE_IDLE; /* 中断服务程序的当前状态 */
static unsigned long I2CM_BASE = I2C0_MASTER_BASE; // 定义I2C主机基址,并初始化
void I2CMasterSpeedSet(ulong ulSpeed)
{
unsigned long ulClk, ulTPR;
ulClk = SysCtlClockGet( ); // 获取当前的系统时钟速率
ulTPR = (ulClk / (2 * 10)) / ulSpeed;
if (ulTPR < 2) ulTPR = 2; // 防止过高的速率设置请求
if (ulTPR > 256) ulTPR = 256; // 防止过低的速率设置请求
ulTPR = ulTPR - 1;
HWREG(I2CM_BASE + I2C_O_MTPR) = ulTPR;
}
void I2CMBaseSet(ulong ulBase)
{
I2CM_BASE = ulBase;
}
/*
*********************************************************************************************************
** 函数名称:I2CInit()
** 函数功能:I2C接口初始化。
** 入口参数:spd 总线速度100K(参数值为100000)或400K(参数值为4000000)
** pri 中断优先级0~7
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明:
*********************************************************************************************************
*/
int I2CInit(uchar pri)
{
if ((I2CM_BASE != I2C0_MASTER_BASE) && (I2CM_BASE != I2C1_MASTER_BASE))
{
I2CM_BASE = I2C0_MASTER_BASE;
}
switch (I2CM_BASE)
{
case I2C0_MASTER_BASE:
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); // 使能I2C0模块
SysCtlPeripheralEnable(I2C0SCL_PERIPH); // 使能SCL所在的GPIO模块
GPIOPinTypeI2C(I2C0SCL_PORT, I2C0SCL_PIN); // 配置相关管脚为SCL功能
SysCtlPeripheralEnable(I2C0SDA_PERIPH); // 使能SDA所在的GPIO模块
GPIOPinTypeI2C(I2C0SDA_PORT, I2C0SDA_PIN); // 配置相关管脚为SDA功能
IntEnable(INT_I2C0); // 使能I2C0中断
break;
case I2C1_MASTER_BASE:
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // 使能I2C1模块
SysCtlPeripheralEnable(I2C1SCL_PERIPH); // 使能SCL所在的GPIO模块
GPIOPinTypeI2C(I2C1SCL_PORT, I2C1SCL_PIN); // 配置相关管脚为SCL功能
SysCtlPeripheralEnable(I2C1SDA_PERIPH); // 使能SDA所在的GPIO模块
GPIOPinTypeI2C(I2C1SDA_PORT, I2C1SDA_PIN); // 配置相关管脚为SDA功能
IntEnable(INT_I2C1); // 使能I2C1中断
break;
default:
break;
}
I2CMasterInit(I2CM_BASE, false); // I2C主机模块初始化,100kbps
I2CMasterIntEnable(I2CM_BASE); // 使能I2C主模块中断
//IntMasterEnable(); // 使能处理器中断
I2CMasterEnable(I2CM_BASE); // 使能I2C主机
// 设置I2C中断的优先级
IntPrioritySet(INT_I2C, (pri << 5));
return(true);
}
/*
*********************************************************************************************************
** 函数名称:ISendByte()
** 函数功能:向无子地址器件发送1字节数据。
** 入口参数:sla 器件地址
** c 要发送的数据
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明: 使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
*********************************************************************************************************
*/
int ISendByte(uchar sla, uchar c)
{
I2C_sla = sla >> 1;
I2C_buf = &c;
I2C_state = STATE_WRITE_ONE;
I2CMasterSlaveAddrSet(I2CM_BASE, I2C_sla, false); // 主机写操作
I2CMasterDataPut(I2CM_BASE, *I2C_buf); // 写一个数据
I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_SINGLE_SEND); // 启动单次发送
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2CM_BASE))
return (false);
else
return (true);
}
/*
*********************************************************************************************************
** 函数名称 :ISendStr()
** 函数功能 :向有子地址器件任意地址开始写入N字节数据
** 入口参数 : sla 器件从地址
** suba_type 子地址结构 0-8+X结构 1-单字节地址 2-双字节地址 3-三字节地址
** suba 器件子地址
** s 数据发送缓冲区指针
** no 写入的个数
** 出口参数 : TRUE 操作成功
** FALSE 操作失败
*********************************************************************************************************
*/
int ISendStr(uchar sla, ulong suba, uchar sub_type, uchar *s, ulong no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
I2C_suba = suba;
switch(sub_type)
{
// 子地址为“8+x”类型
case 0:
I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
I2C_suba_num = 1;
break;
// 子地址为1个字节
case 1:
I2C_suba_num = 1;
break;
// 子地址为2个字节
case 2:
I2C_suba_num = 2;
break;
// 子地址为3个字节
case 3:
I2C_suba_num = 3;
break;
default: break;
}
if((no == 1) && (I2C_suba_num == 1))
I2C_state = STATE_WRITE_FINAL; // 单字节地址或8+x结构地址发送1个字节数据
else
I2C_state = STATE_WRITE_NEXT; // 多字节地址或发送多个字节数据
I2CMasterSlaveAddrSet(I2CM_BASE, I2C_sla, false); // 主机写操作
I2C_suba_num--;
I2CMasterDataPut(I2CM_BASE,
(I2C_suba >> (8 * I2C_suba_num))); // 写子地址高字节
I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_BURST_SEND_START);// 突发写操作启动
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2CM_BASE))
return (false);
else
return (true);
}
/*
*********************************************************************************************************
** 函数名称:ISendStrExt()
** 函数功能:向无子地址器件发送多字节数据。
** 入口参数:sla 器件地址
** s 要发送的数据
** no 发送的字节个数
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明: 发送数据字节至少2个字节
*********************************************************************************************************
*/
int ISendStrExt(uchar sla, uchar *s, uchar no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
if (no > 1) // 发送的字节参数过滤
{
if(no == 2)
I2C_state = STATE_WRITE_FINAL;
else
I2C_state = STATE_WRITE_NEXT;
I2CMasterSlaveAddrSet(I2CM_BASE, I2C_sla, false); // 主机写操作
I2CMasterDataPut(I2CM_BASE, *I2C_buf++);
I2C_num--;
I2CMasterControl(I2CM_BASE, I2C_MASTER_CMD_BURST_SEND_START);// 突发写操作启动
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2CM_BASE))
return (false);
else
return (true);
}
else
return(false);
}
/*
*********************************************************************************************************
** 函数名称:IRcvByte()
** 函数功能:向无子地址器件读取1字节数据。
** 入口参数:sla 器件地址
** c 接收数据的变量指针
** 出口参数:返回值为false时表示操作出错,为true时表示操作正确。
** 说明: 使用前要初始化好I2C引脚功能和I2C中断,并已使能I2C主模式
*********************************************************************************************************
*/
int IRcvByte(uchar sla, uchar *c)
{
I2C_sla = sla >> 1;
I2C_buf = c;
I2C_state = STATE_READ_WAIT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -