📄 can.#1
字号:
/****************************************************************************
**
** 文件名: CAN.c
** 功能: C8051Fxxx的CAN控制器驱动;
** 创建时间:2005.08.05
** 修改时间:2005.12.01
** 修改说明:
** 作者: 李立学
** 版权申明:可以拷贝,可以修改,但必须保留修改时间和作者信息
**
****************************************************************************/
#include "LZK.H"
uint8 xdata CAN_SendDATA[8];
uint8 xdata CAN_RecvDATA[8];
/****************************************************************************
** 函数名称: CAN_Init(void)
** 功能描述: 初始化CAN控制器定时、波特率,使能CAN控制器
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
void CAN_Init(void)
{
SFRPAGE = CAN0_PAGE;
CAN0CN = 0x41; // 0100_0001, Set CCE and INIT
// Bit7: TEST: Test Mode Enable bit. 0: Disabled;
// Bit6: CCE: Configuration Change Enable bit, "CCE". 0: Disabled;
// Bit5: DAR: Disable Automatic Retransmission bit. 0: Eabled;
// Bit4: CANIF:Module Interrupt Flag. 1: CAN interrupt has occurred and is active, Cleared by hardware.
// Bit3: EIE: Module Error Interrupt Enable Bit. 1: Enabled;
// Bit2: SIE: Status change Interrupt Enable Bit. 1: Enabled;
// Bit1: IE: Module Interrupt Enable Bit. 1: Enabled IRQ_B;
// Bit0: INIT: Initialization bit. 0: Normal Operation;
CAN0ADR = BRPEXT; // Address for BRP Extension Register.
CAN0DAT = 0x0000; // BRPE = 0x00;
CAN0ADR = BITREG; // Address for Bit Timing register.
// Prop_Seg = 7 * 4 / 24 = 1166.7nS > 400nS.
CAN0DAT = 7 << 12 | // TSeg2 = (Phase_Seg2 - 1) = 8 - 1 = 7;
14 << 8 | // Tseg1 = (Prop_Seg + Phase_Seg1 - 1) = 7 + 8 - 1 = 14
3 << 6 | // SWJp = SWJ - 1 = 4 - 1 = 3;
3; // BRP = 4.
// Bit Time = Sync_Seg(1) + Prop_Seg(7) + Phase_Seg1(8) + Phase_Seg2(8);
// BautRate = 24M / 4 /(1 + 7 + 8 + 8) = 250K.
// CAN0TST = 0x04; // Basic Mode Enabled. IF1 Used as Tx Buffer, IF2 Used as Rx Buffer.
// Bit7: Rx Monitors the actual value of the CAN_RX Pin
// CAN bus is recessive (CAN_RX = ‘1’) or dominant (CAN_RX = ‘0’).
// Bit[6..5]: Tx1-0 Control of CAN_TX pin
// 00: Reset value, CAN_TX is controlled by the CAN Core.
// 01: Sample Point can be monitored at CAN_TX pin.
// 10: CAN_TX pin drives a dominant (‘0’) value.
// 11: CAN_TX pin drives a recessive (‘1’) value.
// Bit4: LBack Loop Back Mode
// 0/1: Loop Back Mode is disabled / enabled.
// Bit3: Silent Silent Mode
// 0/1: Normal operation / The module is in Silent Mode
// Bit2: Basic Basic Mode
// 0/1: Basic Basic Mode Disabled / Eanabled.
// In Basic Mode, IF1 Registers used as Tx Buffer, IF2 Registers used as Rx Buffer.
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config IF1 as TX.
// WR/RD Mask Arb Control ClrIntPnd TxRqst/NewDat DataA DataB
// 1(WR) 0 0 0 0 1 1 1
CAN0ADR = IF2CMDMSK; // Point to Command Mask 2
CAN0DAT = 0x001F; // Config IF2 as RX.
// WR/RD Mask Arb Control ClrIntPnd TxRqst/NewDat DataA DataB
// 0(RD) 0 0 1 1 1 1 1
CAN0CN &= ~0x41; // CAN0CN = 0x00, Clear CCE and INIT bits, Starts CAN State machine
}
/****************************************************************************
** 函数名称: CAN_ClrMsgObject(void)
** 功能描述: 清除所有CAN控制器msg object.
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
void CAN_ClrMsgObject(void)
{
uint8 i;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1
CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to Msg Obj
for(i=1; i<=32; i++)
{
CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
CAN0DATL = i;
DuS( CAN_6CLK ); // CAN_CLK = 6MHz, 6 CAN_CLK = 1uS.
}
}
// Initialize Message Object use IF2
// IFx Mask 1 Register: 15..0
// Msk15-0
// IFx Mask 2 Register: 15 14 13 12..0
// MXtd MDir reg Msk28-16
// IFx Arbitration 1 Register: 15..0
// ID15-0
// IFx Arbitration 2 Register: 15 14 13 12..0
// MsgVal Xtd Dir ID28-16
// IFx Message Control Register:
// bit 15 14 13 12 11 10 9 8 7 6..4 3..0
// NewDat MsgLst IntPnd UMask TxIE RxIE RmtEn TxRqst EoB reg DLC3-0
// IFx Data A and Data B Registers
// IFx Message Data A1: data1 data0
// IFx Message Data A2: data3 data2
// IFx Message Data B1: data5 data4
// IFx Message Data B2: data7 data6
/****************************************************************************
** 函数名称: CAN_ClrMsgObject(void)
** 功能描述: 清除所有CAN控制器msg object.
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
void CAN_InitMsgObj(unsigned char MsgNum,unsigned int CmdMsk,unsigned int Msk1,unsigned int Msk2,unsigned int Arb1,unsigned int Arb2,unsigned int MsgCtrl)
{
SFRPAGE = CAN0_PAGE; // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = CmdMsk; // Set Command Mask Registers
CAN0ADR = IF1MSK1; // Point to Mask Registers
CAN0DAT = Msk1; // Mask1
CAN0DAT = Msk2; // Mask2
CAN0DAT = Arb1; // Arbitration1
CAN0DAT = Arb2; // Arbitration2
CAN0DAT = MsgCtrl; // Msg Cntrl
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter list --initiates write to Msg Obj.
}
/****************************************************************************
** 函数名称: CAN_RunCtrl(bit RunCtrl)
** 功能描述: 启动/停止CAN控制器
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
/*
void CAN_RunCtrl(bit RunCtrl)
{
SFRPAGE = CAN0_PAGE;
if( RunCtrl )
CAN0CN &= 0xfe; // Clear the INIT bit.
else
CAN0CN |= 0x01; // Set the INIT bit.
}
*/
/****************************************************************************
** 函数名称: CAN_SendMsg()
** 功能描述: 发送msg.
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
void CAN_SendMsg(int8 MsgNum, uint8 ByteNum)
{
uint8 i = 0;
SFRPAGE = CAN0_PAGE; // IF1 already set up for TX
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config to WRITE to CAN RAM, write data bytes,
// set TXrqst/NewDat, Clr IntPnd
CAN0ADR = IF1ARB2; // Point to Arbitration2 register
CAN0DATH |= 0x80; // MsgVal = 1, Msg Valid.
CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field
CAN0DATH = CAN_SendDATA[i]; // Autoincrement through IF data bytes
if(i > ByteNum ) // DATA0
goto CAN_Send_DONE;
i++;
CAN0DATL = CAN_SendDATA[i]; // DATA1
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATH = CAN_SendDATA[i]; // DATA2
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATL = CAN_SendDATA[i]; // DATA3
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATH = CAN_SendDATA[i]; // DATA4
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATL = CAN_SendDATA[i]; // DATA5
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATH = CAN_SendDATA[i]; // DATA6
if(i > ByteNum )
goto CAN_Send_DONE;
i++;
CAN0DATL = CAN_SendDATA[i]; // DATA7
if(i > ByteNum )
goto CAN_Send_DONE;
CAN_Send_DONE: // CAN_Send_DONE
CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
}
/****************************************************************************
** 函数名称: CAN_RecvMsg()
** 功能描述: 接收msg.
** 入口参数: 无
** 出口参数: 无
** 全局变量: 无
** 调用模块: 无
** 说明:
****************************************************************************/
/*
void CAN_RecvMsg(int8 MsgNum)
{
SFRPAGE = CAN0_PAGE; // IF1 already set up for RX
CAN0ADR = IF2CMDRQST; // Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for RX from Msg Obj "MsgNum"
// Move new data to a
CAN0ADR = IF2DATA1; // Point to 1st byte of Data Field
CAN_RecvDATA[0] = CAN0DATH;
CAN_RecvDATA[1] = CAN0DATL;
CAN_RecvDATA[2] = CAN0DATH;
CAN_RecvDATA[3] = CAN0DATL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -