本文中CAN1采用16位掩码,CAN2只能使用大于等于14的筛选器组,根据手册只能使用32位的掩码(因为大于14的筛选器没有说明)。

经测试,STM32手册中的筛选器配置图错误,库函数的命名正确。参考STM32手册中的CAN过滤器16位标识符屏蔽配置错误说明 - smilingfrog - 博客园 (cnblogs.com)

另外,2个掩码条件满足任意一个即可被读取。

CanTxMsg CAN1_Message;
CanTxMsg CAN2_Message;
CanRxMsg CAN1_RecData;
CanRxMsg CAN2_RecData;

void MyCAN_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

//----------DATA Init----------
CAN1_Message.StdId = 0xAA;
CAN1_Message.IDE = 0;
CAN1_Message.RTR = 0;

CAN2_Message.StdId = 0xBB;
CAN2_Message.IDE = 0;
CAN2_Message.RTR = 0;

//----------GPIO Init----------
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

//CAN1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource11, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12, GPIO_AF_CAN1);

//CAN2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB,GPIO_PinSource5 , GPIO_AF_CAN2);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6 , GPIO_AF_CAN2);

//----------CAN Init----------
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = ENABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = MyCAN_SJW;
CAN_InitStructure.CAN_BS1 = MyCAN_BS1;
CAN_InitStructure.CAN_BS2 = MyCAN_BS2;
CAN_InitStructure.CAN_Prescaler = MyCAN_PRE;

CAN_Init(CAN1, &CAN_InitStructure);
CAN_Init(CAN2, &CAN_InitStructure);

//----------Filter Init----------
//CAN1
CAN_FilterInitStructure.CAN_FilterNumber = 6;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdLow = 0xAA << 5;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0xAA << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFE0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFE0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

//CAN2
CAN_FilterInitStructure.CAN_FilterNumber = 14;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

//----------NVIC Init----------
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

//CAN1
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_Init(&NVIC_InitStructure);

//CAN2
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_Init(&NVIC_InitStructure);

//----------ENABLE----------
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
CAN_ITConfig(CAN2,CAN_IT_FMP0, ENABLE);
}

void CAN1_SendData(uchar* Str, uchar Len)
{
CAN1_Message.DLC = Len;
for(uchar i = 0; i < Len; i ++)
{
CAN1_Message.Data[i] = Str[i];
}
uchar MailBox = CAN_Transmit(CAN1, &CAN1_Message);
while(CAN_TransmitStatus(CAN1, MailBox) == CAN_TxStatus_Failed);
}

void CAN2_SendData(uchar* Str, uchar Len)
{
CAN2_Message.DLC = Len;
for(uchar i = 0; i < Len; i ++)
{
CAN2_Message.Data[i] = Str[i];
}
uchar MailBox = CAN_Transmit(CAN2, &CAN2_Message);
while(CAN_TransmitStatus(CAN2, MailBox) == CAN_TxStatus_Failed);
}

void CAN1_RX0_IRQHandler(void)
{
CAN_Receive(CAN1, 0, &CAN1_RecData);
}

void CAN2_RX0_IRQHandler(void)
{
CAN_Receive(CAN2, 0, &CAN2_RecData);
}

