CAN与上位机通信详细教程
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
本文使用32版HAL库与上位机进行通信,使用按键按一次则发送一次数据给上位机,上位机发送一次数据给32板则使用串口打印出来
文章目录
- CAN与上位机通信详细教程
- 一、HAL库配置
- 二、CAN—发送内容
- 1.定义发送结构体
- 2.定义发送函数(记得在can.h头文件也定义一下、在CAN.c里面)
- 3.man函数设置一下
- 二、CAN—接收函数
- 1.定义接收滤波(在can.c里面)
- 2.设置中断函数(写在main.c的int main前面)
- 3.main函数中配置
- 实现结果
提示:本文借鉴多个博文大佬的参考 1.对于can
过滤器配置请大家参考这位博主的,写的非常通俗易懂。
2.对于CSDN上很多作者的通信都是32发一个数据,则上位机把这个数据传输并打印出来,对于我做的一个项目感觉不太相似,就直接捣鼓出来发送、接收数据不一样的形式。好了,下面开始正文。
一、HAL库配置
1.我使用的是正点原子精英板(板子不一样也没关系)原理图
2.开始CubeMX配置
1.GPIO(按键和LED的配置)
2.RCC配置
3.can配置
波特率:36MHZ/(9+5+2)=500
配置中断:
3.串口
二、CAN—发送内容
1.定义发送结构体
2.定义发送函数(记得在can.h头文件也定义一下、在CAN.c里面)
CAN_TxHeaderTypeDef CAN_TX;
void CAN_Send(void)
{
uint32_t TxMailbox;
uint8_t Tdata[8]={0x00,0x04,0x93,0xE0,0x00,0x00,0x27,0x10};
CAN_TX.StdId=0x123;
CAN_TX.ExtId=0x028900F0;
CAN_TX.IDE=CAN_ID_EXT;
CAN_TX.RTR=CAN_RTR_DATA;
CAN_TX.TransmitGlobalTime=DISABLE;
CAN_TX.DLC=8;
if(HAL_CAN_AddTxMessage(&hcan,&CAN_TX,Tdata,&TxMailbox)!=HAL_OK)
{
Error_Handler();
}
}
3.man函数设置一下
下面代码放在main.c文件的while(1)里面
/* USER CODE END WHILE */
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)//当按键按下
{
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
{
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,0);//LED灯亮
CAN_Send();//数据发送
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,1);//LED灯灭
HAL_Delay(500);
}
}
二、CAN—接收函数
1.定义接收滤波(在can.c里面)
void CAN_Filter_Config(void)
{
uint32_t EXRID=0x029BF03F;
CAN_FilterTypeDef CAN_FilterInitStructure;
CAN_FilterInitStructure.FilterBank=0;//使用那个筛选器
CAN_FilterInitStructure.FilterMode=CAN_FILTERMODE_IDMASK;//设置掩码模式
CAN_FilterInitStructure.FilterScale=CAN_FILTERSCALE_32BIT;//筛选器32位宽
CAN_FilterInitStructure.FilterIdHigh=((EXRID<<3)&0xFFFF0000)>>16;//(((((uint32_t )0X1314)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000)>>16;//筛选高id高位
CAN_FilterInitStructure.FilterIdLow=((EXRID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;//((((uint32_t )0X1314)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000;//筛选高id高位
CAN_FilterInitStructure.FilterMaskIdHigh=0xFF00;
CAN_FilterInitStructure.FilterMaskIdLow=0x0000;//设置筛选器每一位匹配
CAN_FilterInitStructure.FilterFIFOAssignment=CAN_FilterFIFO0;//关联到f0
CAN_FilterInitStructure.FilterActivation=ENABLE;//使能筛选器
HAL_CAN_ConfigFilter(&hcan,&CAN_FilterInitStructure);
}
2.设置中断函数(写在main.c的int main前面)
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef CAN_RX;
uint8_t aData[8];
if(hcan->Instance ==CAN1)
{
HAL_CAN_GetRxMessage(hcan,CAN_FilterFIFO0,&CAN_RX,aData);//从上位机获取数据
HAL_UART_Transmit(&huart1,aData,CAN_RX.DLC,HAL_MAX_DELAY);//把获取的数据通过串口打印出来
}
}
3.main函数中配置
下面代码放在int main(void)里面,放在while(1)上面
HAL_CAN_Start(&hcan);
CAN_Filter_Config();
HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);//fifo0中断
实现结果
1.发送结果
2.接收结果
以上程序是完全可以实现的,当然如果还想要文件的我后续把文件上传一下。还要不了解的可以私信我,我看到会回复。
有需要下载项目程序的小伙伴可以点这个链接下载一下