今天进行的是can的初步测试,主要通过中断函数接收消息,首先是使能CAN和中断:
HAL_CAN_Start(&hcan1);
HAL_CAN_Start(&hcan2);
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
配置CAN Filter
CAN_FilterTypeDef filter;
filter.FilterBank = 0;
filter.FilterMode=CAN_FILTERMODE_IDMASK;
filter.FilterScale=CAN_FILTERSCALE_32BIT;
filter.FilterIdHigh=0x0000;
filter.FilterIdLow=0x0000;
filter.FilterMaskIdHigh=0x0000;
filter.FilterMaskIdLow=0x0000;
filter.FilterFIFOAssignment=CAN_FILTER_FIFO0;
filter.FilterActivation=ENABLE;
if(HAL_CAN_ConfigFilter(&hcan1, &filter) != HAL_OK)
{
Error_Handler();
}
编写中断处理函数
uint8_t tx_data[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
void delay_us(uint32_t nus)
{
uint32_t fac_us = 168;
uint32_t told, tnow;
uint32_t tcnt = 0;
uint32_t reload = SysTick->LOAD;
uint32_t ticks = nus * fac_us;
told = SysTick->VAL;
while(1)
{
tnow = SysTick->VAL;
if(tnow != told)
{
if(tnow < told)
tcnt += told - tnow;
else
tcnt += reload - tnow + told;
told = tnow;
if(tcnt >= ticks)
break;
}
}
}
uint8_t CANx_SendStdData(CAN_HandleTypeDef* hcan, uint16_t ID, uint8_t *pData, uint16_t Len)
{
static CAN_TxHeaderTypeDef Tx_Header;
Tx_Header.StdId=ID;
Tx_Header.ExtId=0;
Tx_Header.IDE=0;
Tx_Header.RTR=0;
Tx_Header.DLC=Len;
HAL_CAN_AddTxMessage(hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX0);
//if(HAL_CAN_AddTxMessage(hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK)
//{
// if(HAL_CAN_AddTxMessage(hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX1) != HAL_OK)
// {
// HAL_CAN_AddTxMessage(hcan, &Tx_Header, pData, (uint32_t*)CAN_TX_MAILBOX2);
// }
//}
return 0;
}
CAN_RxHeaderTypeDef rx_header1;
CAN_RxHeaderTypeDef rx_header2;
uint8_t rx_msg_1[8] = {0};
uint8_t rx_msg_2[8] = {0};
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance==CAN1)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_CAN_GetRxMessage(&hcan1, CAN_FILTER_FIFO0, &rx_header1, rx_msg_1);
//HAL_UART_Transmit(&huart2, rx_msg_1, 8, 10000);
// delay 20 us
//delay_us(20);
//CANx_SendStdData(&hcan1, 0x01, tx_data, 8);
// unpack data
}
if(hcan->Instance==CAN2)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
HAL_CAN_GetRxMessage(&hcan2, CAN_FILTER_FIFO0, &rx_header2, rx_msg_2);
//HAL_UART_Transmit(&huart2, rx_msg_2, 8, 10000);
// delay 20 us
//delay_us(20);
//CANx_SendStdData(&hcan2, 0x01, tx_data, 8);
// unpack data
}
}
如果在中断接收中编写耗时过长的部分,很容易导致CAN中断处理失败。我向让CAN在中断接收时进行数据处理并返回消息,结果并没有成功连续接收。按照1ms的间隔发送消息,仅有开头一部分成功处理,后续的全部失败。