can的基础知识点:
1:两个以上的单元同时开始发送消息时,根据标识符 ID 决定优先级。ID 表示访问总线的消息的优先级。
理解:CAN 的数据帧里有一个 ID。在 CAN 里,ID 越小,优先级越高。例如,ID 为 0x01 的消息优先级高于 ID 为 0x10 的消息。ID 不仅用来表示优先级,在实际应用中通常用来表示"这条消息包含什么内容"(比如是发动机转速,还是车门状态)。
2:两个以上的单元同时开始发送消息时,对各消息 ID 的每个位进行逐个仲裁比较。仲裁获胜...继续发送,仲裁失利...立刻停止并接收。
理解:这叫做线与机制。在物理电平上,逻辑 0 是显性电平,逻辑 1 是隐性电平。显性电平可以覆盖隐性电平。一边发送,一边回读。发送隐性电平(1)却读回显性电平(0)的节点,就知道自己输了(失去仲裁),立刻转为接收模式。
3:数据帧 :用于发送节点向接收节点传输实际的数据。在 RT-Thread 中,你配置 rt_can_msg 结构体,填入 id、设置 rtr = RT_CAN_DTR(表示数据帧),并填入你的业务数据(比如温度传感器的值),然后发送。
遥控帧:遥控帧没有数据段。它的结构和数据帧很像,但它的 RTR(远程传输请求)位是隐性电平(1)。当某个节点收到与自己 ID 匹配的遥控帧时,它应该立刻回复一个包含实际数据的数据帧。
错误帧:用于在接收或发送消息时检测出错误,并通知总线上的所有其他节点。CAN 总线有极其严格的自我诊断机制(CRC 校验、位填充检查等)。任何一个节点一旦发现总线上的信号不符合规则,就会立刻发送一串连续的"破坏性"电平(6个显性位)。这会主动破坏当前正在传输的帧,迫使所有节点丢弃这个坏消息。
STM32 内部的 CAN 控制器硬件会自动检测错误并发送错误帧。你需要做的只是在 RT-Thread 中检查错误中断或错误计数器,看看总线是不是物理上出问题了(比如线缆短路、干扰太大)。
过载帧:格式和错误帧非常相似,但它是在帧间隔期间发送的,用来强行延长两帧之间的等待时间。
帧间隔:它是由连续的 3 个隐性位(逻辑 1)组成的。无论是谁刚发完一帧,都必须等待这 3 个位的时间过去,总线才算真正进入"空闲"状态,大家才能开始新一轮的抢夺(仲裁)。如果此时硬件还在处理上一帧的收尾工作,就会用到前面提到的"过载帧"来延长这个间隔。
stm32中纯硬件行为,STM32 会严格遵守这个规则,确保总线节奏有条不紊。你不需要、也无法用代码去干预帧间隔。
4:接收中断与发送中断
接收中断:目的是收,总线信号进入stm32,经过硬件滤波后,存入FIFO中,这时候fifo非空,产生rx中断信号,进入isr中断服务函数,在中断里读取fifo的数据,可以通过释放信号量,来唤醒接收线程
发送中断:目的是发,软件把第一帧信息放入空闲的硬件邮箱,触发硬件发送,发送成功后,邮箱变成空闲,产生tx中断,在中断函数里:从软件的发送队列中提取下一帧信息,放入空邮箱,再次请求发送。