CAN

来源:互联网 发布:价格表设计软件 编辑:程序博客网 时间:2024/06/04 18:58

寄存器 

主要寄存器

控制寄存器0

CANCTL0

 

控制寄存器1

CANCTL1

 

总线计时寄存器0

CANBTR0

6-7同步跳转宽度 0-5分频器系数

总线计时寄存器1

CANBTR1

7采样数 4-6Seg2 0-3Seg1

发送器标志寄存器

CANTFLG

其中012位分别表示三个发送缓冲器的状态

发送缓冲器选择寄存器

CANTBSEL

读取此寄存器时有逻辑规律

接收器标志寄存器

CANRFLG

其中0位上0表示RxFG中无报文1表示RxFG有报文

标识符验收控制寄存器

CANIDAC

设置标识符的接收模式和标识符接收有效标志

标识符接收寄存器0-3

CANIDAR0-3

接收的报文写入后台接收缓冲器。只有当报文通过了标识符接收寄存器和标识符掩码寄存器中的滤波,CPU读取报文,否则报文会被下一报文覆盖。

标识符掩码寄存器0-3

CANIDMR0-3

0 匹配标识符接受寄存器和报文标识寄存器中的相应位相同,只有所有为0的位都相同时,报文被接受。

1 标识符接受寄存器中对应位的状态对接受无影响

标识符接受寄存器4-7

CANIDAR4-7

 

标识符掩码寄存器4-7

CANIDMR4-7

 

标识符寄存器0

CANRIDR0

 

标识符寄存器1

CANRIDR1

 

标识符寄存器2

CANRIDR2

 

标识符寄存器3

CANRIDR3

 

数据段寄存器0-7

CANRDSR0-7

 

数据长度寄存器 

CANDLR

只有0-3位有效,数据帧的字节长度为0-8的范围

发送缓冲器优先寄存器

CANTBPR

 

时间标签寄存器

CANRTSRH

 

时间标签寄存器

CANRTSRL

 

 

标准标识符映射

IDR0

ID10

ID9

ID8

ID7

ID6

ID5

ID4

ID3

IDR1

ID2

ID1

ID0

RTR

IDE

x

x

x

IDR2

x

x

x

x

x

x

x

x

IDR3

x

x

x

x

x

x

x

x

(IDE为0,IDE的0为标准格式1为扩展格式,RTR的0为数据帧1为远程帧)

 

扩展标识符映射

IDR0

ID28

ID20

ID26

ID25

ID24

ID23

ID22

ID21

IDR1

ID20

ID14

ID18

SRR

IDE

ID17

ID16

ID15

IDR2

ID14

ID6

ID12

ID11

ID10

ID9

ID8

ID7

IDR3

ID6

ID5

ID4

ID3

ID2

ID1

ID0

RTR

(SRR和IDE都为1,IDE的0为标准格式1为扩展格式,RTR的0为数据帧1为远程帧)

SRR不论写入什么,在计算ID时都会被视为1,RTR不论写入什么,在计算ID时都会被视为0。

 

报文缓冲器结构

 

报文缓冲器结构

I

D

R

0

I

D

R

1

I

D

R

2

I

D

R

3

D

S

R

0

D

S

R

1

D

S

R

2

D

S

R

3

D

S

R

4

D

S

R

5

D

S

R

6

D

S

R

7

D

L

R

T

B

P

R

T

S

R

H

T

S

R

L

标识符寄存器   数据段寄存器   数据长度寄存器   发送缓冲器   优先寄存器   时间标签寄存器

滤波过程:

首先设置相关的寄存器:CANIDAC CANIDARx CANIDMRx

滤波器是CANIDARx和CANIDMRx的组合意义(因为CANIDMR的某一位设置了,那么CANIDAR的对应为就毫无意义了):例如

滤波器的值为0001x1001x0

那么CANIDMR0/1/2/3的设置是00001000010

CANIDAR0/1/2/3的设置是00010100100

对于报文1:00011100110和报文2:00110100110

此滤波器接收报文1而不接收报文2.

关于滤波器CANIDMR0/1/2/3和CANIDAR0/1/2/3组成一个滤波页,CANIDMR4/5/6/7和CANIDAR4/5/6/7组成一个滤波页面,每个滤波页面可建立一个(32位)两个(16位)四个(8位)滤波器。

 

发送报文

CPU首先确定可用的发送缓冲器(CANTFLG的TXEx标示来确定),然后把CANTFLG读入CANTBSEL,读取CANTBSEL时会自动从地位读出一个可用的发送缓冲器,

 *数据保存到一个发送缓冲器TXEx

 *清除TXEx标志

 *MSCAN安排报文发送

 *设置TXE标志

当设置了TXEx时会触发发送成功的中断,以使得应用软件重新安排缓冲器进行发送任务。

 

滤波器关闭时不接收任何报文。

 

 

 

 can发送数据函数示例:

 

msg_send.id = ID_TX;                        //填写报文内容
msg_send.data[0] = potentiometer_value;
msg_send.len = 1;
msg_send.prty = 0;

 

unsigned char n_tx_buf, i;

  // 检查数据长度
  if(msg.len > MAX_LEN)
    return(FALSE);

  // 检查总线时钟
  if(CANCTL0_SYNCH==0)
    return(FALSE);

  n_tx_buf = 0;
  do
  {
  // 寻找空闲的缓冲器
    CANTBSEL=CANTFLG;
    n_tx_buf=CANTBSEL;
  }while(!n_tx_buf);
 
  // 写入标识符
  CANTIDR0 = (unsigned char)(msg.id>>3);
  CANTIDR1 = (unsigned char)(msg.id<<5);


  //CANTIDR3 = (unsigned char)(msg.id& 0x000000ff);
  //CANTIDR2 = (unsigned char)((msg.id>>8) & 0x000000ff);
  //CANTIDR1 = (unsigned char)((msg.id>>16) & 0x000000ff);
  //CANTIDR0 = (unsigned char)((msg.id>>24) & 0x000000ff);
  // 写入数据
  for(i = 0; i < msg.len; i++)
    *((&CANTDSR0)+i) = msg.data[i];
   
  // 写入数据长度
  CANTDLR = msg.len;
 
  // 写入优先级
  CANTTBPR = msg.prty;
 
  // 清 TXx 标志 (缓冲器准备发送)
  CANTFLG = n_tx_buf;
 
  return(TRUE);

 

 can接收数据函数示例:

 

 Bool MSCANCheckRcvdMsg(void)
{

  // 检测接收标志位
  if(CANRFLG&0x01)
    return(TRUE);
  else return(FALSE);
}

 

 Bool MSCANGetMsg(struct can_msg *msg)

  unsigned char i;

  // 检测接收标志
  if(!(CANRFLG&0x01))
    return(FALSE);
  // 检测 CAN协议报文模式 (一般/扩展) 标识符
  if(CANRIDR1&0x08)
    // IDE = Recessive (Extended Mode)
    return(FALSE);

  // 读标识符
  msg->id = (unsigned int)(CANRIDR0<<3) |
            (unsigned char)(CANRIDR1>>5);
    
  // 读取数据长度
  msg->len = CANRDLR;
  // 读取数据
  for(i = 0; i < msg->len; i++)
    msg->data[i] = *((&CANRDSR0)+i);

  // 清 RXF 标志位 (缓冲器准备接收)
  CANRFLG = 0x01;
  return(TRUE);
}

0 0
原创粉丝点击