SYS配置
RCC配置
时钟配置
CAN配置
can.c中的HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)函数添加了开启can外设的函数
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN GPIO Configuration
PA11 ------> CAN_RX
PA12 ------> CAN_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/*需要添加CAN外设开启函数,否则CAN无法正常工作*/
HAL_CAN_Start(&hcan);//开启CAN
/* USER CODE END CAN1_MspDeInit 1 */
}
}
main.c中添加了过滤器配置函数和发送接收函数
/* USER CODE BEGIN 0 */
/*
* @brief:CAN过滤器配置,接收模式采用的是列表模式
* @param:can_id1(筛选第一个ID号)
* @param:can_id2(筛选第二个ID号)
*
* @retval:none
*/
void CAN_Fliter_Config_IDLIST(uint32_t can_id1,uint32_t can_id2)
{
CAN_FilterTypeDef hcan_filterconfig;
hcan_filterconfig.FilterActivation = CAN_FILTER_ENABLE;//过滤器使能
hcan_filterconfig.FilterBank = 0; //使用过滤器0
hcan_filterconfig.FilterMode = CAN_FILTERMODE_IDLIST;//采用列表模式
hcan_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
hcan_filterconfig.FilterFIFOAssignment = CAN_FilterFIFO0;//使用FIFO0
hcan_filterconfig.FilterIdHigh = (((((uint32_t)can_id1)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xffff0000)>>16;//过滤器ID高16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.FilterIdLow = (((((uint32_t)can_id1)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0x0000ffff); //过滤器ID低16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.FilterMaskIdHigh = (((((uint32_t)can_id1)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xffff0000)>>16;//过滤器掩码高16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.FilterMaskIdLow = (((((uint32_t)can_id1)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0x0000ffff); //过滤器掩码低16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.SlaveStartFilterBank = 14; //过滤器数量14
HAL_CAN_ConfigFilter(&hcan,&hcan_filterconfig); //初始化过滤器
HAL_CAN_Start(&hcan);//开启CAN
HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);//开启CAN-FIFO0中断
}
/*
* @brief:CAN过滤器配置,接收模式采用的是掩码模式
* @param:id(筛选的ID号)
* @param:mask_if(掩码)
*
* @retval:none
*/
void CAN_Fliter_Config_IDMASK(uint32_t id,uint32_t mask_id)
{
CAN_FilterTypeDef hcan_filterconfig;
hcan_filterconfig.FilterActivation = CAN_FILTER_ENABLE;//过滤器使能
hcan_filterconfig.FilterBank = 0; //使用过滤器0
hcan_filterconfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用列表模式
hcan_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
hcan_filterconfig.FilterFIFOAssignment = CAN_FilterFIFO0;//使用FIFO0
hcan_filterconfig.FilterIdHigh = (((((uint32_t)id)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xffff0000)>>16;//过滤器ID高16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.FilterIdLow = (((((uint32_t)id)<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0x0000ffff); //过滤器ID低16位,CAN_ID_EXT(扩展ID)、CAN_RTR_DATA(帧类型为数据帧)
hcan_filterconfig.FilterMaskIdHigh = (mask_id & 0xffff0000)>>16;//过滤器掩码高16位
hcan_filterconfig.FilterMaskIdLow = mask_id & 0x0000ffff; //过滤器掩码低16位
hcan_filterconfig.SlaveStartFilterBank = 14; //过滤器数量14
HAL_CAN_ConfigFilter(&hcan,&hcan_filterconfig); //初始化过滤器
HAL_CAN_Start(&hcan);//开启CAN
HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);//开启CAN-FIFO0中断
}
/*
* @brief:CAN发送函数
* @param:id(CAN发送的ID号)
* @param:ide(帧ID号类型选择)
CAN_ID_STD:标准ID号
CAN_ID_EXT:扩展ID号
* @param:*pMsg(要发送的数据)
* @param:len(发送的数据长度)
*
* @retval:返回0:正常
返回1:异常
*/
uint8_t CAN_SendMsg(uint32_t id,uint8_t ide,uint8_t *pMsg,uint8_t len)
{
CAN_TxHeaderTypeDef pHeader;
uint32_t pTxmailbox;
uint8_t result = 0;
HAL_StatusTypeDef CanStatus;
if(ide == CAN_ID_STD)
{
pHeader.StdId = id; //标准ID号
pHeader.IDE = CAN_ID_STD;//标准ID
}
else
{
pHeader.ExtId = id;//扩展ID号
pHeader.IDE = CAN_ID_STD;//扩展ID
}
pHeader.RTR = CAN_RTR_DATA;//传输数据的帧类型为数据帧
pHeader.DLC = len>8?8:len;//发送数据的字节长度,最大为8个字节
pHeader.TransmitGlobalTime = DISABLE;//是否要发送时间戳
CanStatus = HAL_CAN_AddTxMessage(&hcan, &pHeader, pMsg, &pTxmailbox);//CAN发送函数
if(CanStatus != HAL_OK)
{
result = 1;
}
return result;
}
/*CAN-FIFO0中断回调函数*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef Header;
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);//翻转电平
if(hcan->Instance == CAN1)
{
if(Header.ExtId == 0x012345678) //如果CAN接收的扩展ID为x012345678,则执行以下
{
printf("接收到扩展ID为:0x01234567");
}
if(Header.StdId == 0x087654321) //如果CAN接收的扩展ID为0x07654321,则执行以下
{
printf("接收到扩展ID为:0x07654321");
}
}
}
/* USER CODE END 0 */
main函数中成功发送数据后执行HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13)实现了stm32上的led闪烁,但是电脑上并未收到数据,接收器的RXD灯也未闪烁(A11连接CANH,A12连接CANL,接收器上0R和120R都试过,双方波特率都是250k)。当注释掉main函数中的电平翻转函数HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13),写到can接收中断函数中时,电脑上发送数据给stm32并未出现led灯的亮灭,但是can接收上面的TXD灯会随着电脑给stm32发送数据出现闪烁。求指点,感谢感谢
int main(void)
{
/* USER CODE BEGIN 1 */
char CAN_Send_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();
/* USER CODE BEGIN 2 */
CAN_Fliter_Config_IDLIST(0x012345678,0x07654321);//CAN过滤器配置
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(CAN_SendMsg(0x123,CAN_ID_STD,CAN_Send_Data,8)==0)//CAN发送函数
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
}
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}