📄 main.c
字号:
Uart1_SendByte(CAN_Data[pcan++]);
//canlength--;
if(pcan== 8)
{
able1=0;//保护,防止溢出
CAN_Data[0]=0;
CAN_Data[1]=0;
CAN_Data[2]=0;
CAN_Data[3]=0;
CAN_Data[4]=0;
CAN_Data[5]=0;
CAN_Data[6]=0;
CAN_Data[7]=0;
}
if(pcan >= 8) pcan=0;//保护,防止溢出
}
if(able2)//需要8通道一起传送时收到64字节数据
{
//if(pchanl%8 ==0 )
//Delay_s(5);
{
for(i=1;i<=64;i++)
{
Uart1_SendByte(CAN_Datachannel[pchanl++]);
}
}
//Uart1_SendByte(CAN_Datachannel[pchanl++]);
//canlength--;
if(pchanl == 64)
{
able2=0;//保护,防止溢出
}
if(pchanl >= 64) pchanl=0;//保护,防止溢出
}
if(puart==4)
{
if((nexten==1) && (jjj==1))
{
CAN_trans(0x0A);
}
}
}
}
/***********************************************************************************/
// 文件结束
/***********************************************************************************/
////////////////////////////////////////////////////////////////////////////////
//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 (ii=1;ii<33;ii++)
{
CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj
CAN0DATL = ii;
}
}
//Initialize Message Object for RX
//*********** MsgNum代表消息对象号码,ID代表该消息对象的优先级 **********
void init_msg_object_RX (char MsgNum,ID)
{
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" 因为no extended ID 故仲裁位只有ID28~18有效
// 即高字的XXX0 0000 0000 00xx中的'0'为11位有效仲裁位,
// 我们将主机广播的仲裁的消息作为 0 (优先级最高),其余从1开始
CAN0DAT = 0x8000+ID*4; // Arb2 high byte:Set MsgVal bit, no extended ID,
// Dir = RECEIVE
// 因为我们是从机,故接受来自主机的消息处 仲裁应为 0
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
//*********** MsgNum代表消息对象号码,ID代表该消息对象的优先级 **********
void init_msg_object_TX (char MsgNum,ID)
{
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 = 0xA000+ID*4; // Autoincrement to Arb2 high byte:
// Set MsgVal bit, no extended ID, Dir = WRITE
// 因为我们是主机,故发送到从机的广播消息处 仲裁设为 0
CAN0DAT = 0x0088; // Msg Cntrl: DLC = 8, remote frame function not enabled****************每帧1字节数据
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 = 11.0592 MHz/2 = 5.5296 MHz.
System clock period t_sys = 1/f_sys =180.808449 ns.
CAN time quantum tq = t_sys (at BRP = 0)
*/
SFRPAGE = CAN0_PAGE;
CAN0CN |= 0x41; // Configuration Change Enable CCE and INIT
CAN0ADR = BITREG ; // Point to Bit Timing register
CAN0DAT = 0x7FFF; // 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
}
//指定每帧字节数的CAN传送
void CAN_trans (char MsgNum)
{
unsigned char i=0;
unsigned int charnum = 0;
//unsigned char charh, charl;
// if(puart<puart1) charnum=puart+QUENEUART-puart1;
// else if(puart>puart1) charnum=puart-puart1;
// else return;
// if(charnum>=8) charnum=8; //charnum即待传送字节(<=8)的确认
//固定每帧8字节,不足填充0xFF的情况
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
for(i=1;i<=4;i++)
{ if(i%2)
CAN0DATH=UART_Data[puart1++];
else
CAN0DATL=UART_Data[puart1++];
if(puart1>=4) puart1=0;
}
puart=0;
// for(;i<=8;i++)
// { if(i%2) CAN0DATH=0xFF;
// CAN0DATL=0xFF; }
nexten=0; //本消息要发送,后面的数据要等我的TxOK中断信号
UART_Data[0]=0;
UART_Data[1]=0;
UART_Data[2]=0;
UART_Data[3]=7;
jjj=0;
CAN0ADR = IF1CMDRQST;
CAN0DATL = MsgNum;
}
// Receive Data from the IF2 buffer
void receive_data (char MsgNum)
{
unsigned char i=1, recdata=0xFF;
char SFRPAGE_SAVE = SFRPAGE; // Save SFRPAGE
//每帧8字节,多余补充0xFF的情况
SFRPAGE = CAN0_PAGE; // IF1 already set up for RX
CAN0ADR = IF2CMDMSK;
CAN0DAT = 0x000F;
CAN0ADR = IF2CMDRQST;// Point to Command Request Reg.
CAN0DATL = MsgNum; // Move new data for RX from Msg Obj "MsgNum"
CAN0ADR=IF2DATA1;
for(i=1;i<=8;i++)
{
if(i%2) recdata=CAN0DATH;
else recdata=CAN0DATL;
LED = ~LED;
if(channelable == 0)
{
if(pcan <= 7)
{
CAN_Data[pcan++]=recdata;
// canlength++;
}
if(pcan == 8)
{
pcan=0;
able1=1;//收到8字节时允许发送数据
}
}
if(channelable == 1)
{
if(pchanh<=63)
{
CAN_Datachannel[pchanh++]=recdata;
}
if(pchanh == 64)
{
pchanh=0;
able2=1;//收到64字节时允许发送数据
}
}
}
SFRPAGE = SFRPAGE_SAVE;
}
////////////////////////////////////////////////////////////////////////////////
//Interrupt Service Routine
////////////////////////////////////////////////////////////////////////////////
void ISRcan (void) interrupt 19
{
char data MsgNum;
char SFRPAGE_SAVE = SFRPAGE; // Save SFRPAGE
SFRPAGE = CAN0_PAGE;
status = CAN0STA;
if ((status&0x10) != 0)
{ // RxOk is set, interrupt caused by reception
CAN0STA = (CAN0STA&0xEF)|0x07; // Reset RxOk, set LEC to NoChange
/* read message number from CAN INTREG */
CAN0ADR = INTREG;
MsgNum = CAN0DATL;
receive_data (MsgNum); // Up to now, we have only one RX message
}
if ((status&0x08) != 0)
{ // TxOk is set, interrupt caused by transmision
CAN0STA = (CAN0STA&0xF7)|0x07; // Reset TxOk, set LEC to NoChange
//CAN_trans (0x0A);
nexten=1;
}
if (((status&0x07) != 0)&&((status&0x07) != 7))
{ // Error interrupt, LEC changed
/* error handling ? */
CAN0STA = CAN0STA|0x07; // Set LEC to NoChange
}
//if((status&0x07)==7) CAN0STA=0;
SFRPAGE = SFRPAGE_SAVE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -