CAN通信笔记--fork调试:set follow-fork-mode [parent|child]

,时序

帧起始有1 位,标识一个数据帧的开始,且一定是显性,即0

帧结尾由7 位隐性状态构成,表示一个数据帧结束
帧起始位后是11bit 的仲裁域,即标识符,CAN 总线就是利用这个域来做仲裁的,ID
号越低优先级越高。对于扩展帧,这个域是29 位的。
接下来的一个bit 称为 RTR,即远程发送请求位。如果这个帧是 数据帧,则该位为0,
如果是 远程帧,则为1
接下来6 个bit,称为控制域。分别是 1 位的IDE(标识符扩展),一位的 保留位(置0),
以及 4 位的DLC(数据长度
IDE=0 表示这个标准帧;IDE=1 表示是扩展帧
DLC 表示数据帧的字节数,取值(0~8),它指的不是整个帧的长度,而是后面那个数
据域(Data Field)的长度
控制域后面就是 0-8 个字节的数据域,这才是真正要发送的数据。
再后面是 CRC 域,即对前面数据的校验,这样接收方可以判断传输过程中是否出错。
这部分 15 位,在之后有一个一bit 的CRC 界定符,总是1,这个目的就是标识CRC 域
的结束。
在这之后就是 2bit 的应答域(有的书上称为应答场),第 一个bit 是ACK, 第2 个bit
则是界 定符(始终是1)。在发送时, 发送节点将这个ACK bit 设为1(隐性), 接收节
点在正确接收到报文后,将这个bit 设为0(显性
),这样发送节点会回读到这个0,它
就知道该帧被正确接收了,否则,就表示没有被正确接收。
最后是 连续7 个隐性位(即连续7 个1)表示帧结束(EOF)。节点如果 检测到总线上连

续11 个1,就表示总线现在处于空闲状态。

CANCTL0 寄存器 RXACT=0:处于发送或空闲 RXACT=1:正在接收数据

CANCTL1 CANE 使能位  LOOPB=1:模式使能    LISTEN=0:正常模式

BORM=0:配置为自动bus off 恢复模式  

CANRFLG RSTAT[1:0]  00 接收器状态  <=96 OK      01:RxWRN <=127  

10:RxERR  <=255      11:Bus off

TSTAT[1:0]  同上

RXF=1:在RxFG 接收缓冲区里接收到新的报文

CANRIER  OVERIE  RXFIE  中断使能

CANTFLG  TXE[2:0]  TXEx=1,则表示该缓冲区是空

CANTIER  TXEIE[2:0] 发送缓冲区空中断使能位

CANTARQ  ABTRQ[2:0] 取消发送过程请求

CANTBSEL  TX[2:0] 发送缓冲区选择位 有多个设置为1,则只有最低bit 有效

缓冲区选择过程:首先读CANTFLG,把读到的值写入CANTBSEL
再读出CANTBSEL,读出来的值中最低的那个为1 的位就是选中的缓冲区

CANIDAC 接收模式设置(ID过滤)

CANMISC 用户清除BOHOLD,则就发出了请求MSCAN 从bus off 状态恢复

CANIDAR0~7 寄存器 接收(或者说是过滤)规则(与CANIDMR0~7 一起)。MSCAN每接收到一个报文(帧),
就会将其中的ID 标识符与CANIDAR0~7 寄存器的值比较(当然具体如何比较还取决于CANIDMR0~7),8 个寄存器被分成两组,

第一组(first bank)由CANIDAR0~3
组成,第2 组(second bank)由CANIDAR4~7 组成。对于扩展帧,由于有29bit 的标识符,
需要每组中的4 个寄存器一起参与比对,而对于标准帧,则只需要头两个(CANIDAR0~1),

CANIDMR0~7 寄存器  某个位设置为1,则在比对的时候该位就忽略(即”don’t care”)

标识符寄存器IDR0~3 

标识符过滤 如果作为32 位模式,则MSCAN 将有两个过滤器,每个32 位。这种模式下,如果是
扩展帧,那么29 位标识符+RTR+SRR+IDE=32 位。首先这32 位与CANIDMR0~3 的mask
掩码进行处理,即看哪些位是don’t care 的

16 位模式
此种模式下,MSCAN 实现了4 个16 位的过滤器。对于扩展帧,29 位标识符的高14
位+SRR+IDE=16 位,与CANIDMR0~1 和CANIDAR0~1 进行与上述32 位模式相同的比对
过程,如果匹配称为命中0;如果不匹配,则继续与CANIDMR2~3 和CANIDAR2~3 比对,
如果匹配称为命中1;

void mscan_init()
{
unsigned char sjw,brp;
unsigned char tseg1,tseg2;
if(!CANCTL0&0x01)
CANCTL0_INITRQ=1;/* Active MSCAN initialization mode*/
while(!CANCTL1_INITAK) ;/*Wait until the MSCAN is in initialization mode*/
sjw=(SJW-1)<<6;
brp=(BRP-1);
CANBTR0=(unsigned char)(sjw|brp);/* Configures SJW and Tq clock Baud Rate Prescaler*/

tseg1=(TSEG1-1);
tseg2=(TSEG2-1)<<4;
CANBTR1=(unsigned char)(tseg1|tseg2);/* Configure Time Segment 1 and 2, and one Sample
per bit*/
/*Not mask all identifier*/
CANIDMR0=0xFF;
CANIDMR1=0XFF;
CANIDMR2=0XFF;
CANIDMR3=0XFF;
CANIDMR4=0XFF;
CANIDMR5=0XFF;
CANIDMR6=0XFF;
CANIDMR7=0XFF;
CANCTL1=0x80;/* Enable MSCAN and normal operation and select the oscillator clock as
MSCAN clock source*/
CANCTL0=0x00;/* Active MSCAN Normal Operation*/
while(CANCTL1_INITAK) ;/*Wait until the MSCAN operates normally*/
while(!CANCTL0_SYNCH) ;/*Wait until MSCAN is synchronized to the CAN bus*/
#if RECV_INTERRUPT
CANRIER_RXFIE = 1; /* Enable Full Receive Buffer interrupt */
#endif
#if TRAN_INTERRUPT
CANTIER=0x07; /* Enable transmit buffer empty interrupt */
#endif
}

unsigned char mscan_send_msg(struct mscan_msg msg)
{
unsigned char txbuf_num,i;
if(msg.len>MAX_LEN)/* Checks len validity*/
return (FALSE) ;
if(!CANCTL0_SYNCH)/*Checks synchronization to CAN bus*/
return (FALSE);
txbuf_num=0;
do{
CANTBSEL=CANTFLG; /* Looks for a free buffer*/
txbuf_num=CANTBSEL;
} while(!txbuf_num);
CANTIDR0=(unsigned char)(msg.id>>3);/*Write Identifier ,standard identifier*/
CANTIDR1=(unsigned char)(msg.id<<5);
if(msg.RTR)
CANTIDR1|=0X10;
for(i=0;i<msg.len;i++)
{
*((&CANTDSR0)+i)=msg.data[i]; /* Write Data Segment*/
}
CANTDLR=msg.len;/* Write Data Length*/
CANTTBPR=msg.prty;/* Write Priority */
CANTFLG=txbuf_num;/* Clear TXE Flag (buffer ready to transmission)*/
return (TRUE);
}

struct mscan_msg
{
unsigned int id;
unsigned char RTR;
unsigned char data[8];
unsigned char len;
unsigned char prty;
};
 接收一个数据帧
/*
**功能:MSCAN 接收message
**入口参数:结构体msg
**return:0:接收失败
** 1:接收成功
*/
unsigned char mscan_get_msg(struct mscan_msg *msg)
{
unsigned char i;
if(!CANRFLG_RXF)/* Checks for received messages*/
return (FALSE);
if(CANRIDR1_IDE)/* Checks if message has standard identifier*/
return (FALSE);
msg->id=(unsigned int)((CANRIDR0<<3)|(CANRIDR1>>5));/*Read id message */
if(CANRIDR1&0x10)
msg->RTR=1;
else
msg->RTR=0;
msg->len=CANRDLR;/*Read data length*/
for(i=0;i<msg->len;i++)
{
msg->data[i]=*((&CANRDSR0)+i);/*Read data segment */
}
CANRFLG_RXF=1;/* Clear RXF flag (buffer ready to be read)*/
return (TRUE);

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值