?? 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 + -