📄 xkcan_node.c
字号:
#include <REGX52.h>
#include <absacc.h>
#include "xkcan.h"
//#pragma OT(4, speed)
// Frame Datas and pointers
_t_can_frame idata rxCanFrame[2];
_t_can_frame * idata pWriteRxCanFrame;
_t_can_frame * idata pWriteRxCanFrameTemp;
_t_can_frame * idata pReadRxCanFrame;
_t_can_frame * idata pReadRxCanFrameTemp;
_t_can_frame * idata pCanFrameTemp;
_t_can_frame * idata pCanFrameTemp2;
_t_can_frame idata txCanFrameTemp;
_t_can_status idata sCanDefault;
extern ubyte * idata pRx485Frame;
extern _t_485_tuoke_dh4 idata tx485FrameTemp;
// Flags and global variables
ubyte volatile flag_can_ir = 0;
ubyte volatile flag_can_txc = 0;
ubyte volatile flag_can_rcv = 0;
ubyte volatile flag_uart_txc = 1;
ubyte volatile flag_uart_rcv = 0;
ubyte volatile flag_485_rcv = 0;
ubyte volatile flag_485_tx = 0;
ubyte volatile flag_timer_exp_set = 0;
ubyte volatile flag_timer_exp_timeup = 0;
ubyte volatile timer_clock_pause;
ubyte volatile timer_exp_clock_pause;
uint timer_tick1, timer_tick2;
ubyte stntype;
ubyte uart_data;
ubyte NMT_Status;
ubyte EXP_Status;
ubyte NID;
ubyte cGuardingToggle = 0x80;
ubyte timer_toggle = 0;
ubyte volatile regStatus[ETN_STATUS_BANK_COUNT + 1];
//ubyte volatile StatusNum = 0;
// Function Prototypes
void InitBoard();
ubyte EnterStatus(ubyte status);
ubyte EnterExpStatus(ubyte status);
void UpdateTimeDisplay();
void pause();
void delay(uint);
void ParseCanRxData();
void StatusMachine();
void UpdateRegStatus();
//void serial_IT(void) interrupt SIO_VECTOR
//void ex1_int(void) interrupt IE1_VECTOR
void main(void)
{
ubyte noop = 0;
InitBoard();
EnterStatus(STATUS_INITIALISING);
timer_tick2 = TIMER_Count();
while (1)
{
// Parse Received Data
timer_tick1 = TIMER_Count();
if ( flag_can_rcv == 1 )
{
flag_can_rcv = 0;
ParseCanRxData();
}
// Deal with the status machine
StatusMachine();
// Clock Stuffs
if ((timer_tick_500ms & 1) == 1 )
{
timer_tick_500ms = 0;
UpdateClock();
UpdateTimeDisplay();
}
//P1 = ~NID;//~NMT_Status;
}
}
void InitBoard()
{
// Set default CAN parameters
sCanDefault.btr0 = 0x01; // 250kbps at 16MHz crystal
sCanDefault.btr1 = 0x1c;
//sCanDefault.cobid = _GEN_COBID(0x0F, NID);
NID = ~P1;
sCanDefault.acr0 = ( (ubyte)NID >>3 ) & 0x0f;
sCanDefault.acr1 = ( (ubyte)NID <<5 ) & 0xe0;
sCanDefault.acr2 = 0;//( sCanDefault.cobid >>3 ) & 0x0f;
sCanDefault.acr3 = 0;//( sCanDefault.cobid <<5 ) & 0xe0;
sCanDefault.amr0 = 0xf0;
sCanDefault.amr1 = 0x1f;
sCanDefault.amr2 = 0xf0;
sCanDefault.amr3 = 0x1f;
sCanDefault.mod = 0;
sCanDefault.cdr = SJA1000_CDR_CLOCK_OFF|SJA1000_CDR_PELICAN_MODE|SJA1000_CDR_CBP;
sCanDefault.ocr = SJA1000_OCR_MODE_NORMAL|SJA1000_OCR_TX0_PUSHPULL;
sCanDefault.ier = SJA1000_IER_RIE|SJA1000_IER_TIE;
pWriteRxCanFrame = &rxCanFrame[0];
pWriteRxCanFrameTemp = &rxCanFrame[1];
pReadRxCanFrame = &rxCanFrame[0];
pReadRxCanFrameTemp = &rxCanFrame[1];
// Device Initialization
DIG_Init();
TIMER_Init();
_485_Init();
CAN_Init(&sCanDefault);
// Device Open
TIMER_Reset();
CLOCK_Set(1, 2, 3);
CLOCK_Exp_Set(4, 5, 6);
DIG_Open();
TIMER_Start();
CLOCK_Start();
CAN_Open(&sCanDefault);
// Enable global interrupt
EA = 1;
EX1 = 1;
}
ubyte EnterStatus(ubyte status)
{
if (status == STATUS_INITIALISING)
{
NMT_Status = status;
}
else if (status == STATUS_RESET_APP)
{
EnterExpStatus(EXP_PRE_INIT);
NMT_Status = status;
}
else if (status == STATUS_RESET_COMM)
{
NMT_Status = status;
}
else if (status == STATUS_PRE_OPERATIONAL)
{
// Send BootUp Frame
cGuardingToggle = (~cGuardingToggle & 0x80);
txCanFrameTemp.dlc = 2;
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_NMT_EC, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = cGuardingToggle | NMT_Status;
txCanFrameTemp.dat[1] = EXP_Status;
CAN_Transmit( &txCanFrameTemp );
NMT_Status = status;
}
else if (status == STATUS_OPERATIONAL)
{
NMT_Status = status;
}
else if (status == STATUS_STOPPED)
{
EnterExpStatus(EXP_STOPPED);
NMT_Status = status;
}
else
{
//TODO: Add your error handling code here
//ERROR: Wrong Status
return STATUS_ERROR;
}
return status;
}
ubyte EnterExpStatus(ubyte status)
{
if (status == EXP_PRE_INIT)
{
CLOCK_Exp_Reset();
EXP_Status = status;
}
else if (status == EXP_INITIALISING)
{
CLOCK_Exp_Init();
EXP_Status = status;
}
else if (status == EXP_STANDBY)
{
EXP_Status = status;
}
else if (status == EXP_RUNNING)
{
CLOCK_Exp_Start();
EXP_Status = status;
}
else if (status == EXP_PAUSE)
{
CLOCK_Exp_Pause();
EXP_Status = status;
}
else if (status == EXP_FAULT)
{
EXP_Status = status;
}
else if (status == EXP_STOPPED)
{
CLOCK_Exp_Stop();
EXP_Status = status;
}
else if (status == EXP_END_REQUEST)
{
CLOCK_Exp_Stop();
flag_timer_exp_set = 0;
txCanFrameTemp.dlc = 1;
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_SDO_RX, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = SDO_CS_EXP_END_REQUEST;
CAN_Transmit( &txCanFrameTemp );
EXP_Status = status;
}
else if (status == EXP_END)
{
CLOCK_Exp_Stop();
EXP_Status = status;
}
else
{
//TODO: Add your error handling code here
//ERROR: Wrong Status
return EXP_STATUS_ERROR;
}
return status;
}
void ex1_int(void) interrupt IE1_VECTOR //using 3 //外部中断1
{
EA = 0;
flag_can_ir = CAN_ReadReg(SJA1000_IR); //保持中断寄存器值
if ( flag_can_ir & SJA1000_IR_RI != 0 )
{
CAN_Receive (pWriteRxCanFrame);
pCanFrameTemp = pWriteRxCanFrameTemp;
pWriteRxCanFrameTemp = pWriteRxCanFrame;
pWriteRxCanFrame = pCanFrameTemp;
flag_can_rcv = 1;
}
if ( flag_can_ir & SJA1000_IR_TI != 0 )
{
flag_can_txc = 1;
}
EA = 1;
}
void serial_IT(void) interrupt SIO_VECTOR
{
EA = 0;
if (RI == 1)
{ /* if reception occur */
RI = 0; /* clear reception flag for next reception */
uart_data = SBUF; /* Read receive data */
flag_uart_rcv = 1;
}
else
{
flag_uart_txc = 1;
TI = 0; /* if emission occur */
}
EA = 1;
/* clear emission flag for next emission*/
}
void pause(){for(;;);}
void delay(uint t)
{
int iTemp;
for ( iTemp = 0; iTemp < t; iTemp++ );
}
void ParseCanRxData()
{
ubyte cTemp, i, dlc;
ubyte csTemp, fcTemp;
dlc = pReadRxCanFrame->dlc;
fcTemp = _GET_FRAME_FC(pReadRxCanFrame);
csTemp = pReadRxCanFrame->dat[0];
if ( fcTemp == FC_NMT_MC)
{
if ( csTemp == NMT_MC_CS_START_REMOTE )
{
EnterStatus(STATUS_OPERATIONAL);
}
else if ( csTemp == NMT_MC_CS_STOP_REMOTE )
{
EnterStatus(STATUS_STOPPED);
}
else if ( csTemp == NMT_MC_CS_ENTER_PRE_OP )
{
EnterStatus(STATUS_PRE_OPERATIONAL);
}
else if ( csTemp == NMT_MC_CS_RESET_NODE )
{
EnterStatus(STATUS_RESET_APP);
}
else if ( csTemp == NMT_MC_CS_RESET_COMM )
{
EnterStatus(STATUS_RESET_COMM);
}
else
{
//TODO: Add your error handling code here
//ERROR: Recevied undefined NMT Module Control frame
}
// Different Response of p2p frame or broadcast frame
}
else if ( fcTemp == FC_NMT_EC )
{
if ( pReadRxCanFrame->rtr == 1 )//&& _GET_FRAME_NID(pReadRxCanFrame) == NID)
{
cGuardingToggle = (~cGuardingToggle & 0x80);
cTemp = cGuardingToggle | NMT_Status;
txCanFrameTemp.dlc = 2;
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_NMT_EC, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = cTemp;
txCanFrameTemp.dat[1] = EXP_Status;
CAN_Transmit( &txCanFrameTemp );
}
else
{
//TODO: Add your error handling code here
//ERROR: Recevied undefined NMT Error Control frame
}
}
else if ( fcTemp == FC_SYNC )
{
}
else if ( fcTemp == FC_TIME_STAMP )
{
CLOCK_Set(csTemp, pReadRxCanFrame->dat[1], pReadRxCanFrame->dat[2] );
TIMER_Restart();
CLOCK_Start();
}
else if ( fcTemp == FC_EMCY )
{
}
else if ( NMT_Status == STATUS_OPERATIONAL )
{
if ( fcTemp == FC_PDO1_TX )
{
if ( csTemp == PDO1_TX_SET_SWITCH )
{
Switch_Write(0x10);
for ( i = 1; i <= ETN_SWITCH_BANK_COUNT; i++ )
{
Switch_Write( pReadRxCanFrame->dat[i] );
}
}
else if ( csTemp == PDO1_TX_SET_SPC_SWITCH )
{
Switch_Write(0x1f + dlc);
for ( i = 1; i < dlc; i++ )
{
Switch_Write( pReadRxCanFrame->dat[i] );
}
}
else if ( csTemp == PDO1_TX_GET_STATUS )
{
txCanFrameTemp.dlc = 1 + ETN_STATUS_BANK_COUNT;
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_PDO1_RX, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = PDO1_TX_GET_STATUS;
for ( i = 1; i <= ETN_STATUS_BANK_COUNT; i++ )
{
txCanFrameTemp.dat[i] = regStatus[i];
}
CAN_Transmit( &txCanFrameTemp );
}
else if ( csTemp == PDO1_TX_GET_SPC_STATUS )
{
txCanFrameTemp.dlc = dlc;
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_PDO1_RX, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = PDO1_TX_GET_SPC_STATUS;
for ( i = 1; i < dlc; i++ )
{
cTemp = pReadRxCanFrame->dat[i];
txCanFrameTemp.dat[i] = cTemp | ( ( ((regStatus[cTemp>>3])>>(cTemp&0x7)) & 0x01) << 7 );
// No error handling here
}
CAN_Transmit( &txCanFrameTemp );
// Reserved
}
}
else if ( fcTemp == FC_PDO2_TX )
{
if ( csTemp == PDO2_485_READ && flag_485_tx == 0 )
{
_485_GenerateReadFrame( pReadRxCanFrame->dat[1], pReadRxCanFrame->dat[2], &tx485FrameTemp);
stntype = pReadRxCanFrame->dat[1];
flag_485_tx = 1;
}
/* else if ( csTemp == PDO2_485_CTRL && flag_485_tx == 0)
{
//Generate a full frame from CAN
//flag_485_tx = 1;
}
else if ( csTemp == PDO2_485_CTRL_1 && flag_485_tx == 0)
{
//Generate a full frame from CAN
//flag_485_tx = 1;
}
else if ( csTemp == PDO2_485_CTRL_C && flag_485_tx == 0)
{
//Generate a full frame from CAN
//flag_485_tx = 1;
}
else if ( csTemp == PDO2_485_CTRL_C_1 && flag_485_tx == 0)
{
//Generate a full frame from CAN
//flag_485_tx = 1;
}
else
{
// ERROR Handling
}
*/
}
else if ( fcTemp == FC_SDO_TX )
{
if ( csTemp == SDO_CS_EXP_TIME )
{
CLOCK_Exp_Set( pReadRxCanFrame->dat[1], pReadRxCanFrame->dat[2], pReadRxCanFrame->dat[3]);
flag_timer_exp_set = 1;
}
else if ( csTemp == SDO_CS_EXP_START )
{
if (flag_timer_exp_set == 1)
EnterExpStatus(EXP_RUNNING);
}
else if ( csTemp == SDO_CS_EXP_STOP )
{
EnterExpStatus(EXP_STOPPED);
}
else if ( csTemp == SDO_CS_EXP_PAUSE )
{
EnterExpStatus(EXP_PAUSE);
}
else if ( csTemp == SDO_CS_EXP_RESET )
{
EnterExpStatus(EXP_INITIALISING);
}
else if ( csTemp == SDO_CS_EXP_RESUME )
{
EnterExpStatus(EXP_RUNNING);
}
else if ( csTemp == SDO_CS_EXP_END )
{
EnterExpStatus(EXP_END);
}
else
{
//TODO: Add your error handling code here
//ERROR: Recevied undefined NMT Module Control frame
}
}
else
{
//Error Handle
}
}
// Data received. After all dealings, switch the ping-pong buffer
pCanFrameTemp2 = pReadRxCanFrameTemp;
pReadRxCanFrameTemp = pReadRxCanFrame;
pReadRxCanFrame = pCanFrameTemp2;
}
void StatusMachine()
{
if (NMT_Status == STATUS_INITIALISING)
{
//STATUS_INITIALISING
EnterStatus (STATUS_RESET_APP); // automatically
}
else if (NMT_Status == STATUS_RESET_APP)
{
//STATUS_RESET_APP
EnterStatus (STATUS_RESET_COMM); // automatically
}
else if (NMT_Status == STATUS_RESET_COMM)
{
//STATUS_RESET_COMM
EnterStatus (STATUS_PRE_OPERATIONAL); // automatically
}
else if (NMT_Status == STATUS_PRE_OPERATIONAL)
{
//STATUS_PRE_OPERATIONAL
//EnterStatus (STATUS_OPERATIONAL); // automatically
}
else if (NMT_Status == STATUS_OPERATIONAL)
{
// Check all instruments and other devices's status
UpdateRegStatus();
// Send Data to 485 bus
_485_SendData(stntype);
// Receive Data from UART, this might be 485 data
stntype = _485_ReceiveData();
//CRC Check
//if ( flag_485_rcv == 1 )
//{
// if ( _485_Tuoke_DH4_CRCCheck( pRx485Frame ) != 1 );
// flag_485_rcv = 0;
//}
// SEND 485 data to CAN
if (flag_485_rcv == 1 )
{
txCanFrameTemp.cobid = _GEN_D_COBID(FC_D_PDO2_RX, NID);
txCanFrameTemp.rtr = 0;
txCanFrameTemp.dat[0] = PDO2_485_READ;
txCanFrameTemp.dat[1] = stntype;
if (stntype == INSTR_TUOKE_DH4)
{
txCanFrameTemp.dlc = 5;
txCanFrameTemp.dat[2] = ((_t_485_tuoke_dh4_rx *)pRx485Frame)->stn;
txCanFrameTemp.dat[3] = ((_t_485_tuoke_dh4_rx *)pRx485Frame)->dat_L;
txCanFrameTemp.dat[4] = ((_t_485_tuoke_dh4_rx *)pRx485Frame)->dat_H;
}
CAN_Transmit( &txCanFrameTemp );
flag_485_rcv = 0;
}
if (EXP_Status == EXP_PRE_INIT)
{
EnterExpStatus(EXP_INITIALISING);
}
else if (EXP_Status == EXP_INITIALISING)
{
if (flag_timer_exp_set == 1)
EnterExpStatus(EXP_STANDBY);
}
else if (EXP_Status == EXP_STANDBY)
{
;
}
else if (EXP_Status == EXP_RUNNING)
{
if (flag_timer_exp_timeup == 1)
{
EnterExpStatus(EXP_END_REQUEST);
}
}
else if (EXP_Status == EXP_PAUSE)
{
;
}
else if (EXP_Status == EXP_FAULT)
{
;
}
else if (EXP_Status == EXP_STOPPED)
{
EnterExpStatus(EXP_END_REQUEST);
}
else if (EXP_Status == EXP_END_REQUEST)
{
;
}
else if (EXP_Status == EXP_END)
{
;
}
else if (EXP_Status == EXP_STATUS_ERROR)
{
;
}
else
{
;
}
}
else if (NMT_Status == STATUS_STOPPED)
{
//STATUS_STOPPED
}
else
{
// STATUS_DEFAULT
}
}
void UpdateRegStatus()
{
ubyte cTemp;
if ( timer_tick1 != timer_tick2 )
{
timer_tick2 = TIMER_Count();
cTemp = Status_Read();
if (cTemp == 0x55)
{
regStatus[1] = Status_Read();
}
else
{
cTemp = Status_Read();
cTemp = Status_Read();
}
cTemp = Status_Read();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -