📄 i2c0.c
字号:
/*********************************************************************
* Copyright (c) 2011-2012,李士伟
* All rights reserved.
*文 件 名:i2c0.c
*描 述:I2C0驱动源文件
*当前版本:V1.00
*作 者:李士伟
*创建日期:2012.01.28
**********************************************************************/
/*
未完成!!!
*/
#include <drivers\lpc2103\target.h>
#include <drivers\lpc2103\i2c0.h>
#include <drivers\lpc2103\pinsel.h>
#include <drivers\lpc2103\vic.h>
#include <kernel\asm.h>
#include <kernel\flag.h>
#include <kernel\sched.h>
#include <kernel\kd.h>
#include <kernel\kds.h>
#define STA 0x20 /* 起始标志 */
#define STO 0x10 /* 停止标志 */
#define SI 0x80 /* 中断标志 */
#define AA 0x04 /* 应答信号 */
static OS_TCB *I2C0UsingTCB; /* 正在使用I2C0的任务 */
static OS_TCB *I2C0WaitQ; /* 等待I2C0服务队列 */
static INT8U I2C0TagAddr; /* 当前处理的数据包目标地址 */
static INT32U I2C0DataSize; /* 当前处理的数据包大小 */
static INT8U *I2C0DataPtr; /* 当前处理的数据缓冲区指针 */
static INT32U I2C0Offset; /* 当前处理的数据指针偏移量 */
/*********************************************************************
*函 数 名:I2C0_ISR
*描 述:I2C0中断服务例程
*输入参数:无
*输出参数:无
*返 回 值:无
*注 意:
**********************************************************************/
void I2C0_ISR(void)
{
INT8U state = 0; /* 状态标志 */
state = I2C0STAT;
switch (state)
{
case 0x08:
{
I2C0DAT = I2C0TagAddr;
I2C0CONCLR = SI;
break;
}
case 0x10:
{
break;
}
case 0x38:
{
break;
}
/* 主发送模式状态 */
case 0x18:
{
if (I2C0Offset == I2C0DataSize) /* 数据包已发送完 */
{
I2C0CONCLR = SI;
I2C0CONSET = STO; /* 发送停止信号,释放总线 */
OS_EnterRunQ(I2C0UsingTCB);
if (I2C0WaitQ != NULL)
{
OS_EnterRunQ(I2C0WaitQ);
}
return ;
}
I2C0DAT = I2C0DataPtr[I2C0Offset++];
I2C0CONCLR = SI; /* 清除中断标志 */
break;
}
case 0x20:
{
break;
}
case 0x28:
{
break;
}
case 0x30:
{
break;
}
/* 主接收模式状态 */
case 0x40:
{
break;
}
case 0x48:
{
break;
}
case 0x50:
{
if (I2C0Offset == I2C0DataSize)
{
I2C0CONCLR = AA; /* 发送非应答信号 */
I2C0CONSET = STO; /* 发送停止信号,释放总线 */
I2C0CONCLR = SI;
OS_EnterRunQ(I2C0UsingTCB);
if (I2C0WaitQ != NULL)
{
OS_EnterRunQ(I2C0WaitQ);
}
return ;
}
I2C0DataPtr[I2C0Offset++] = I2C0DAT;
I2C0CONSET = AA; /* 发送应答信号 */
I2C0CONCLR = SI;
break;
}
case 0x58:
{
break;
}
default:
{
break;
}
}
}
/*********************************************************************
*函 数 名:I2C0_SendDataPack
*描 述:I2C0发送一个数据包
*输入参数:pack: 数据包指针
*输出参数:无
*返 回 值:无
*注 意:
**********************************************************************/
void I2C0_SendDataPack(I2C_DATA_PACK *pack)
{
OS_ENTER_CRITICAL();
for ( ; ; )
{
if (I2C0UsingTCB != NULL) /* 有任务正在访问I2C */
{
OS_EnterWaitQTail(&I2C0WaitQ, OSTCBCur);
OS_Sched();
continue ;
}
break;
}
/* 设置数据包信息 */
I2C0TagAddr = (pack->TagAddr) & 0xFE;
I2C0DataSize = pack->DataSize;
I2C0DataPtr = pack->DataPtr;
I2C0Offset = 0;
OS_EnterWaitQTail(&(I2C0UsingTCB), OSTCBCur);
I2C0CONSET = STA; /* 发送一个起始标志引发中断 */
OS_EXIT_CRITICAL();
OS_Sched();
}
/*********************************************************************
*函 数 名:I2C0_ReceDataPack
*描 述:I2C0接收一个数据包
*输入参数:pack: 数据包指针
*输出参数:无
*返 回 值:无
*注 意:
**********************************************************************/
void I2C0_ReceDataPack(I2C_DATA_PACK *pack)
{
OS_ENTER_CRITICAL();
for ( ; ; )
{
if (I2C0UsingTCB != NULL) /* 有任务正在访问I2C */
{
OS_EnterWaitQTail(&I2C0WaitQ, OSTCBCur);
OS_Sched();
continue ;
}
break;
}
/* 设置数据包信息 */
I2C0TagAddr = (pack->TagAddr) & 0xFF;
I2C0DataSize = pack->DataSize;
I2C0DataPtr = pack->DataPtr;
I2C0Offset = 0;
OS_EnterWaitQTail(&(I2C0UsingTCB), OSTCBCur);
I2C0CONSET = STA; /* 发送一个起始标志引发中断 */
OS_EXIT_CRITICAL();
OS_Sched();
}
/*********************************************************************
*函 数 名:I2C0_Init
*描 述:I2C0初始化
*输入参数:Fscl:串行时钟频率(Hz)
*输出参数:无
*返 回 值:0,初始化成功; 1,初始化失败
*注 意:
**********************************************************************/
INT32U I2C0_Init(INT32U Fscl)
{
if (PIN_Configure(PIN_SDA0))
{
if (PIN_Configure(PIN_SCL0) == 0)
{
PIN_Release(PIN_SDA0);
return 0;
}
}
I2C0WaitQ = NULL;
I2C0UsingTCB = NULL;
I2C0DataSize = 0;
I2C0DataPtr = NULL;
I2C0Offset = NULL;
I2C0TagAddr = 0;
I2C0CONCLR = 0x7C; /* 先禁止I2C */
/* 设置串行时钟频率 */
I2C0SCLH = Fpclk / (Fscl + 1) / 2;
I2C0SCLL = Fpclk / (Fscl) / 2;
/* 注册中断处理服务例程 */
VIC_RegisterIRQ(I2C0_Handler, I2C0_INTR_NUM, I2C0_INTR_PRIO);
I2C0CONSET = 0x40; /* 主机模式,启动I2C */
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -