相关文章
学习CAN协议(二):使用CAN发送数据
学习CAN协议(三):使用CAN接收数据
目录
本文主要讲述如何使用STM32 CubeMX配置和使用CAN发送一包数据。
示例芯片:STM32F103C8T6
所用库:HAL库
一、配置CubeMX
1、配置RCC的HSE为外部时钟。
2、配置时钟树,PCLK1是CAN口使用的时钟频率。
3、开启CAN通信,我这里使用的波特率为500KHZ,波特率=PCLK1/Prescaler/(time1+time2+1)
在这里为16MHZ/8=2MHZ 2MHZ/(1+2+1)=500KHZ
4、生成工程文件
二、代码编写
1、启动CAN通信。
HAL_CAN_Start(CAN_HandleTypeDef *hcan)
需要一个参数,这个参数为CAN通信的句柄,可以追进 MX_CAN_Init 函数中找到
这可看见句柄为 hcan (有的单片机有两组CAN口,所以可能分 hcan1 和 hcan2 ),因为参数是指针类型,所以使用时要加 取地址符 &
HAL_CAN_Start(&hcan);
2、编写一个CAN发送函数
2.1 CAN的发送函数
追进 HAL_CAN_Start 函数,往上划一下可以看到一块注释,里面详细说明了CAN通信的控制函数。
HAL_CAN_Start :启动CAN模块
HAL_CAN_Stop :停止CAN模块
HAL_CAN_RequestSleep:进入休眠模式
HAL_CAN_WakeUp:从休眠模式中唤醒
HAL_CAN_IsSleepActive :检查睡眠模式是否激活
HAL_CAN_AddTxMessage :向Tx邮箱添加消息,并激活相应的传输请求
HAL_CAN_AbortTxRequest :中止传输请求
HAL_CAN_GetTxMailboxesFreeLevel:返回发送数据数量
HAL_CAN_IsTxMessagePending:检查是否有传输请求,在选定的Tx邮箱上挂起
HAL_CAN_GetRxMessage :获取CAN消息
HAL_CAN_GetRxFifoFillLevel :返回接收数据数量
由此可以找到 HAL_CAN_AddTxMessage 是发送数据的函数
HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan,
const CAN_TxHeaderTypeDef *pHeader,const uint8_t aData[], uint32_t *pTxMailbox)
第一个参数是句柄,
第二个参数为一个 CAN_TxHeaderTypeDef 结构体类型的消息头部,
第三个参数的要发送的数据,
第四个参数为返回值,返回一个发送的邮箱号
2.2 编写消息头部
因为第二个参数为一个 CAN_TxHeaderTypeDef 结构体类型的消息头部,因此我们要先定义一个这个结构体类型的变量,并进行初始化。
先找到这个结构体
通过追源码找个这个结构体,结构体里面有六个成员:
StdId:表示标准ID,范围为 0~0x7FF;
ExtId:表示扩展ID,范围为 0~0x1FFFFFFF;
IDE:表示传输的消息类型,CAN_ID_STD 表示传输消息为标准帧 CAN_ID_EXT 表示传输消息为扩展帧。
RTR:用来表示区分普通消息和控制命令,CAN_RTR_DATA 表示消息为数据,CAN_RTR_REMOTE 表示消息为控制信号
DLC:表示消息长度,大小为0~8个字节。
TransmitGlobalTime:是否添加时间戳, 启用:ENABLE 禁用:DISABLE
知道了这些信息,我们就可以自己写一个CAN的发送函数了
CAN的发送示例代码
uint32_t mail=0;
void CAN_SEND(uint8_t *buf,int len)
{
if(len>8) //发送字节数不能超过8字节
len=8;
CAN_TxHeaderTypeDef txHead;
txHead.ExtId=0x1234578; // 设置扩展ID
txHead.IDE=CAN_ID_EXT;
txHead.RTR=CAN_RTR_DATA; // 表示发送的为数据
txHead.DLC=len; //发送数据的长度
txHead.TransmitGlobalTime=DISABLE;
HAL_CAN_AddTxMessage(&hcan,&txHead,buf,&mail);
}
如果要使用,我们直接调用这个接口就可以
CAN_SEND("hello",5); //发送一个 hello ,长度5字节
实机演示
可以看一下这位up主的视频