接收程序:
void CanReadFifo(CAN_DataDef *CAN)
{
u8 i;
u8 pdat;
u8 RX_Index=0;
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
if(pdat & 0x80)//判断是标准帧还是扩展帧
{
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //扩展帧ID占4个字节
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
CAN->ID = (((u32)pdat << 24) + ((u32)pdat << 16) + ((u32)pdat << 8) + pdat) >> 3;
}
else
{
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //标准帧ID占2个字节
pdat = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));
CAN->ID = ((pdat << 8) + pdat) >> 5;
}
CAN->FF = pdat >> 7; //帧格式
CAN->RTR = pdat >> 6; //帧类型
CAN->DLC = pdat; //数据长度
for(i=0;((i<CAN->DLC) && (i<8));i++) //读取数据长度为len,最多不超过8
{
CAN->DataBuffer = CanReadReg((u8)(RX_BUF0 + (RX_Index++&3))); //读取有效数据
}
while(RX_Index&3) //判断已读数据长度是否4的整数倍
{
CanReadReg((u8)(RX_BUF0 + (RX_Index++&3)));//读取填充数据,一帧数据占据4的整数倍缓冲区空间,不足补0
}
}
初始化设置:
void CANSetBaudrate()
{
//CanWriteReg(BTR0,(SJW << 6) + BRP);
//CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
CanWriteReg(MR, 0x04); //使能Reset模式
CanWriteReg(BTR0, 0x2f); //SJW(0), BRP(47)
CanWriteReg(BTR1, 0xff); //SAM(0), TSG2(7), TSG1(15)
CanWriteReg(MR, 0x00); //退出Reset模式
}
void CANInit()
{
CANEN = 1; //CAN1模块使能
CanWriteReg(MR,0x05);//使能 Reset Mode, 采用单滤波设置
CANSetBaudrate(); //设置波特率
//设置过滤ID为:xxF8xxxx 的帧才接收
// CanWriteReg(ACR0,0x07); //总线验收代码寄存器
// CanWriteReg(ACR1,0xc0);
// CanWriteReg(ACR2,0x00);
// CanWriteReg(ACR3,0x00);
// CanWriteReg(AMR0,0xF8); //总线验收屏蔽寄存器
// CanWriteReg(AMR1,0x07);
// CanWriteReg(AMR2,0xFF);
// CanWriteReg(AMR3,0xFF);
//取消过滤ID,所有帧都接收
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, 采用单滤波设置(设置过滤器后注意选择滤波模式)
//CanWriteReg(MR,0x00); //退出 Reset Mode, 采用双滤波设置(设置过滤器后注意选择滤波模式)
//P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.10x10:P5.0,P5.10x20:P4.2,P4.50x30:P7.0,P7.1
P_SW1 &= 0xcf;
P_SW1 |= 0x00;
CANICR = 0x02; //CAN中断使能
} 就屏蔽了这句//P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4); //端口切换(CAN_Rx,CAN_Tx) 0x00:P0.0,P0.10x10:P5.0,P5.10x20:P4.2,P4.50x30:P7.0,P7.1
换成了P_SW1 &= 0xcf;
P_SW1 |= 0x00; 我找问题的时候,发现ID影响到了n(返回帧个数),CanReadMsg这个程序就跑飞了一样
u8 CanReadMsg(CAN_DataDef *CAN)
{
u8 i;
do{
CanReadFifo(&CAN);//读取接收缓冲区数据
i = CanReadReg(SR);
}while(i&0x80); //判断接收缓冲区里是否还有数据,有的话继续读取
return n; //返回帧个数
} 例程STC32G-DEMO-CODE里的50-CAN总线扩展帧收发测试程序是将收到的报文通过CAN总线原样返回。
如果你是两个产品进行通信的话,建议用屠龙刀例程包里面的例子测试:14-CAN1-CAN2总线标准帧扩展帧同时使用收发测试
这个例子将收到的报文通过串口打印出来,这样通过串口打印信息就能判断是否收到对应ID的数据。
屠龙刀例程包下载地址:https://www.stcai.com/hxgnsyb
好的,谢谢啦,我试试 屠龙刀里的子程序和我用的例程是一样的,没有区别。你那边改ID后不影响收数据吗? 会不会是帧ID数据类型出问题? 我用例程试了也是同样的问题,我只是把例程的波特率改成了10K,我把例程传上来,您跑一下看看 您说的帧ID数据类型是啥意思?
页:
1
[2]