📄 iic0.c
字号:
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Copyright (c) $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$ 肖遥电子(广州)研发中心
$ Shawyoo Electronics (GuangZhou) R&D Center
$ http://www.shawyoo.com Email: autoele@qq.com
$ QQ群:9069471/9069433/9524253 All rights reserved.
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Copyright (c) $$$$$$$$$$$$$$$$$$$$$$$$$$$ */
/*
文件描述
文件名: IIC0.c
功能描述: IIC0底层驱动程序
编译环境: Keil for ARM + ARTX
目标CPU: LPC2000
作者: 肖建辉
创建时间:
建议编辑环境:UltraEdit 11.00a+ 制表符宽度为三个字符,程序可读性更好。
Keil中可用配置工具
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*/
#include "RTOS.h"
#define IIC0_GLOBALS 1
#include "IIC0.h"
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:IIC_Read
功能描述:按指定的从机地址的当前存储地址和长度读取数据
入口参数:从机地址,任务命令,读取的长度,接收缓冲
出口参数:无
全局变量: 无
创建时间:
修改时间:
*/
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar IIC_Read(uchar SlaveAddr,uchar Comm,uint16 Length,uchar *pBuffer)
{
NOP(); NOP();
if(IIC.Busy)
return ERROR;
IIC.Busy = TRUE;
IIC.SlaverAddress = SlaveAddr;
IIC.Command = Comm;
IIC.RLen = Length;
IIC.ReadWrite = TW_READ;
IIC.RW_Type = IIC_READ_COMM;
IIC.pReadBuffer = pBuffer;
TW_Start();
return OK;
} // End of <IIC_Read> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:IIC_Write
功能描述:写数据到从机
入口参数:从机地址,任务命令,长度,写入的数据区指针
出口参数:
全局变量:
创建时间:
修改时间:
*/
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar IIC_Write(uchar SlaveAddr,uchar Comm,uint16 Length,uchar *pBuffer)
{
NOP(); NOP();
if(IIC.Busy)
return ERROR;
IIC.Busy = TRUE;
IIC.SlaverAddress = SlaveAddr;
IIC.Command = Comm;
IIC.WLen = Length;
IIC.ReadWrite = TW_WRITE;
IIC.RW_Type = IIC_WRITE_COMM;
IIC.pWriteBuffer = pBuffer;
TW_Start();
return OK;
} // End of <IIC_Write> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:IIC_WriteRead
功能描述:按指定的从机地址的随机存储地址读取数据
入口参数:器件地址,任务命令,写长度和写数据缓冲指针,读长度和数据缓冲指针
出口参数:无
全局变量:
创建时间:
修改时间:
*/
void Delay_mS(unsigned char c);
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar IIC_WriteRead(uchar Addr,uchar Comm,uint16 WLen,uchar *pW,uint16 RLen,uchar *pR)
{
NOP(); NOP();
if(IIC.Busy)
return ERROR;
IIC.Busy = TRUE;
IIC.SlaverAddress = Addr;
IIC.Command = Comm;
IIC.WLen = WLen; // 写长度
IIC.ReadWrite = TW_WRITE;
IIC.RW_Type = IIC_RW_COMM;
IIC.pWriteBuffer = pW; // 写缓冲
////////////////////////////////////////
IIC.RLen = RLen; // 读长度
IIC.pReadBuffer = pR; // 读缓冲
TW_Start(); // 启动IIC
return OK;
} // End of <IIC_WriteRead> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:ReadEEPROM
功能描述:读EEPROM
入口参数:器件地址,存储器地址,读长度,读取存储指针
出口参数:无
全局变量:
创建时间:
修改时间:
*/
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void ReadEEPROM(uchar DAddr,uint16 RAddr,uint16 RLen,uchar *pData)
{
uchar sAddr[2];
NOP(); NOP();
sAddr[0] = RAddr>>8;
sAddr[1] = RAddr;
while(IIC_WriteRead(DAddr,0,2,sAddr,RLen,pData));
os_dly_wait(1+(RLen/(I2C_FREQUENCY/1000))); // 以适应读数据时延时
NOP(); NOP();
} // End of <ReadEEPROM> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:EEPROM_Write
功能描述:写EEPROM
入口参数:器件地址,页长度,写存储地址,写长度,待写数据指针
出口参数:输入成功与否(只判断输入EEPROM,不判断是否写成功),返回0表示成功
全局变量:
创建时间:
修改时间:
*/
#include <string.h>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar WriteEEPROM(uchar DAddr,uchar PageLen,uint16 WAddr,
uint16 WLen,uchar *pData)
{
uchar PageBuffer[68];
uchar owLen; // One time Write Len
NOP(); NOP();
if(PageLen%8) return ERROR; // 页长度必须为8的位数
////////////////////////////////////// 写首址
PageBuffer[0] = WAddr>>8;
PageBuffer[1] = WAddr;
if((WLen+(WAddr%PageLen))<=PageLen)
{
memmove(&PageBuffer[2],pData,WLen);
IIC_Write(DAddr,0,(WLen+2),PageBuffer);
os_dly_wait(1);
}
else
{
if(WAddr%PageLen) // 不是从整页地址开始写
{
owLen = PageLen-WAddr%PageLen; // 第一轮写的长度
memmove(&PageBuffer[2],pData,owLen); // 第一轮写的数据
while(IIC_Write(DAddr,0,(owLen+2),PageBuffer)); // 输入EEPROM
os_dly_wait(1);
WAddr += owLen; // 下一页地址
pData += owLen;
WLen -= owLen;
}
/////////////////////////////////////////////////////////////
while(WLen)
{
PageBuffer[0] = WAddr>>8;
PageBuffer[1] = WAddr; // 写地址
if(WLen>=PageLen)
owLen = PageLen;
else
owLen = WLen;
memmove(&PageBuffer[2],pData,owLen); // 取数据到缓冲
while(IIC_Write(DAddr,0,(owLen+2),PageBuffer)); // 输入EEPROM
os_dly_wait(1);
WAddr += owLen;
pData += owLen;
WLen -= owLen;
}
}
return OK;
} // End of <WriteEEPROM> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:I2C0_INT
功能描述:IIC0中断服务程序
入口参数:无
出口参数:无
全局变量:
创建时间:
修改时间:
*/
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void I2C0_INT(void) __irq // IIC0 interrupt function
{
uchar s;
NOP(); NOP();
s = IIC.Status = I20STAT;
NOP(); NOP();
switch(s)
{
/// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
/// Start or repeat Start bit has been Transmitted
case TW_MS_START: // Start bit OK;
case TW_MS_REP_START: // Repeat Start bit OK
I20DAT = (IIC.SlaverAddress|IIC.ReadWrite);
break;
///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// Master Transmitter Mode ///////////////////////////////////////////////
case TW_MT_SLA_ACK: // SLA+W has been transmitted; ACK has been received
I20DAT = *IIC.pWriteBuffer++;
break;
case TW_MT_DATA_ACK: // Data byte in I2DAT has been transmitted;
// ACK has been received
IIC.WLen--;
if(IIC.WLen)
I20DAT = *IIC.pWriteBuffer++;
else
{
if(IIC.RW_Type==IIC_RW_COMM)
{
IIC.ReadWrite = TW_READ;
IIC.RW_Type = IIC_READ_COMM;
I20CONCLR = (TW_INT_FLAG); // 清除IIC中断标志
VICVectAddr = 0; // 清除总中断标志
TW_Start(); // 再次启动IIC
return;
}
else // 单写完成
{
UserEvtFlag.IIC = IIC_WRITE_OK_EVT_FLAG;
TW_Stop(); // 结束总线
IIC.Busy = FALSE;
}
//isr_evt_set(IIC_WRITE_EVT_OK,tidGetSpeedValue);
}
break;
///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// Master Receive Mode //////////////////////////////////////////////////
case TW_MR_SLA_ACK: // SLA+R has been transmitted; ACK has been received
if(IIC.RLen>1)
TW_Ack(); // 下次发送应答信号
else
TW_NoAck(); // 下次发送非应答信号
break;
case TW_MR_DATA_ACK: // Data byte has been received,ACK has been returned
*IIC.pReadBuffer++ = I20DAT;
IIC.RLen--;
if(IIC.RLen==1)
TW_NoAck(); // 下次发送非应答信号
break;
case TW_MR_DATA_NACK: // Data byte has been received,NOT ACK has been returned
*IIC.pReadBuffer++ = I20DAT;
/////////////////////////////////////////////////////////
if(IIC.Command==IIC_GET_GPS_COMMAND) // GPS 任务操作IIC完成
{
UserEvtFlag.GPS = GPS_REC_OK_EVT_FLAG;
isr_evt_set(GPS_REC_OK_EVT_FLAG,TaskID.GPS);
}
else if(IIC.Command==IIC_GET_T485_COMMAND) // 读485数据之任务操作IIC完成
{
UserEvtFlag.MainTask = MAIN_TASK_EVT_FLAG;
isr_evt_set(MAIN_TASK_EVT_FLAG,TaskID.MainTask);
}
else if(IIC.Command==IIC_EEPROM_UART0) // 串口0任务中操作IIC完成
{
UserEvtFlag.UART0 = IIC_RW_OK_EVT_FLAG;
isr_evt_set(IIC_RW_OK_EVT_FLAG,TaskID.UART0);
}
else if(IIC.Command==IIC_EEPROM_GSM_GPRS) // GSM/GPRS 任务操作IIC完成
{
UserEvtFlag.GSM_GPRS = IIC_RW_OK_EVT_FLAG;
isr_evt_set(IIC_RW_OK_EVT_FLAG,TaskID.GSM_GPRS);
}
else if(IIC.Command==IIC_INIT_CHECK_COMM) // 系统初始化任务操作IIC完成
{
UserEvtFlag.MainTask = IIC_INIT_CHECK_EVT_FLAG;
isr_evt_set(IIC_INIT_CHECK_EVT_FLAG,TaskID.MainTask);
}
////////////////////////////////////////////////////////
NOP();
TW_Stop(); // 结束总线
IIC.Busy = FALSE;
break;
///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// Master 异常处理 //////////////////////////////////////////////////
case TW_MR_SLA_NACK: // 发送了地址没收到应答
case TW_MT_SLA_NACK: // 发送了地址没收到应答
case TW_MT_DATA_NACK: // 发送了数据没收到应答
case TW_MT_ARB_LOST: // 丢失仲裁
default:
TW_Stop();
IIC.Busy = FALSE;
break;
}
I20CONCLR = (TW_INT_FLAG); // 清除中断标志
NOP(); NOP();
VICVectAddr = 0;
} // End of <I2C0_INT> function
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
函数名称:I2cInit
功能描述:I2c0初始化函数
入口参数:无
出口参数:无
全局变量:
创建时间:
修改时间:
*/
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void I2C0_Init(void)
{
I20CONCLR = 0x6C; // 清除控制寄存器
VICIntEnClr = (1<<IIC0_INT_VECT); // 禁止能I2c中断
PINSEL0 = (PINSEL0 & 0xffffff0f) | 0x50; // 选择管脚为I2c
I20SCLH = (Fpclk / I2C_FREQUENCY + 1) / 2; // 设置高电平时间
I20SCLL = (Fpclk / I2C_FREQUENCY) / 2; // 设置低电平时间
I20CONSET = 1<<TW_ENABLE; // Master model
/////////////////////////////////////////////
VICVectAddr6 = (uint32)I2C0_INT;
VICVectCntl6 = (IRQ_ENABLE|IIC0_INT_VECT);
VICIntEnable |= (1<<IIC0_INT_VECT); //
IIC.Busy = IIC.WLen = IIC.RLen = IIC.RW_Type = 0;
IIC.Command = IIC.SlaverAddress = 0;
} //End of <I2C0_Init> Function
/*
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ End of File $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -