MCU型号:stm32F103RCT6
软件包:
首先是STM32CubeMX配置:
①RCC
②CAN配置
波特率计算方法:
BaudRate=APB1CLK/分频系数/(1+BS1+BS2).
此处:36M/12/(1+3+2)=500k.
CAN工作模式:Normal
打开CAN接收中断:
③打开串口,利用串口调试
中断优先级根据需要设置
最后为勾选“为每个外设生成初始化文件”
生成代码
①在can.c文件中添加过滤器配置函数(接收用)
/* USER CODE BEGIN 1 */
void CAN1_Config(void)
{
CAN_FilterTypeDef CAN_FilterType;
CAN_FilterType.FilterBank=0;
CAN_FilterType.FilterIdHigh=0x0000;
CAN_FilterType.FilterIdLow=0x0000;
CAN_FilterType.FilterMaskIdHigh=0x0000;
CAN_FilterType.FilterMaskIdLow=0x0000;
CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;
CAN_FilterType.FilterMode=CAN_FILTERMODE_IDMASK;
CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
CAN_FilterType.FilterActivation=ENABLE;
CAN_FilterType.SlaveStartFilterBank=14;
if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan)!=HAL_OK)
{
Error_Handler();
}
}
设置为接收所有报文数据(即暂时不过滤)
添加完之后在can.h中声明一下此函数。
②在main.c中添加串口重定义,用于打印信息。
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
在main.c中添加发送函数,并且要声明它。
/***********************************************
函数功能:can发送数据
入口参数:
ide: 0:标准帧
1:扩展帧
id: 帧ID
len: 数据长度
data: 数据
返回值:0:成功。1:失败
************************************************/
uint8_t Can_TxMessage(uint8_t ide,uint32_t id,uint8_t len,uint8_t *data)
{
uint32_t TxMailbox;
CAN_TxHeaderTypeDef CAN_TxHeader;
HAL_StatusTypeDef HAL_RetVal;
uint16_t i=0;
if(ide == 0)
{
CAN_TxHeader.IDE = CAN_ID_STD; //标准帧
CAN_TxHeader.StdId = id;
}
else
{
CAN_TxHeader.IDE = CAN_ID_EXT; //扩展帧
CAN_TxHeader.ExtId = id;
}
CAN_TxHeader.DLC = len;
CAN_TxHeader.RTR = CAN_RTR_DATA;//数据帧,CAN_RTR_REMOTE遥控帧
CAN_TxHeader.TransmitGlobalTime = DISABLE;
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)
{
i++;
if(i>0xfffe)
return 1;
}
HAL_Delay(500);
HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&CAN_TxHeader,data,&TxMailbox);
if(HAL_RetVal != HAL_OK)
return 1;
return 0;
}
接收回调函数:
/*******************************************
函数功能:接受中断回调函数
返回值:无
********************************************/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef CAN_RxHeader;
HAL_StatusTypeDef HAL_Retval;
uint8_t Rx_Data[8];
uint8_t Data_Len=0;
uint32_t ID=0;
uint8_t i;
HAL_Retval = HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&CAN_RxHeader,Rx_Data);
if(HAL_Retval == HAL_OK)
{
Data_Len = CAN_RxHeader.DLC;
if(CAN_RxHeader.IDE)
ID = CAN_RxHeader.ExtId;
else
ID = CAN_RxHeader.StdId;
printf("id:%xrn",ID);
printf("Data_Len:%drn",Data_Len);
for(i=0;i<8;i++)
printf("Rx_Data[%d]=%xrn",i,Rx_Data
);
}
}
下面是main函数
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t data[8]={1,2,3,4,5,6,7,8};//定义发送数组
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
CAN1_Config(); //调用过滤器函数
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Can_TxMessage(0,0x222,8,data);//发送想要发送的报文数据
//0:标准帧 0x222:帧ID 数据长度DLC:8 data:数据存放的数组
HAL_Delay(1000); //发送要有延时
}
/* USER CODE END 3 */
}
调试结果
使用开发板+CAN收发器TJA1050+ZLG的UCBCAN-II分析仪
借助上位机软件CANTest和串口助手
可以看到:MCU发送出来的数据如下,由USBCAN接收到并显示
然后USBCAN发送数据,MCU接收到之后由串口打印显示出来,如下:
注意:TJA1050为5V供电,要和开发板共地。
MCU型号:stm32F103RCT6
软件包:
首先是STM32CubeMX配置:
①RCC
②CAN配置
波特率计算方法:
BaudRate=APB1CLK/分频系数/(1+BS1+BS2).
此处:36M/12/(1+3+2)=500k.
CAN工作模式:Normal
打开CAN接收中断:
③打开串口,利用串口调试
中断优先级根据需要设置
最后为勾选“为每个外设生成初始化文件”
生成代码
①在can.c文件中添加过滤器配置函数(接收用)
/* USER CODE BEGIN 1 */
void CAN1_Config(void)
{
CAN_FilterTypeDef CAN_FilterType;
CAN_FilterType.FilterBank=0;
CAN_FilterType.FilterIdHigh=0x0000;
CAN_FilterType.FilterIdLow=0x0000;
CAN_FilterType.FilterMaskIdHigh=0x0000;
CAN_FilterType.FilterMaskIdLow=0x0000;
CAN_FilterType.FilterFIFOAssignment=CAN_RX_FIFO0;
CAN_FilterType.FilterMode=CAN_FILTERMODE_IDMASK;
CAN_FilterType.FilterScale=CAN_FILTERSCALE_32BIT;
CAN_FilterType.FilterActivation=ENABLE;
CAN_FilterType.SlaveStartFilterBank=14;
if(HAL_CAN_ConfigFilter(&hcan,&CAN_FilterType)!=HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING)!=HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan)!=HAL_OK)
{
Error_Handler();
}
}
设置为接收所有报文数据(即暂时不过滤)
添加完之后在can.h中声明一下此函数。
②在main.c中添加串口重定义,用于打印信息。
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
return ch;
}
在main.c中添加发送函数,并且要声明它。
/***********************************************
函数功能:can发送数据
入口参数:
ide: 0:标准帧
1:扩展帧
id: 帧ID
len: 数据长度
data: 数据
返回值:0:成功。1:失败
************************************************/
uint8_t Can_TxMessage(uint8_t ide,uint32_t id,uint8_t len,uint8_t *data)
{
uint32_t TxMailbox;
CAN_TxHeaderTypeDef CAN_TxHeader;
HAL_StatusTypeDef HAL_RetVal;
uint16_t i=0;
if(ide == 0)
{
CAN_TxHeader.IDE = CAN_ID_STD; //标准帧
CAN_TxHeader.StdId = id;
}
else
{
CAN_TxHeader.IDE = CAN_ID_EXT; //扩展帧
CAN_TxHeader.ExtId = id;
}
CAN_TxHeader.DLC = len;
CAN_TxHeader.RTR = CAN_RTR_DATA;//数据帧,CAN_RTR_REMOTE遥控帧
CAN_TxHeader.TransmitGlobalTime = DISABLE;
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)
{
i++;
if(i>0xfffe)
return 1;
}
HAL_Delay(500);
HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&CAN_TxHeader,data,&TxMailbox);
if(HAL_RetVal != HAL_OK)
return 1;
return 0;
}
接收回调函数:
/*******************************************
函数功能:接受中断回调函数
返回值:无
********************************************/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef CAN_RxHeader;
HAL_StatusTypeDef HAL_Retval;
uint8_t Rx_Data[8];
uint8_t Data_Len=0;
uint32_t ID=0;
uint8_t i;
HAL_Retval = HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&CAN_RxHeader,Rx_Data);
if(HAL_Retval == HAL_OK)
{
Data_Len = CAN_RxHeader.DLC;
if(CAN_RxHeader.IDE)
ID = CAN_RxHeader.ExtId;
else
ID = CAN_RxHeader.StdId;
printf("id:%xrn",ID);
printf("Data_Len:%drn",Data_Len);
for(i=0;i<8;i++)
printf("Rx_Data[%d]=%xrn",i,Rx_Data
);
}
}
下面是main函数
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t data[8]={1,2,3,4,5,6,7,8};//定义发送数组
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
CAN1_Config(); //调用过滤器函数
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Can_TxMessage(0,0x222,8,data);//发送想要发送的报文数据
//0:标准帧 0x222:帧ID 数据长度DLC:8 data:数据存放的数组
HAL_Delay(1000); //发送要有延时
}
/* USER CODE END 3 */
}
调试结果
使用开发板+CAN收发器TJA1050+ZLG的UCBCAN-II分析仪
借助上位机软件CANTest和串口助手
可以看到:MCU发送出来的数据如下,由USBCAN接收到并显示
然后USBCAN发送数据,MCU接收到之后由串口打印显示出来,如下:
注意:TJA1050为5V供电,要和开发板共地。
举报