你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F767ZIT6 CAN1无法接收中断

[复制链接]
jxchen 提问时间:2022-6-27 14:43 / 未解决
使用 STM32F767ZIT6 NUCLEO BOARD + CANALYST -II USB CAN 分析儀 (創芯科技)
波特率設定: 1Mbit/s
传送OK,但無法接收中斷
相關程式碼如下:

/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  *
  * COPYRIGHT(c) 2016 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */


/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef Can1_Handle;
  /* USER CODE BEGIN 1 */
CAN_TxHeaderTypeDef   TxHeader;
CAN_RxHeaderTypeDef   RxHeader;
CAN_FilterConfTypeDef  sFilterConfig;
uint8_t  TxData[8]={0};
uint8_t  RxData[8]={0};
uint8_t  rxflag=0;
uint8_t   flag=0;
uint32_t   TxMailbox;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);


  void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)
{
    RCC_ClkInitTypeDef RCC_ClkInitStruct= {0};
    RCC_OscInitTypeDef RCC_OscInitStruct= {0};
    HAL_StatusTypeDef ret = HAL_OK;
       
                //HAL_RCC_DeInit();                                                //把 RCC 外设初始化成复位状态,这句是必须的
        /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();                                                                                                                                                        //使能PWR时钟
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);        //设置调压器输出电压级别,以便在器件未以最大频率工作

    /*
    使能HSE,配置HSE为PLL的时钟源,配置PLL的各种分频因
    子M N P Q
     * PLLCLK = HSE/M*N/P = 25M / 25 *432 / 2 = 216M
     */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                                        //打开PLL
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = m;                //主PLL和音讯PLL分频系数(PLL之前的分频)
    RCC_OscInitStruct.PLL.PLLN = n;                //主PLL倍频系数(PLL倍频)
    RCC_OscInitStruct.PLL.PLLP = p;                //系统时钟的主PLL分频系数(PLL之后的分频)
    RCC_OscInitStruct.PLL.PLLQ = q;                //USB/SDIO/随机数生成器等的主PLL分频系数(PLL之后的分频)

    ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
    if (ret != HAL_OK) {
        while (1) {
            ;
        }
    }

    /* 启动 OverDrive 模式以达到216M频率  */
    ret = HAL_PWREx_EnableOverDrive();        //开启Over-Driver功能
    if (ret != HAL_OK) {
        while (1) {
            ;
        }
    }

    /* 选择PLLCLK作为SYSCLK,并配置 HCLK, PCLK1 and PCLK2
    的时钟分频因子
     * SYSCLK = PLLCLK     = 216M
     * HCLK   = SYSCLK / 1 = 216M
     * PCLK2  = SYSCLK / 2 = 108M
     * PCLK1  = SYSCLK / 4 = 54M
     */
                //选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK |
                                  RCC_CLOCKTYPE_HCLK |
                                  RCC_CLOCKTYPE_PCLK1 |
                                  RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
/* 此函数会更新SystemCoreClock,并重新配置HAL_InitTick */
    ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);//同时设置FLASH延时周期为7WS,也就是8个CPU周期
    if (ret != HAL_OK) {
        while (1) {
            ;
       }
    }
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
        if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
        {
                /* Reception Error */
                Error_Handler();
        rxflag=0;
        }
    else
    {
        rxflag=1;

    }
}
/*----------------------------------------------------------------------------
  check if transmit mailbox is empty
*----------------------------------------------------------------------------*/
uint8_t CAN_waitReady (void)  {
        uint8_t flag=0;
  while (!(CAN1->TSR & CAN_TSR_TME0));         // Transmit mailbox 0 is empty
       flag= 1;
        return flag;
}
/*

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)
{
        uint8_t  CAN_TxRd=0;

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
        MX_GPIO_Init();
        MX_CAN1_Init();

        TxHeader.StdId = 0X321;
        TxHeader.ExtId = 0x0;
        TxHeader.IDE = CAN_ID_STD;
        TxHeader.RTR = CAN_RTR_DATA;
        TxHeader.DLC = 2;
        TxHeader.TransmitGlobalTime = DISABLE;
        TxData[0] = 0xCA;
        TxData[1] = 0xFE;



  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
        if (flag==0)
    {
                 CAN_TxRdy=CAN_waitReady();
        if (  CAN_TxRdy !=0)
        {
            CAN_TxRdy=0;
                  /* USER CODE BEGIN 3 */
                        if (HAL_CAN_AddTxMessage(&Can1_Handle, &TxHeader, TxData, &TxMailbox) != HAL_OK)
                        {
                                /* Transmission request Error */
                                Error_Handler();
                        }
                        else
                        {
                                 flag=1;
                               
                        }
                }
        }
        else        if (flag==1 && rxflag==1)
        {
                        flag=rxflag=0;
        }
       
  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{
        HSI_SetSysClock(16, 432, 2, 9);
}

