学习完就要做笔记要总结,趁这个没有忘记,加上这几天搞模型设计搞到头晕,写一写博客吧,各路大佬将就看一下哈
1.硬件
我用的是STM32103C8T6的板子,用的是最下系统板,然后外接了一个TJA1050,害,上图
做实验的话是够用的了
2.生成工程
因为之前用原子的例程写了一个,但是对于我这种懒人来说,还是STM32CUBEMX比较方便,后期开发也容易一点,下面是生成工程的一些步骤,由于是笔记,所以写得比较详细,如果比较熟练的话就可以直接跳过生成工程这个部分。
首先是芯片的选型
然后是相应的功能配置
在这里勾选发送和接收
然后就是配置参数,
这里要选哦,至于为啥,待会再讲
然后就是RCC
以及SYS~
因为这里想要把CAN收发的数据通过串口转发出去,所以就使能一下串口,选一下异步通信以及波特率115200bit/s
然后就是配置时钟u,这里就是用外部时钟
注意看红色箭头喔,这里的时钟频率是36M喔,再回想一下刚刚上面说的为什么CAN的参数要那么配置呢?下面是某一位关于CAN的波特率的设置,可以进去看,我就不献丑了
总结下来就是:波特率=peripheral clocks/prescaler/(TQ1+TQ2+SJW)
这里就是36M/4/(9+8+1)=500kps(这个速率也是一般汽车上一般电子产品的报文传输速率,一般对实时性要求不是很高,深入的我就没研究了)
然后生成工程,刚生成的工程里面都是一些初始化,但是要实现CAN的收发功能还是需要用户自定义的,所以我们要在生成的工程里面添加收发的定义,当然,还有串口的定义
3.CAN的发送
首先我们先看stm32f1xx_hal_can.h
这里面是一些实现CAN收发功能的一些声明,这个图可能有点小,下面是程序块
/** @addtogroup CAN_Exported_Functions_Group3 Control functions
* @brief Control functions
* @{
*/
/* Control functions **********************************************************/
HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan);
HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan);
HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan);
HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan);
uint32_t HAL_CAN_IsSleepActive(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_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan);
uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes);
uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox);
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);
这个是代码块,然后主要用到里面的收发函数
打开main.c文件,在man函数里面加上以下代码块,这个是定义一个输出的数组,以及CAN报文的一些帧结构
/* USER CODE BEGIN 1 */
CAN_TxHeaderTypeDef Can_Tx;
uint8_t tdata[8] = {
0x00,0x11