前几篇有介绍过CANBus~透过MCP2515模块去完成通讯。
这篇会使用STM32当中的CAN-Bus来实现通讯~
与之前介绍Can不同的是在STM32当中将一个bit分为3个区段而已,将传播段与相位缓冲段1结合。
可以看到在STM32当中将Bit仅分为3个区段,而同步区段固定为1Tq ; BS1为0-16TQ ;BS2为0-8TQ,采样点同样落在BS1与BS2交界。
TQ = (BRP+1) x Tpclk
TQ= (15+1) x (1/16) = 0.9375(us) = 937.5(ns)
BPR : 预分频系数 Tpclk : APB Clock 周期
这时可以知道1个TQ为937.5ns,同时SyncSeg固定为1TQ 後续BS1为4TQ BS2为3TQ:
Bit Timing : TQ timing x (1+BS1+BS2)
937.5ns x 8 = 7500ns
TQ Timing : 上方计算出来1 TQ的时间
BS1 : BS1 的TQ数量 BS2 : BS2的TQ数量
Baud Rate = 1 / Bit Timing
1 / 7500ns x 1000000000 = 133333 bit/s
1000000000是因为ns换为s
(SyncSeg + BS1 )/ 总TQ数量 *100%
以上方来说即为 5 / 8 x 100% = 62.5%
采样点在通讯过程最好是落在60~70%,所以在选择TQ数量时要注意采样点位置!
FIFO (First In First Out) : 先进先出,在RX Buffer当中可以储存3笔资料,会按照接收到的讯息顺序,读取最先接收到的讯息。
换个方式说假如今天邮差送了一封信到信箱当中而且信箱大小只能容纳3封,那这封信就会变成编号1的信件(CAN_RFR→FMP = 0b01),这时候可以选择去收信或是晚点收。
马上收信 : 从信箱当中拿走信(CAN_RFR→RFOM = 1),信箱当中是空的了,这时候信箱会将编号归0,可以重复这个步骤接收下一封信件。
晚点收信 : 信箱中还是有着一封信,假设又收到一封信但由於刚刚没有取走第一封,这时候就会改为编号2的信件(CAN_RFR→FMP = 0b10),当累积到第三封信件时(CAN_RFR→FMP = 0b11)信箱已经满了,所以当第四封信件就会放置在信箱外面(溢出)。
针对信箱满了的情况下可以分为两种处理方法:
在STM32当中CAN具有4个向量中断 :
我使用的板子是L476RG,只具备一个CAN通讯(CAN1)。
Prescaler : 等於上方计算公式的BPR,影响的是TQ的时间。
这边我APB Clock为16 ,Prescaler 设为15
(15+1) x (1/16) = 0.9375(us) = 937.5(ns)
Time Quanta Bit Segment 1 : 传播段与相位缓冲段1结合,会影响到采样点的位置
Time Quanta Bit Segment 2 : 相位缓冲段2,会影响到采样点的位置
以上我设置为4TQ与3TQ,而同步段固定为1TQ共8TQ,所以看以看到下方Time for One Bit 为7500ns (937.5ns x 8 = 7500ns)
Baud Rate : 1 / 7500ns x 1000000000 = 133333 bit/s
ReSynchronization Jump Width : 重新同步跳转宽度,用来弥补两设备间的通讯误差,可设置范围0-4TQ。
上方图为基本模式设定,这边就都选Disable即可。
而最後的是工作模式选择 : 分为正常模式、环回模式、静默模式等等,因为我手边只有一块就先选环回模式来测试。
四个中断向量则是上方说明的四个,根据需要可以开启对应的中断。
HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo)
void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
__weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
__weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
__weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(&hcan1,CAN_FILTER_FIFO0,&rxheader1,msg);
}
}
__weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hcan);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_CAN_RxFifo0FullCallback could be implemented in the user
file
*/
}
__weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(&hcan1,CAN_FILTER_FIFO0,&rxheader1,msg);
}
}
__weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hcan);
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_CAN_RxFifo0FullCallback could be implemented in the user
file
*/
}
<<: [前端/JavaScript] 实作汇出excel下载按钮的超好用套件:ExcelJS(下)- 用React汇出excel (export excel)
今年参赛的另一个主题,也请大家多多支持,感恩~ https://ithelp.ithome.com...
表格 (table) 表格是一个由列和栏组成的结构化资料(tabular data)。表格能帮助你快...
「然而,没有测试套件,他们就丧失确保『程序修改後是否仍能照预期般工作』的能力,他们没办法保证『对系...
前情提要 除结尾倒数两篇 (゚∀゚) 来看看能不能在今天一次性写完w 现在时间 10/11 aka....
新建一个.net core mvc专案後 预设每一个检视之所以都能套用版面配置页 主要是在於藉由.\...