双CAN通讯模板的更多相关文章

  1. 高性能双端js模板

    高性能双端js模板(新增filter)---simplite simplite是一款js实现的模板引擎,它能够完成浏览器端js模版和node服务器端js模板的数据渲染. 渲染性能十分突出. 支持浏览器 ...

  2. TCP建立与断开连接、socket通讯模板

    在传输层,有一个重点是TCP传输时建立连接的三次"握手"和四次"挥手",因为socket工作于应用层和传输层之间,故而涉及到建立连接和关闭连接的过程,以下笔记可 ...

  3. python网络编程:TCP通讯模板、粘包及解决方案、自定义报头

    一.TCP通讯模板 二.远程CMD程序 三.解决粘包问题 四.解决粘包问题2 一.TCP通讯模板 TCP客户端 import socket c = socket.socket() # 连接服务器 c. ...

  4. Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板

    历时好几天,终于完工了! 支持无向图四种功能:1.割点的求解 2.割边的求解 3.点双连通分量的求解 4.边双连通分量的求解 全部支持重边!!!!全部支持重边!!!!全部支持重边!!!! 测试数据: ...

  5. python网络编程:socket半连接池、UDP通讯模板

    一.TCP半连接池原理 二.UDP通讯 三.UDP聊天 四.UDP聊天2 五.UDP会粘包吗 六.UDP总结 七.UDP与TCP对比 一.TCP半连接池原理 客户端 import socket cli ...

  6. 高性能双端js模板---simplite

    simplite是一款js实现的模板引擎,它能够完成浏览器端js模版和node服务器端js模板的数据渲染,渲染性能达到引擎的极限. 渲染性能十分突出. 支持浏览器端和node服务器端模板渲染. 它简单 ...

  7. hdu 3352 求边双联通分量模板题(容器)

    /*这道题是没有重边的,求加几条边构成双联通,求边联通分量,先求出桥然后缩点,成一个棵树 找叶子节点的个数*/ #include<stdio.h> #include<string.h ...

  8. poj 1523 SPF(双连通分量割点模板)

    题目链接:http://poj.org/problem?id=1523 题意:给出无向图的若干条边,求割点以及各个删掉其中一个割点后将图分为几块. 题目分析:割点用tarjan算法求出来,对于每个割点 ...

  9. (转载)GDI+双缓冲

    双缓冲在GDI+里可以有效的提高描画效率.改善显示的质量. 下面的代码是一个最简单的双缓冲的模板.可以根据需要,做简单的修改即可. Bitmap CacheImage( [Width], [Heigh ...

  10. Node.js模板引擎的深入探讨

    每次当我想用 node.js 来写一个 web 相关项目的时候.我总是会陷入无比的纠结.原因是 JavaScript 生态圈里的模板引擎实在太多了,但那么多却实在找不出一个接近完美的,所谓完美的概念就 ...

随机推荐

  1. Python arcpy创建栅格、批量拼接栅格

      本文介绍基于Python语言arcpy模块,实现栅格影像图层建立与多幅遥感影像数据批量拼接(Mosaic)的操作.   首先,相关操作所需具体代码如下: import os import arcp ...

  2. Ubuntu20.04桌面系统快速上手教程

    转载csdn:ChunKai93 https://blog.csdn.net/iamzhoujunjia/article/details/105349441

  3. aspnetcore读取配置【源码分析】

    总的逻辑 继承 IConfigurationSource 这个接口的子类是配置源 ,其中的build方法,创建并返回对应的ConfigurationProvider. 继承 IConfiguratio ...

  4. switch-声明和类型模式匹配

    1.声明和类型模式:类型为 T 的声明模式在表达式结果为非 NULL 且满足以下任一条件时与表达式匹配 var numbers = new int[] { 10, 20, 30 }; Console. ...

  5. 97、UserAgentUtils

    user-agent-utils 是一个用来解析 User-Agent 字符串的 Java 类库. 其能够识别的内容包括: 超过150种不同的浏览器: 7种不同的浏览器类型: 超过60种不同的操作系统 ...

  6. 08. AssetBundle.LoadFromFile

    参数 path 文件在磁盘上的路径. crc 未压缩内容的 CRC-32 校验和(可选).如果该参数不为零,则加载前将内容与校验和进行比较,如果不匹配则给出错误. offset 字节偏移(可选).该值 ...

  7. maven发布到本地仓库

    <distributionManagement> <repository> <id>localRepository</id> <url>fi ...

  8. 552. 学生出勤记录 II (Hard)

    问题描述 552. 学生出勤记录 II (Hard) 可以用字符串表示一个学生的出勤记录,其中的每个字符用来标记当天的出勤情况(缺勤.迟到.到场).记录中只含下面三种字符: 'A':Absent,缺勤 ...

  9. Python中的__new__()方法

    1.__new__()至少要有一个参数cls,代表当前类,此参数在实例时由python解释器自动识别, 2.__new__()必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别 ...

  10. C语言中的malloc、new、memset函数解析

    1. malloc 在window下,malloc的函数原型: extern void *malloc(unsigned int num_bytes); 头文件: #include<malloc ...