|
|
楼主 |
发表于 2026-9-22 19:41:40
|
显示全部楼层
你好老师,代码大概如下,按照例程里面的稍微修改了一下。
if(sr & 0x01) //判断是否有 BS:BUS-OFF状态
{
CANAR = MR;
CANDR &= ~0x04; //清除 Reset Mode, 从BUS-OFF状态退出
}
else
{
CanSendMsg(CAN_ID,TX_BUF);
}
}
}
}
}
/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt 1
{
B_1ms = 1; //1ms标志
// led=!led;
}
//========================================================================
// 函数: u8 CanReadReg(u8 addr)
// 描述: CAN功能寄存器读取函数。
// 参数: CAN功能寄存器地址.
// 返回: CAN功能寄存器数据.
// 版本: VER1.0
// 日期: 2020-11-16
// 备注:
//========================================================================
u8 CanReadReg(u8 addr)
{
u8 dat;
CANAR = addr;
dat = CANDR;
return dat;
}
//========================================================================
// 函数: void CanWriteReg(u8 addr, u8 dat)
// 描述: CAN功能寄存器配置函数。
// 参数: CAN功能寄存器地址, CAN功能寄存器数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-16
// 备注:
//========================================================================
void CanWriteReg(u8 addr, u8 dat)
{
CANAR = addr;
CANDR = dat;
}
//========================================================================
// 函数: void CanReadFifo(u8 *pdat)
// 描述: 读取CAN缓冲区数据函数。
// 参数: *pdat: 存放CAN缓冲区数据.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-16
// 备注:
//========================================================================
void CanReadFifo(u8 *pdat)
{
pdat[0] = CanReadReg(RX_BUF0);
pdat[1] = CanReadReg(RX_BUF1);
pdat[2] = CanReadReg(RX_BUF2);
pdat[3] = CanReadReg(RX_BUF3);
pdat[4] = CanReadReg(RX_BUF0);
pdat[5] = CanReadReg(RX_BUF1);
pdat[6] = CanReadReg(RX_BUF2);
pdat[7] = CanReadReg(RX_BUF3);
pdat[8] = CanReadReg(RX_BUF0);
pdat[9] = CanReadReg(RX_BUF1);
pdat[10] = CanReadReg(RX_BUF2);
pdat[11] = CanReadReg(RX_BUF3);
pdat[12] = CanReadReg(RX_BUF0);
pdat[13] = CanReadReg(RX_BUF1);
pdat[14] = CanReadReg(RX_BUF2);
pdat[15] = CanReadReg(RX_BUF3);
}
//========================================================================
// 函数: u16 CanReadMsg(u8 *pdat)
// 描述: CAN接收数据函数。
// 参数: *pdat: 接收数据缓冲区.
// 返回: CAN ID.
// 版本: VER1.0
// 日期: 2020-11-19
// 备注:
//========================================================================
u16 CanReadMsg(u8 *pdat)
{
u8 i;
u16 CanID;
u8 buffer[16];
CanReadFifo(buffer);
CanID = ((buffer[1] << 8) + buffer[2]) >> 5;
for(i=0;i<8;i++)
{
pdat = buffer[i+3];
}
return CanID;
}
//========================================================================
// 函数: void CanSendMsg(u16 canid, u8 *pdat)
// 描述: CAN发送数据函数。
// 参数: canid: CAN ID; *pdat: 发送数据缓冲区.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-19
// 备注:
//========================================================================
void CanSendMsg(u16 canid, u8 *pdat)
{
u16 CanID;
CanID = canid << 5;
// CanWriteReg(TX_BUF0,0x08); //bit7: 标准帧(0)/扩展帧(1), bit6: 数据帧(0)/远程帧(1), bit3~bit0: 数据长度(DLC)
CanWriteReg(TX_BUF0,changdu);
CanWriteReg(TX_BUF1,(u8)(CanID>>8));
CanWriteReg(TX_BUF2,(u8)CanID);
CanWriteReg(TX_BUF3,pdat[0]);
CanWriteReg(TX_BUF0,pdat[1]);
CanWriteReg(TX_BUF1,pdat[2]);
CanWriteReg(TX_BUF2,pdat[3]);
CanWriteReg(TX_BUF3,pdat[4]);
CanWriteReg(TX_BUF0,pdat[5]);
CanWriteReg(TX_BUF1,pdat[6]);
CanWriteReg(TX_BUF2,pdat[7]);
CanWriteReg(TX_BUF3,0x00);
CanWriteReg(CMR ,0x04); //发起一次帧传输
}
//========================================================================
// 函数: void CANSetBaudrate()
// 描述: CAN总线波特率设置函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-19
// 备注:
//========================================================================
void CANSetBaudrate()
{
CanWriteReg(BTR0,(SJW << 6) + BRP);
CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
}
//========================================================================
// 函数: void CANInit()
// 描述: CAN初始化函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-19
// 备注:
//========================================================================
void CANInit()
{
CANEN = 1; //CAN1模块使能
CANSEL = 0; //选择CAN1模块
P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.1 0x10:P5.0,P5.1 0x20:P4.2,P4.5 0x30:P7.0,P7.1
// CAN2EN = 1; //CAN2模块使能
// CANSEL = 1; //选择CAN2模块
// P_SW3 = (P_SW3 & ~(3)) | (0); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.2,P0.3 0x01:P5.2,P5.3 0x02:P4.6,P4.7 0x03:P7.2,P7.3
CanWriteReg(MR ,0x04); //使能 Reset Mode
CANSetBaudrate(); //设置波特率
//使用单滤波过滤器,只接收 ID=0x0067 的报文 0000 1100 1110
/* CanWriteReg(ACR0,0x0C); //总线验收代码寄存器
CanWriteReg(ACR1,0xE0);
CanWriteReg(ACR2,0x00);
CanWriteReg(ACR3,0x00);
CanWriteReg(AMR0,0x00); //总线验收屏蔽寄存器
CanWriteReg(AMR1,0x0F);
CanWriteReg(AMR2,0xFF);
CanWriteReg(AMR3,0xFF);
*/
CanWriteReg(ACR0,0x00); //总线验收代码寄存器
CanWriteReg(ACR1,0x00);
CanWriteReg(ACR2,0x00);
CanWriteReg(ACR3,0x00);
CanWriteReg(AMR0,0xFF); //总线验收屏蔽寄存器
CanWriteReg(AMR1,0xFF);
CanWriteReg(AMR2,0xFF);
CanWriteReg(AMR3,0xFF);
CanWriteReg(IMR ,0xff); //中断寄存器
CanWriteReg(ISR ,0xff); //清中断标志
CanWriteReg(MR ,0x01); //退出 Reset Mode, 采用单滤波设置(设置过滤器后注意选择滤波模式)
CANICR = 0x02; //CAN中断使能
}
//========================================================================
// 函数: void CANBUS_Interrupt(void) interrupt CAN_VECTOR
// 描述: CAN总线中断函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2020-11-19
// 备注:
//========================================================================
void CANBUS_Interrupt(void) interrupt CAN1_VECTOR
{
u8 isr;
u8 arTemp;
arTemp = CANAR; //CANAR现场保存,避免主循环里写完 CANAR 后产生中断,在中断里修改了 CANAR 内容
isr = CanReadReg(ISR);
if((isr & 0x04) == 0x04) //TI
{
CANAR = ISR;
CANDR |= 0x04; //CLR FLAG
}
if((isr & 0x08) == 0x08) //RI
{
CANAR = ISR;
CANDR |= 0x08; //CLR FLAG
//
B_CanRead = 1;
}
if((isr & 0x40) == 0x40) //ALI
{
CANAR = ISR;
CANDR |= 0x40; //CLR FLAG
}
if((isr & 0x20) == 0x20) //EWI
{
CANAR = ISR;
CANDR |= 0x20; //CLR FLAG
}
if((isr & 0x10) == 0x10) //EPI
{
CANAR = ISR;
CANDR |= 0x10; //CLR FLAG
}
if((isr & 0x02) == 0x02) //BEI
{
CANAR = ISR;
CANDR |= 0x02; //CLR FLAG
}
if((isr & 0x01) == 0x01) //DOI
{
CANAR = ISR;
CANDR |= 0x01; //CLR FLAG
}
CANAR = arTemp; //CANAR现场恢复
}
|
|