我想了解CANopen协议.
目前,我没有任何CAN硬件或CANopen堆栈可供试验.
我想知道如何编写Java程序来简单地解释在RS-232端口接收的CANopen消息.
我正在使用STM32F4Discovery工具包来构建一个简单的CAN接口.我设法配置它,所以我可以传输CAN消息,但是,我坚持接收它们.据我所知,要接收CAN消息,它必须通过验收过滤器.我想设置过滤器接受从ID 0x700到0x7FF的所有(标准,2.0A)消息.我该怎么做呢?
我已阅读参考手册,但我不知道如何实际配置过滤.
void CAN_FilterConfiguration(void) {
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN2 filter configuration */
CAN_FilterInitStructure.CAN_FilterNumber = 1; // filter number = 1 (0<=x<=13)
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; // FIFO = 0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
Run Code Online (Sandbox Code Playgroud) 我一直在摆弄几个月前购买的蓝牙 elm327 设备,并且能够获得标准的 obd 信息,如 vin、rpm、速度等。但正如我最近读到的那样,obd2 和 can 是不一样的。我尝试使用 AT MA 命令嗅探我的 CAN 总线,但没有得到任何响应,所以我猜 CAN 网络已与 obd2 接口解耦。有机会访问can网络吗?或者我可能需要不同的设备来执行此操作?也许这个信息有帮助:我有一辆 2011 款斯柯达。
我想使用我的 stm32f4 发现板制作 OBD II 读取器。我在 google 上搜索了一些文档,了解需要将哪种 CAN 帧发送到 OBD 端口以及从 OBD 端口接收到的内容。请在这方面帮助我,我不想使用像 ELM3xx 这样的 OBD-UART 转换器。给我推荐一些STM32F4平台上的库或示例。
谢谢
我有类似的问题.如何编写简单的CANopen层.我读了答案,但我必须自己编程一个CANopen层我无法获得商业广告.那么有没有写CANopen堆栈的基础知识(或者我不确定差异的层)?我甚至不知道从哪里开始..
如果需要这里有一些信息:
我的主设备是带有QNX的beagle bone black.QNX有一个通用的CAN库我认为但不是CANopen特有的.我的奴隶是一个军事化的无刷电机控制器.我正在用C++写作.我有一个关于我的系统的一般要求的文档.有2个RPDO和4个TPDO,传输是同步的,没有停止模式(因此没有心跳和节点保护)并且所有消息信息都被陈述(大小,格式,相关节点ID等)
我用 C 编写了一些代码来读取 CAN 总线数据。当我读取 11 位 CAN ID 时,一切正常。当我尝试读取 29 位 ID 时,它会错误地显示 ID。
例子:
接收带有29位ID的消息:
0x01F0A020
并打印它
printf("%X\n", frame.can_id);
Run Code Online (Sandbox Code Playgroud)
它打印81F0A020。
11位ID消息
0x7DF
并打印它
printf("%X\n", frame.can_id);
Run Code Online (Sandbox Code Playgroud)
它正确打印7DF。
为什么会这样呢?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <net/if.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#define MAX_DATA_LEN 8
#define MAX_FIELDS 23
#define MAX_FIELD_LEN 64
#include <limits.h>
char data_str[MAX_FIELDS][MAX_FIELD_LEN];
int i;
int
main(void)
{
int …Run Code Online (Sandbox Code Playgroud) 我是 CAN 协议的新手,我正在尝试通过 Linux 的 SocketCAN 使用它。然而,我对可用的 2 种不同的 CAN 套接字(RAW 和广播管理器 (BCM))感到困惑。
文档指出,BCM 套接字不适用于发送单独的 CAN 帧。直觉上我猜测 BCM 更适合单主多从配置,但这似乎有些错误。
BCM 的用途是什么?或者说,它们之间的功能有什么区别?在什么情况下我会选择使用广播管理器而不是原始套接字?
我开始在 STM32F103xx MCU 中对 CAN 外设环回模式的 HAL 驱动程序进行基本使用。根据MCU的用户手册,当传输完全完成并且数据在CAN总线上可用时,CAN_TSR寄存器的TME、RQCP和TXOK位被硬件置1,表明相应的邮箱已变空,并且传输成功。
当我调试以下程序时,CAN_TSR 寄存器中没有发生上述任何更改。我只能看到 TME 位被设置,这意味着提供了一个邮箱用于传输,但从未传输。
我的这段代码导致程序中出现不定式循环:
while(HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));
Run Code Online (Sandbox Code Playgroud)
您能解释一下我的问题是什么以及我应该做什么吗?感谢您的想法。
这是完整的代码:
#include "main.h"
CAN_HandleTypeDef hcan;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);
/* USER CODE BEGIN PFP */
void Can_TX(void);
/* USER CODE END PFP */
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
/* USER CODE BEGIN 2 …Run Code Online (Sandbox Code Playgroud) 我试图用CAN数据读取文本文件,文件格式如下:
XL_CAN_EV_TAG_RX_OK CH:0 T = 51165282304 ID:98FF5C80 DLC:7 000000040000E0 XL_CAN_EV_TAG_RX_OK CH:0 T = 51172728832 ID:98FF1480 DLC:7 FFFFFFAD7C1CFF XL_CAN_EV_TAG_RX_OK CH:0 T = 51173007360 ID:98FF1080 DLC:7 FFFFE30C0E01FF XL_CAN_EV_TAG_RX_OK CH:0 T = 51173285888 ID :98FF1180 dlc:7 FFFF9706FEFFFB XL_CAN_EV_TAG_RX_OK ch:0 t = 51173564416 id:98FF1280 dlc:7 FFFF9706FEFFFB
我必须阅读上面看到的CANid和CANDATA,我设法使用以下内容读取CANID:
unsigned int hex = 0;
fscanf(fr, "%X", &hex);
printf(" %X ", hex);
Run Code Online (Sandbox Code Playgroud)
我用c = fgetc(fr); 直到c读取第二个":"并且hex读取canid罚款.
但是,当我必须使用相同的代码"fscaf"读取数据时,它只读取最后7个数据,例如,我得到如下结果:
40000e0
D7C1CFF
C0E01FF
6FEFFFB
6FEFFFB
这就是问题.我发现的替代方案是将其作为char读取.
如果我使用getc读取,我得到char格式的数据,我不知道如何将其转换为十六进制,它也分别读取每个字母,我必须将它们组合,然后将其转换为int类型(十六进制) )具体并将其发送到一个数组,如下所示:
数据[0] = FF; 数据[1] = FF; 数据[2] = FF; 数据[3] = AD; …
我将在 linux 中使用 CANOpen。在内核中,linux 有 socketcan,我有一些问题需要进一步实现。
1-) 对象字典的样子,是头文件还是 EDS 文件?
2-) 我需要对 pdo 和 sdo 配置使用对象字典吗?
3-) 我应该实现我的自定义 canopen 库,它只实现一些协议,还是使用像 canfestival 这样实现几乎所有协议和对象字典的库?