/* CAN2 init function */
static void MX_CAN1_Init(void)
{
         __CAN1_CLK_ENABLE();
          Can1_Handle.Instance = CAN1;
      Can1_Handle.Init.Prescaler = 6;
      Can1_Handle.Init.Mode = CAN_MODE_NORMAL;
      Can1_Handle.Init.SyncJumpWidth = CAN_SJW_1TQ;
      Can1_Handle.Init.TimeSeg1 = CAN_BS1_5TQ;
      Can1_Handle.Init.TimeSeg2 = CAN_BS2_3TQ;
      Can1_Handle.Init.TimeTriggeredMode = DISABLE;
      Can1_Handle.Init.AutoBusOff = ENABLE;
      Can1_Handle.Init.AutoWakeUp = ENABLE;
      Can1_Handle.Init.AutoRetransmission = DISABLE;
      Can1_Handle.Init.ReceiveFifoLocked = DISABLE;
      Can1_Handle.Init.TransmitFifoPriority = DISABLE;
      if (HAL_CAN_Init(&Can1_Handle) != HAL_OK)
      {
        Error_Handler();
      }
          
        HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
     /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_TX_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
    HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
       
        sFilterConfig.FilterBank = 0;
        sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
        sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
        sFilterConfig.FilterIdHigh = 0;
        sFilterConfig.FilterIdLow = 0;
        sFilterConfig.FilterMaskIdHigh = 0;
        sFilterConfig.FilterMaskIdLow = 0;
        sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
        sFilterConfig.FilterActivation = ENABLE;
   // sFilterConfig.SlaveStartFilterBank=14;
           HAL_CAN_ConfigFilter(&Can1_Handle, &sFilterConfig);
    {
      /* Filter configuration Error */
      Error_Handler();
    }
  if (HAL_CAN_Start(&Can1_Handle) != HAL_OK)
  {
        /* Start Error */
        Error_Handler();
  }
  if (HAL_CAN_ActivateNotification(&Can1_Handle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
        /* Notification Error */
        Error_Handler();
  }  

}

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
     /* Peripheral clock enable */


     __GPIOB_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PB8     ------> CAN1_RX
    PB9     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler */
}

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */

/**
  * @}
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    stm32f7xx_it.c
  * @brief   Interrupt Service Routines.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f7xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */

/* USER CODE END TD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef Can1_Handle;
/* USER CODE BEGIN EV */

/* USER CODE END EV */

/******************************************************************************/
/*           Cortex-M7 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/**
  * @brief This function handles Non maskable interrupt.
  */
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Pre-fetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32F7xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f7xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles CAN1 TX interrupts.
  */
void CAN1_TX_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_TX_IRQn 0 */

  /* USER CODE END CAN1_TX_IRQn 0 */
  HAL_CAN_IRQHandler(&Can1_Handle);
  /* USER CODE BEGIN CAN1_TX_IRQn 1 */

  /* USER CODE END CAN1_TX_IRQn 1 */
}

/**
  * @brief This function handles CAN1 RX0 interrupts.
  */
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */

  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_IRQHandler(&Can1_Handle);
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */

  /* USER CODE END CAN1_RX0_IRQn 1 */
}

/**
  * @brief This function handles CAN1 RX1 interrupt.
  */
void CAN1_RX1_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX1_IRQn 0 */

  /* USER CODE END CAN1_RX1_IRQn 0 */
  HAL_CAN_IRQHandler(&Can1_Handle);
  /* USER CODE BEGIN CAN1_RX1_IRQn 1 */

  /* USER CODE END CAN1_RX1_IRQn 1 */
}

/**
  * @brief This function handles CAN1 SCE interrupt.
  */
void CAN1_SCE_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_SCE_IRQn 0 */

  /* USER CODE END CAN1_SCE_IRQn 0 */
  HAL_CAN_IRQHandler(&Can1_Handle);
  /* USER CODE BEGIN CAN1_SCE_IRQn 1 */

  /* USER CODE END CAN1_SCE_IRQn 1 */
}

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */


收藏 评论8 发布时间:2022-6-27 14:43

举报

8个回答
1+1=2 回答时间:2022-6-28 07:49:19
你开接收中断了吗?
butterflyspring 回答时间:2022-6-28 11:24:34
CAN通讯对时钟精度要求比较高,楼主应该使用外部HSE晶体作为系统时钟。否则接收很难保证。
梅先生 回答时间:2022-6-29 08:06:45
中断有使能的吗
jxchen 回答时间:2022-7-4 12:44:50



有中断使能如下:
if (HAL_CAN_ActivateNotification(&Can1_Handle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  {
        /* Notification Error */
        Error_Handler();
  }  

已经可以正常动作,感谢帮忙


峰所 回答时间:2022-7-14 10:25:11
jxchen 发表于 2022-7-4 12:44
有中断使能如下:if (HAL_CAN_ActivateNotification(&Can1_Handle, CAN_IT_RX_FIFO0_MSG_PENDING) != HA ...

你好,我也碰到这样的问题了,用创芯科技的CAN控制可以接收到数据,但是发送后,STM32进不了接收中断。
峰所 回答时间:2022-7-14 10:25:54
你好,我也碰到这样的问题了,用创芯科技的CAN控制可以接收到数据,但是发送后,STM32进不了接收中断。请问你的是什么问题?
废鱼 回答时间:2022-7-15 21:50:20
峰所 发表于 2022-7-14 10:25
你好,我也碰到这样的问题了,用创芯科技的CAN控制可以接收到数据,但是发送后,STM32进不了接收中断。请问 ...

1、接收配置需要配置为全接收模式
2、保证CAN 转换芯片不是在低功耗模式,具体查看CAN芯片的手册。
ZHANGYONGHAI 回答时间:2022-11-8 10:43:48
QQ422866299探讨一下FDCAN通信
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版