#include "Head.h"
U8 Send_data[8];
U8 Receive_data[8];
void CAN0_Init()
{
U8 i;
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CAN0_PAGE; // All CAN register are on page 0x0C
CAN0CN |= 0x01; // Start Intialization mode
//---------Initialize general CAN peripheral settings
CAN0CN |= 0x4E; // Enable Status, Error,
// Module Interrupts
// Enable access to bit timing register
// See the CAN Bit Timing Spreadsheet for how to calculate this value
CAN0BT = 0x1C02; // Based on 24 Mhz CAN clock, set the
// CAN bit rate to 500 Kbps - 1C02
//---------Initialize settings common to all message objects
// Command Mask Register
CAN0IF1CM = 0x00F0; // Write Operation
// Transfer ID Mask, MDir, MXtd
// Transfer ID, Dir, Xtd, MsgVal
// Transfer Control Bits
// Don't set TxRqst or transfer data
CAN0IF2CM = 0x00F0;
// Mask Registers
CAN0IF1M1 = 0xffff; // Mask Bits 15-0 not used for filtering
CAN0IF1M2 = 0xffff; // Ignore Extended Identifier for
// filtering
// Used Direction bit for filtering
// Use ID bits 28-18 for filtering
CAN0IF2M1 = 0xffff;
CAN0IF2M2 = 0xffff;
;
//IF1用于发送,源地址为0x01,目的地址为0x0a
//IF2用于接收,源地址为0x0a,目的地址为0x01
for(i = 0; i < 9; i ++)
{
switch(i){
case 0:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (0<<10); //无折分,消息类型:0x00
CAN0IF1MC = 0x0880 | 0;
break;
case 1:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (1<<10); //无折分,消息类型:0x01
CAN0IF1MC = 0x0880 | 1;
break;
case 2:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (2<<10); //无折分,消息类型: 0x02 //设置
CAN0IF1MC = 0x0880 | 3;
break;
case 3:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (2<<10); //无折分,消息类型: 0x02 //查询
CAN0IF1MC = 0x0880 | 1;
break;
case 4:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (3<<10); //无折分,消息类型: 0x03查询
CAN0IF1MC = 0x0880 | 1;
break;
case 5:
// Arbitration Registers
CAN0IF1A1 = 0x0002 | (3<<10); //首帧,消息类型: 0x03
CAN0IF1MC = 0x0880 | 8;
break;
case 6:
// Arbitration Registers
CAN0IF1A1 = 0x0000 | (3<<10); //中间帧,消息类型: 0x03
CAN0IF1MC = 0x0880 | 8;
break;
case 7:
// Arbitration Registers
CAN0IF1A1 = 0x0001 | (3<<10); //尾帧,消息类型: 0x03
CAN0IF1MC = 0x0880 | 8;
break;
case 8:
// Arbitration Registers
CAN0IF1A1 = 0x0003 | (4<<10); //无折分,消息类型: 0x04 ,查询
CAN0IF1MC = 0x0880 | 0;
break;
default:
break;
}
CAN0IF1A2 = 0xe0a8;
CAN0IF1CR = i;
while (CAN0IF1CRH & 0x80) {}
//CAN0IF2A2 = 0xc0a8;
}
//接收
for(i = 9; i < 15; i ++)
{
switch(i){
case 9:
CAN0IF2A1 = 0x0003 | (1<<10); //无折分,消息类型:0x01
CAN0IF2MC = 0x1480 | 1;
break;
case 10:
CAN0IF2A1 = 0x0003 | (2<<10); //无折分,消息类型:0x02
CAN0IF2MC = 0x1480 | 3;
break;
case 11:
CAN0IF2A1 = 0x0002 | (3<<10); //首帧,消息类型: 0x03
CAN0IF2MC = 0x1480 | 8;
break;
case 12:
CAN0IF2A1 = 0x0000 | (3<<10); //中间帧,消息类型: 0x03
CAN0IF2MC = 0x1480 | 8;
break;
case 13:
CAN0IF2A1 = 0x0001 | (3<<10); //尾帧,消息类型: 0x03
CAN0IF2MC = 0x1480 | 8;
break;
case 14:
CAN0IF2A1 = 0x0003 | (4<<10); //无折分,消息类型: 0x04
CAN0IF2MC = 0x1480 | 5;
break;
default:
break;
}
CAN0IF2A2 = 0xc504;
CAN0IF2CR = i;
while (CAN0IF2CRH & 0x80) {}
}
//---------Initialize settings for unused message objects
for (i = 15; i < 32; i ++)
{
// Set remaining message objects to be Ignored
CAN0IF1A2 = 0x0000; // Set MsgVal to 0 to Ignore
CAN0IF1CR = i; // Start command request
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
CAN0IF2A2 = 0x0000; // Set MsgVal to 0 to Ignore
CAN0IF2CR = i; // Start command request
while (CAN0IF2CRH & 0x80) {} // Poll on Busy bit
}
CAN0CN &= ~0x41; // Return to Normal Mode and disable
// access to bit timing register
SFRPAGE = SFRPAGE_save;
}
void CAN0_TransferMO (U8 obj_num)
{
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CAN0_PAGE;
CAN0IF1DA1L = Send_data[0];
CAN0IF1DA1H = Send_data[1];
CAN0IF1DA2L = Send_data[2];
CAN0IF1DA2H = Send_data[3];
CAN0IF1DB1L = Send_data[4];
CAN0IF1DB1H = Send_data[5];
CAN0IF1DB2L = Send_data[6];
CAN0IF1DB2H = Send_data[7];
CAN0IF1CM = 0x0087; // Set Direction to Write
// Write TxRqst, all 8 data bytes
CAN0IF1CR = obj_num; // Start command request
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
}
INTERRUPT (CAN0_ISR, INTERRUPT_CAN0)
{
U8 SFRPAGE_save = SFRPAGE;
// SFRPAGE is set to CAN0_Page automatically when ISR starts
U8 status = CAN0STAT; // Read status, which clears the Status
// Interrupt bit pending in CAN0IID
U8 Interrupt_ID = CAN0IID; // Read which message object caused
// the interrupt
if (status & TxOk) // If transmit completed successfully
{
CAN0IF1CM = 0x0008;
CAN0IF1CR = Interrupt_ID;
while (CAN0IF1CRH & 0x80) {}
if (Interrupt_ID == 0x20) Interrupt_ID = 0x00;
}
if (status & RxOk) // If transmit completed successfully
{
//SFRPAGE = ACTIVE_PAGE;
//LED = 0;
//Data_Init(Receive_data,8);
//SFRPAGE = SFRPAGE_save;
CAN0IF2CM = 0x007F;
CAN0IF2CR = Interrupt_ID;
while (CAN0IF1CRH & 0x80) {} // Poll on Busy bit
CAN0IF2CR = Interrupt_ID;
Receive_data[0] = CAN0IF2DA1L;
Receive_data[1] = CAN0IF2DA1H;
Receive_data[2] = CAN0IF2DA2L;
Receive_data[3] = CAN0IF2DA2H;
Receive_data[4] = CAN0IF2DB1L;
Receive_data[5] = CAN0IF2DB1H;
Receive_data[6] = CAN0IF2DB2L;
Receive_data[7] = CAN0IF2DB1H;
if (Interrupt_ID == 0x20) Interrupt_ID = 0x00;
make_data(Interrupt_ID);
}
}