📄 main.c
字号:
void external_osc (void)
{
int n; // local variable used in delay FOR loop.
SFRPAGE = CONFIG_PAGE; // switch to config page to config oscillator
OSCXCN = 0x77; // start external oscillator; 22.1 MHz Crystal
// system clock is 22.1 MHz / 2 = 11.05 MHz
for (n=0;n<255;n++); // delay about 1ms
while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize
CLKSEL |= 0x01; // switch to external oscillator
}
void config_IO (void)
{
SFRPAGE = CONFIG_PAGE; //Port SFR's on Configuration page
XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull digital output
P5MDOUT |= 0x0f;
P5=0xfe;
P2MDOUT |= 0x18; // Configure P2.3 as push-pull to drive LED
XBR2 = 0x40; // Enable Crossbar/low ports
}
////////////////////////////////////////////////////////////////////////////////
//CAN Functions
////////////////////////////////////////////////////////////////////////////////
//Clear Message Objects
void clear_msg_objects (void)
{
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<33;i++)
{
CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
CAN0DATL = i;
}
}
//Initialize Message Object for RX
void init_msg_object_RX (char MsgNum)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B8; // Set to WRITE, and alter all Msg Obj except ID MASK
// and data bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to "0"
CAN0DAT = 0x8000; // Arb2 high byte:Set MsgVal bit, no extended ID,
// Dir = RECEIVE
CAN0DAT = 0x0480; // Msg Cntrl: set RXIE, remote frame function disabled
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DATL = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF register contents to the Msg Obj in CAN RAM
}
//Initialize Message Object for TX
void init_msg_object_TX (char MsgNum)
{
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x00B2; // Set to WRITE, & alter all Msg Obj except ID MASK bits
CAN0ADR = IF1ARB1; // Point to arbitration1 register
CAN0DAT = 0x0000; // Set arbitration1 ID to highest priority
CAN0DAT = 0xA004; // Autoincrement to Arb2 high byte:
// Set MsgVal bit, no extended ID, Dir = WRITE
CAN0DAT = 0x0081; // Msg Cntrl: DLC = 1, remote frame function not enabled
CAN0ADR = IF1CMDRQST; // Point to Command Request reg.
CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter list
// --initiates write to Msg Obj
// 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN RAM.
}
//Start CAN
void start_CAN (void)
{
/* Calculation of the CAN bit timing :
System clock f_sys = 22.1184 MHz/2 = 11.0592 MHz.
System clock period t_sys = 1/f_sys = 90.422454 ns.
CAN time quantum tq = t_sys (at BRP = 0)
Desired bit rate is 1 MBit/s, desired bit time is 1000 ns.
Actual bit time = 11 tq = 996.65ns ~ 1000 ns
Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381%
CAN bus length = 10 m, with 5 ns/m signal delay time.
Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns
(maximum loop delay between CAN nodes)
Prop_Seg = 5 tq = 452 ns ( >= 400 ns).
Sync_Seg = 1 tq
Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq
Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq
SJW = (min(Phase_Seg1, 4) tq = 2 tq
TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6
TSEG2 = (Phase_Seg2 - 1) = 2
SJW_p = (SJW - 1) = 1
Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640
Clock tolerance df :
A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2))
B: df < SJW / (20 * bit_time)
A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246%
B: df < 2/(20*11) = 1/110 = 0.9091%
Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz)
*/
SFRPAGE = CAN0_PAGE;
CAN0CN |= 0x41; // Configuration Change Enable CCE and INIT
CAN0ADR = BITREG ; // Point to Bit Timing register
CAN0DAT = 0x2640; // see above
CAN0ADR = IF1CMDMSK; // Point to Command Mask 1
CAN0DAT = 0x0087; // Config for TX : WRITE to CAN RAM, write data bytes,
// set TXrqst/NewDat, clr IntPnd
// RX-IF2 operation may interrupt TX-IF1 operation
CAN0ADR = IF2CMDMSK; // Point to Command Mask 2
CAN0DATL = 0x1F; // Config for RX : READ CAN RAM, read data bytes,
// clr NewDat and IntPnd
CAN0CN |= 0x06; // Global Int. Enable IE and SIE
CAN0CN &= ~0x41; // Clear CCE and INIT bits, starts CAN state machine
}
/***********************************************************************************
* 函数名称:Timer0_ISR;
*
* 函数功能描述:定时器0中断响应;
*
* 输入参数:none;
*
* 返回数据:none;
*
* 注意: none;
************************************************************************************/
void Timer0_ISR (void) interrupt 1
{
char data SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = SFR_PAGE_0; // set SFR page F
i++;
if(i==10)
{
i=0;
flag=~flag;
}
TF0 = 0; // 清除中断标志
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
/***********************************************************************************
* 函数名称:LED_state;
*
* 函数功能描述:LED开关控制 0:关闭,其他:开启;
*
* 输入参数:0:关闭,其他:开启;
*
* 返回数据:none;
*
* 注意: none;
************************************************************************************/
void LED_state(unsigned char flag)
{
if(flag)
transmit_Byte(0x01);
// else
// LED=0;
}
void transmit_Byte (char MsgNum)
{
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 = IF1DATA1; // Point to 1st byte of Data Field
// CAN0DATL = bytedata; // Ones signals to transmit byte data
for(i=0;i<=100;i++)
{ CAN0DATL = i; // Ones signals to transmit byte data
CAN0ADR = IF1CMDRQST; // Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum"
}
}
/***********************************************************************************/
// 文件结束
/***********************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -