这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » STC32G12K128单滤波模式下的CAN验收器代码位、屏蔽位的配置

共3条 1/1 1 跳转至

STC32G12K128单滤波模式下的CAN验收器代码位、屏蔽位的配置

专家
2024-02-16 14:46:59   被打赏 50 分(兑奖)     打赏

之前做的STC32G12K128的CAN测试程序中,预想要达到的测试目的是:CAN1发送数据,CAN2接收数据;CAN2发送数据,CAN1接收数据。但实际测试中,出现的结果是:CAN1发送数据,CAN1接收数据;CAN2发送数据,CAN2接收数据。在我搭配的电路如下:

1.png按照这个电路,CAN1和CAN2是使用相同的总线,因此无论是哪个CAN发送了数据,CAN1和CAN2都会收到数据。那么为了实现我的目的,就需要配置CAN,使自己的CAN发送的数据,被自己屏蔽掉,只接受自身以外的CAN发送的数据。

根据STC32G12K128的说明,需要配置验收器和屏蔽器。STC32G12K128的CAN1和CAN2都配置有属于自己的验收器(总线验收代码寄存器ACR0~ACR3)和屏蔽器(总线验收屏蔽寄存器AMR0~AMR3)。理论上,只要在初始化时配置好这两组寄存器就可以。如果使用单滤波模式,需要配置CAN 模式寄存器(MR)中的B0位AFM为1,即

CanWriteReg(MR  ,0x01); // 使用单滤波模式

按照滤波的规则,每一位验收屏蔽分别对应每一位验收代码,

1)当该位验收屏蔽位为“1”的时候(即设为无关),接收的相应帧 ID 位无论是否和相应的验收代码位相同均会表示为接收;

2)当验收屏蔽位为“0”的时候(即设为相关),只有相应的帧 ID 位和相应的验收代码位值相同的情况才会表示为接收。

3)只有在所有的位都表示为接收的时候,CAN 控制器才会接收该报文。


滤波器配置定义了一个长滤波器(4 字节、32 位),由 4 个验收码寄存器和 4 个验收屏蔽寄存器组

成的验收滤波器,滤波器字节和信息字节之间位的对应关系取决于当前接收帧格式。

接收 CAN 标准帧单滤波器配置:对于标准帧,11 位标识符、RTR 位、数据场前两个字节参与滤波;

对于参与滤波的数据,当AMR中对应的位Bx= 0时,对应的 ACR中Bx的位和参与滤波数据的对应位Bx必须相同才算验收通过;

如果由于置位 RTR=1 位而没有数据字节,或因为设置相应的数据长度代码而没有或只有一个数据字节信息,报文也会被接收。

对于一个成功接收的报文,所有单个位在滤波器中的比较结果都必须为“接受”; 

注意 AMR1 和 ACR1 的低四位是不用的,为了和将来的产品兼容,这些位可通过设置 AMR1.3、AMR1.2、AMR1.1 和 AMR1.0 为 1 而定为“不影响”。


所以单滤波模式下,只需要针对扩展帧中的报文识别码来配置就行,不需要数据位的参与。

2.png


程序中,CAN的ID配置为,

CAN1_ID = 0x01303132;

CAN2_ID = 0x03333435;


根据滤波规则,当AMR中对应的位Bx= 0时,对应的 ACR中Bx的位和参与滤波数据的对应位Bx必须相同才算验收通过;

那么对于CAN1,为了能只让CAN2 的数据被接收,因此配置成:验收代码位与CAN2的ID一致的数据,表示只接受CAN2发送的数据;验收屏蔽位全部设成0,表示直接和验收收代位一致的ID(即CAN2的ID)发送的数据。

同样,需要配置CAN2的验收代码位为CAN1对应的ID,验收屏蔽位全部设成0。

改变CAN1和CAN2的初始化部分程序,

    // 总线验收代码寄存器

    // CAN1_ID = 0x01303132;

    // CAN2_ID = 0x03333435;

    // 对CAN1,ACR配置成CAN2的ID

CAN_InitStructure.CAN_ACR0    = 0x03;     //总线验收代码寄存器 0~0xFF

    // 总线验收代码寄存器

CAN_InitStructure.CAN_ACR1    = 0x33;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR2    = 0x34;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR3    = 0x35;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR0    = 0x00;     //总线验收屏蔽寄存器 0~0xFF

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR1    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR2    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR3    = 0x00;

    

    CAN_Inilize(CAN1,&CAN_InitStructure);     //CAN1 初始化

    

    

    // 总线验收代码寄存器

    // CAN1_ID = 0x01303132;

    // CAN2_ID = 0x03333435;

    // 对CAN2,ACR配置成CAN1的ID

CAN_InitStructure.CAN_ACR0    = 0x01;     //总线验收代码寄存器 0~0xFF

    // 总线验收代码寄存器

CAN_InitStructure.CAN_ACR1    = 0x30;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR2    = 0x31;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR3    = 0x32;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR0    = 0x00;     //总线验收屏蔽寄存器 0~0xFF

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR1    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR2    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR3    = 0x00;

    

CAN_Inilize(CAN2,&CAN_InitStructure);     //CAN2 初始化

编译、下载、运行,结果显示,接收处理部分没有收到数据。OLED上的显示只有发送部分的数据,至少说明屏蔽起作用了。

3.png

问题出在哪里呢?难道是ID配置错了?根据手册


难道是ID的位顺序不对?ID只使用29位,从B0开始到B28。这个ID.后面跟着的顺序号和B的位顺序号是一致的,还是正好相反的?


为了验证,只对CAN1做验证、屏蔽处理,CAN2可以接受任意数据,并把发送方的ID显示出来。

    // 总线验收代码寄存器

    // CAN1_ID = 0x01303132;

    // CAN2_ID = 0x03333435;

    // 对CAN1,ACR配置成CAN2的ID

CAN_InitStructure.CAN_ACR0    = 0x03;     //总线验收代码寄存器 0~0xFF

    // 总线验收代码寄存器

CAN_InitStructure.CAN_ACR1    = 0x33;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR2    = 0x34;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR3    = 0x35;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR0    = 0x00;     //总线验收屏蔽寄存器 0~0xFF

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR1    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR2    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR3    = 0x00;

    

    CAN_Inilize(CAN1,&CAN_InitStructure);     //CAN1 初始化

    

    

    // 总线验收代码寄存器

    // CAN1_ID = 0x01303132;

    // CAN2_ID = 0x03333435;

    // 对CAN2,ACR配置成CAN1的ID

CAN_InitStructure.CAN_ACR0    = 0x00;     //总线验收代码寄存器 0~0xFF

    // 总线验收代码寄存器

CAN_InitStructure.CAN_ACR1    = 0x00;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR2    = 0x00;

// 总线验收代码寄存器

    CAN_InitStructure.CAN_ACR3    = 0x00;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR0    = 0xFF;     //总线验收屏蔽寄存器 0~0xFF

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR1    = 0xFF;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR2    = 0xFF;

// 总线验收屏蔽寄存器

    CAN_InitStructure.CAN_AMR3    = 0xFF;

    

CAN_Inilize(CAN2,&CAN_InitStructure);     //CAN2 初始化

结果依然不对。上次发的测试的那个,CAN2发送,CAN2是可以接收自己的。现在依然没有接收。

问题出在哪里呢?





关键词: 菜鸟学单片机          STC32G12K128     CAN收    

工程师
2024-02-28 11:40:18     打赏
2楼

学习了


院士
2024-04-08 16:31:37     打赏
3楼

谢谢分享。


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]