?? lpc2400can.c
字號:
/****************************************Copyright (c)*****************************************************
** 廣州致遠電子有限公司
** 工業通信網絡事業部
** http://www.embedcontrol.com
**-------------------------------------文件信息--------------------------------------------------------
** 文 件 名: LPC2400CAN.c
** 當 前 版 本: v1.0
** 日 期: 2007年5月06日
** 描 述:
**-------------------------------------歷史創建--------------------------------------------------------
** 文 件 名: LPC2400CAN.c
** 版 本: v1.0
** 日 期: 2008年4月26日
** 創 建 人: 劉彥龍
** 描 述: LPC2400開發板實驗教程實例代碼
**-------------------------------------歷史修改--------------------------------------------------------
** 文 件 名:
** 版 本:
** 日 期:
** 修 改 人:
** 描 述:
**********************************************************************************************************/
#include "LPC2400CAN.h"
static struct _MessageDetail MessageDetailT;
/**********************************************************************************************************
**函數原型 : unsigned char Enter_SWRst(unsigned char Ch);
**參數說明 : Ch:CAN控制器號,0表示第一路CAN
**返回值 : 0:失敗
** : 1: 成功
**說 明 : CAN控制器進入軟件復位模式
**********************************************************************************************************/
unsigned char Enter_SWRst(unsigned char Ch)
{
unsigned long regaddr;
REG_CANMOD regmod;
regaddr = (unsigned long)(&CAN1MOD)+(unsigned long)Ch*CANOFFSET;
regmod.DWord = RGE(regaddr); /* 讀取CAN1MOD寄存器 */
regmod.Bits.RM = 1; /* RM位置“1” */
RGE(regaddr) = regmod.DWord; /* 回寫CAN1MOD寄存器 */
regmod.DWord = RGE(regaddr); /* 驗證寫入值 */
return (unsigned char)((0 != regmod.Bits.RM)? 1:0);
}
/**********************************************************************************************************
**函數原型 : unsigned char Quit_SWRst(unsigned char Ch);
**參數說明 : Ch:CAN控制器號,0表示第一路CAN
**返回值 : 0:失敗
** : 1: 成功
**說 明 : CAN控制器退出軟件復位模式
**********************************************************************************************************/
unsigned char Quit_SWRst(unsigned char Ch)
{
unsigned long regaddr;
REG_CANMOD regmod;
regaddr = (unsigned long)(&CAN1MOD)+(unsigned long)Ch*CANOFFSET;
regmod.DWord = RGE(regaddr); /* 讀取CAN1MOD寄存器 */
regmod.Bits.RM = 0; /* RM位置“0” */
RGE(regaddr) = regmod.DWord; /* 回寫CAN1MOD寄存器 */
regmod.DWord = RGE(regaddr); /* 驗證寫入值 */
return (unsigned char)((0 != regmod.Bits.RM)? 0:1);
}
/**********************************************************************************************************
**函數原型 : unsigned char CAN_Init(unsigned char Ch, unsigned long Baud);
**參數說明 : Ch:CAN控制器號,0表示第一路CAN
** : Baud:CAN波特率值
**返回值 : 無
**說 明 : CAN控制器退出軟件復位模式
**********************************************************************************************************/
void CAN_Init(unsigned char Ch, unsigned long Baud)
{
unsigned long regaddr;
switch(Ch) { /* 配置CAN控制器引腳 */
case 0:
PCONP |= 1 << 13; /* 打開CAN控制器電源 */
PINSEL0 = PINSEL0 & (~0x0F) | 0x05;
#if 0
PINSEL0 &= ~(0x03L<<0); /* RD1 */
PINSEL0 |= (0x01L<<0);
PINSEL0 &= ~(0x03L<<2); /* TD1 */
PINSEL0 |= (0x01L<<2);
#endif
break;
case 1:
PCONP |= 0x01L<<14; /* 打開CAN控制器電源 */
PINSEL0 &= ~(0x03L<<8); /* RD2 */
PINSEL0 |= (0x02L<<8);
PINSEL0 &= ~(0x03L<<10); /* TD2 */
PINSEL0 |= (0x02L<<10);
break;
default:
break;
}
Enter_SWRst(Ch);
regaddr = (unsigned long)(&CAN1BTR)+(unsigned long)Ch*CANOFFSET;
RGE(regaddr) = Baud;
CAN_AFMR &= ~0x07; /* 設置為旁路模式 */
CAN_AFMR|=(1<<1);
Quit_SWRst(Ch);
}
/**********************************************************************************************************
**函數原型 : unsigned char CANRCVANDSEND(unsigned char Ch, unsigned char BUFNum);
**參數說明 : Ch:CAN控制器號,0表示第一路CAN
** : BUFNum 選擇緩沖區
**返回值 : 無
**說 明 : CAN將收到的信息再發送出去
**********************************************************************************************************/
unsigned char CANRCVANDSEND(unsigned char Ch, unsigned char BUFNum)
{
unsigned long mes,CAN32reg;
unsigned long regaddr;
unsigned char i=5;
BUFNum-=1; /* 計算地址方便。 */
regaddr = (unsigned long)(&CAN1RFS)+(unsigned long)Ch*CANOFFSET; /* 處理DLC、RTR、FF */
mes = RGE(regaddr);
mes &= 0Xffff0000;
regaddr = (unsigned long)(&CAN1TFI1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr)=mes;
regaddr = (unsigned long)(&CAN1RID)+(unsigned long)Ch*CANOFFSET; /* 處理ID */
mes = RGE(regaddr);
regaddr = (unsigned long)(&CAN1TID1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr)=mes;
regaddr = (unsigned long)(&CAN1RDA)+(unsigned long)Ch*CANOFFSET; /* 處理 數據A */
mes = RGE(regaddr);
regaddr = (unsigned long)(&CAN1TDA1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr)=mes;
regaddr = (unsigned long)(&CAN1RDB)+(unsigned long)Ch*CANOFFSET; /* 處理 數據B */
mes = RGE(regaddr);
regaddr = (unsigned long)(&CAN1TDB1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr)=mes;
regaddr = (unsigned long)(&CAN1CMR)+(unsigned long)Ch*CANOFFSET; /* 寫控制寄存器,發送 */
CAN32reg = RGE(regaddr);
CAN32reg &= ~0x03;
CAN32reg |= 0x03;
CAN32reg &= ~((1<<5)|(1<<6)|(1<<7));
switch(BUFNum) {
case 0: CAN32reg |= 01<<5;break;
case 1: CAN32reg |= 01<<6;break;
case 2: CAN32reg |= 01<<7;break;
default: break;
}
RGE(regaddr)=CAN32reg;
regaddr = (unsigned long)(&CAN1GSR)+(unsigned long)Ch*CANOFFSET; /* 查 接收緩沖區狀態 */
mes = RGE(regaddr);
while(mes&(1<<0)) { /* RBS為1 接收緩沖區滿 */
regaddr = (unsigned long)(&CAN1CMR)+(unsigned long)Ch*CANOFFSET;
mes=RGE(regaddr);
mes |= (1<<2); /* 釋放接收緩沖區 */
RGE(regaddr)=mes;
if(!(i--)) {
return(0);
}
}
regaddr = (unsigned long)(&CAN1CMR)+(unsigned long)Ch*CANOFFSET;
mes=RGE(regaddr);
mes &= (~(1<<2));
RGE(regaddr)=mes;
return(1);
}
/**********************************************************************************************************
**函數原型 : unsigned char writedetail(unsigned char LEN,unsigned char FF, unsigned int ID,unsigned char *data);
**參數說明 : LEN:數據長度
** : *data 發送數據所在的數組
:
**返回值 : 操作成功返回 1 失敗返回 0
**說 明 : 用戶填寫發送 幀信息
**********************************************************************************************************/
unsigned char writedetail(unsigned char LEN,unsigned char FF, unsigned int ID,unsigned char *data)
{
unsigned char i;
if(LEN>8) {
return(0);
} else {
MessageDetailT.LEN=LEN;
MessageDetailT.FF=FF;
MessageDetailT.CANID=ID;
MessageDetailT.DATAA=0; /* 先清零 */
MessageDetailT.DATAB=0;
for(i=0;i<LEN;i++) {
if(i<4) {
MessageDetailT.DATAA |= (*(data+i)<<(i*8));
} else {
MessageDetailT.DATAB |= (*(data+i)<<((i-4)*8));
}
}
return(1);
}
}
/**********************************************************************************************************
**函數原型 : unsigned char CANSend(unsigned char Ch, unsigned char BUFNum);
**參數說明 : Ch:CAN控制器號,0表示第一路CAN
** : BUFNum 選擇緩沖區
: MessageDetailT 報文的特征信息及數據
**返回值 : 無
**說 明 : CAN控制器退出軟件復位模式
**********************************************************************************************************/
unsigned char CANSend(unsigned char Ch, unsigned char BUFNum)
{
unsigned long CAN32reg;
unsigned long regaddr;
unsigned char FFflag;
BUFNum-=1; /* 計算地址方便。 */
/* 3緩沖區間地址差 0x10 */
regaddr = (unsigned long)(&CAN1TFI1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
CAN32reg = RGE(regaddr);
CAN32reg &= ~((0x0fL<<16) | (0x01L<<30) | (0x80000000)); /* 清 DLC,RTR.FF位 */
CAN32reg |= ((unsigned long)MessageDetailT.LEN<<16) | ((unsigned long)MessageDetailT.FF<<31);
RGE(regaddr)=CAN32reg;
FFflag = MessageDetailT.FF;
/* 寫幀ID */
regaddr = (unsigned long)(&CAN1TID1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
CAN32reg = RGE(regaddr);
if(FFflag) { /* FF為1,ID為29位 */
CAN32reg &=0x70000000;
CAN32reg |= (unsigned long)(MessageDetailT.CANID & 0x1fffffff);
} else {
CAN32reg &= 0xfffff800; /* FF為0 ,ID為11位 */
CAN32reg |= (unsigned long)(MessageDetailT.CANID & 0x000007ff);
}
RGE(regaddr)=CAN32reg;
/* 寫幀數據A */
regaddr = (unsigned long)(&CAN1TDA1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr) = MessageDetailT.DATAA;
/* 寫幀數據B */
regaddr = (unsigned long)(&CAN1TDB1)+(unsigned long)Ch*CANOFFSET+(unsigned long)0X10*BUFNum;
RGE(regaddr) = MessageDetailT.DATAB;
regaddr = (unsigned long)(&CAN1CMR)+(unsigned long)Ch*CANOFFSET; /* 寫控制寄存器,發送 */
CAN32reg = RGE(regaddr);
CAN32reg &= ~0x03;
CAN32reg |= 0x03;
CAN32reg &= ~((1<<5)|(1<<6)|(1<<7));
switch(BUFNum) {
case 0: CAN32reg |= 01<<5;break;
case 1: CAN32reg |= 01<<6;break;
case 2: CAN32reg |= 01<<7;break;
default: break;
}
RGE(regaddr)=CAN32reg;
regaddr = (unsigned long)(&CAN1GSR)+(unsigned long)Ch*CANOFFSET; /* 查詢發送狀態 */
CAN32reg = RGE(regaddr);
if(CAN32reg&(1<<3)) { /* 所有的請求已成功完成 */
return(1); /* 發送成功返回 1 */
} else { return (0);} /* 發送失敗返回 0 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -