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

来源:互联网 发布:python开发环境下载 编辑:程序博客网 时间:2024/06/08 06:51

,时序

帧起始有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);

}

原创粉丝点击