奏奏奏 发表于 2016-12-31 14:30:34

STM32的CAN slave mode与master mode的区别是什么?

本帖最后由 奏奏奏 于 2017-1-2 23:14 编辑

用的芯片是STM32F107
因为它有两个CAN口
做CAN的中继来用
问题是将CAN1口的接收数据用CAN2口发出是正常的
但是反过来将CAN2口的接收数据用CAN1口发出就出问题了
所以就在考虑是否关系到这个问题:CAN1口是master mode,而CAN2口是slave mode,是否CAN2口的接收中断用法与CAN1口的不一样
贴一下代码:
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
      if(hcan == &hcan1)
      {
                printf("\r\n CAN      receive ID=%x",hcan->pRxMsg->StdId);
                printf("\r\n CAN      receive length=%d      \r\n CAN      receive data:\r\n",hcan->pRxMsg->DLC);
                uint8_t j=hcan->pRxMsg->DLC;
                for(uint8_t i=0;i<j;i++)
                {
                        printf(" %x      ",hcan->pRxMsg->Data);
                }
                printf("\r\n");
               
                //转发到CAN2端口
               
      //
                /*##-1- Configure CAN2 Transmission Massage #####################################*/
                hcan2.pTxMsg->StdId = hcan->pRxMsg->StdId;
                hcan2.pTxMsg->RTR = CAN_RTR_DATA;
                hcan2.pTxMsg->IDE = CAN_ID_STD;
                hcan2.pTxMsg->DLC = hcan->pRxMsg->DLC;

                uint8_t j2=hcan->pRxMsg->DLC;
                for(uint8_t i=0;i<j2;i++)
                {

                        hcan2.pTxMsg->Data =hcan->pRxMsg->Data;
                }

                HAL_CAN_Transmit(&hcan2, 10);
      //      
               
                __HAL_CAN_ENABLE_IT(hcan,CAN_IT_FMP0);//重新开启FIF00消息挂号中断                              
      }


      if(hcan == &hcan2)
      {
                printf("\r\n CAN      receive ID=%x",hcan->pRxMsg->StdId);
                printf("\r\n CAN      receive length=%d      \r\n CAN      receive data:\r\n",hcan->pRxMsg->DLC);
                uint8_t j=hcan->pRxMsg->DLC;
                for(uint8_t i=0;i<j;i++)
                {
                        printf(" %x      ",hcan->pRxMsg->Data);
                }
                printf("\r\n");
               
                //转发到CAN1端口
               
      //
                /*##-1- Configure CAN2 Transmission Massage #####################################*/
                hcan1.pTxMsg->StdId = hcan->pRxMsg->StdId;
                hcan1.pTxMsg->RTR = CAN_RTR_DATA;
                hcan1.pTxMsg->IDE = CAN_ID_STD;
                hcan1.pTxMsg->DLC = hcan->pRxMsg->DLC;

                uint8_t j2=hcan->pRxMsg->DLC;
                for(uint8_t i=0;i<j2;i++)
                {

                        hcan1.pTxMsg->Data =hcan->pRxMsg->Data;
                }

                HAL_CAN_Transmit_IT(&hcan1);
      //      
               
                __HAL_CAN_ENABLE_IT(hcan,CAN_IT_FMP0);//重新开启FIF00消息挂号中断                              
      }
}

奏奏奏 发表于 2017-1-2 22:54:18

找到解决CAN2接收问题的办法了
上面的代码中

sFilterConfig.FilterNumber = 0;
修改为:
sFilterConfig.FilterNumber = 14;

就可以解决了。:lol

任风吹吹 发表于 2016-12-31 16:24:02

CAN1口是master mode,而CAN2口是slave mode。。。。
跟这个SLAVEMODE是没有关系的,这个只是说CAN2是没有自己的过滤器,而是共享了CAN1的过滤器组,所以CAN2就叫SLAVE了。

你的问题可以这样排查:
CAN2能接收到数据吗?
CAN2单独能发送数据吗?

奏奏奏 发表于 2017-1-1 01:17:58

任风吹吹 发表于 2016-12-31 16:24
CAN1口是master mode,而CAN2口是slave mode。。。。
跟这个SLAVEMODE是没有关系的,这个只是说CAN2是没有 ...

好的,谢谢!我按这个思路查一遍

damiaa 发表于 2017-1-1 10:28:20

顶起顶起

5265325 发表于 2017-1-1 12:09:14

:lol:lol:lol:lol

五哥1 发表于 2017-1-1 14:43:16

二楼回答正确,你需要回答这两个问题

andypanfan 发表于 2017-1-1 15:13:48

:lol:lol:lol:lol:lol:lol:lol:lol:lol

奏奏奏 发表于 2017-1-2 20:07:41

本帖最后由 奏奏奏 于 2017-1-2 20:09 编辑

任风吹吹 发表于 2016-12-31 16:24
CAN1口是master mode,而CAN2口是slave mode。。。。
跟这个SLAVEMODE是没有关系的,这个只是说CAN2是没有 ...
排查过了。
CAN2不能接收到数据!问题在这里
CAN2单独发送数据正常。
附上main.c的代码:

/**
******************************************************************************
* 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 "stm32f1xx_hal.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
CAN_FilterConfTypeDefsFilterConfig;
static CanTxMsgTypeDef      TxMessage;
static CanRxMsgTypeDef      RxMessage;
/* USER CODE END PV */

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

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

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

int main(void)
{

/* USER CODE BEGIN 1 */

/* 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();
MX_CAN2_Init();
MX_USART1_UART_Init();

/* USER CODE BEGIN 2 */
printf("\n\r UART Printf Example: retarget the C library printf function to the UART\n\r");
       
//hcan1.pTxMsg = &TxMessage;
hcan2.pRxMsg = &RxMessage;
        __HAL_CAN_ENABLE_IT(&hcan2,CAN_IT_FMP1);//重新开启FIF00消息挂号中断
//        __HAL_CAN_ENABLE_IT(&hcan2,CAN_IT_FMP0);//重新开启FIF00消息挂号中断
printf("**** This is CAN test program ****\r\n\r\n");

/*##-1- Configure CAN2 Transmission Massage #####################################*/
//hcan2.pTxMsg->StdId = 0x123;
//hcan2.pTxMsg->RTR = CAN_RTR_DATA;
//hcan2.pTxMsg->IDE = CAN_ID_STD;
//hcan2.pTxMsg->DLC = 8;
//hcan2.pTxMsg->Data = 'C';
//hcan2.pTxMsg->Data = 'A';
//hcan2.pTxMsg->Data = 'N';
//hcan2.pTxMsg->Data = ' ';
//hcan2.pTxMsg->Data = 'T';
//hcan2.pTxMsg->Data = 'e';
//hcan2.pTxMsg->Data = 's';
//hcan2.pTxMsg->Data = 't';

/*##-2- Configure the CAN1 Filter ###########################################*/
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);       
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
//      printf("\n\r welcome to www.waveshere.com !!!\n\r");
      HAL_Delay(1000);
      /*##-3- Start the CAN2 Transmission process #####################################*/
//      if(HAL_CAN_Transmit(&hcan2, 10) != HAL_OK)
//      {
//          /* Transmition Error */
//          Error_Handler();
//      }
//                        HAL_CAN_Transmit(&hcan2, 10);
//               
//      if(HAL_CAN_GetState(&hcan2) != HAL_CAN_STATE_READY)
//      {
//          Error_Handler();
//            
//      }
      /*##-4- Start the CAN1 Reception process ########################################*/
//      if(HAL_CAN_Receive(&hcan1, CAN_FIFO0,10) != HAL_OK)
//      {
//          /* Reception Error */
//          Error_Handler();   
//      }
//                        HAL_CAN_Receive(&hcan1, CAN_FIFO0,10);
                       
//      if(HAL_CAN_GetState(&hcan1) != HAL_CAN_STATE_READY)
//      {
//          Error_Handler();
//      }
//      printf("StdId : %x\r\n",hcan1.pRxMsg->StdId);
//      printf("RxMsg : %s",hcan1.pRxMsg->Data);
//      printf("\r\n\r\n");   
      
//      HAL_Delay(1000);

}
/* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
    Error_Handler();
}

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
    Error_Handler();
}

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

__HAL_RCC_PLLI2S_ENABLE();

/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* USER CODE BEGIN 4 */
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
        printf("\r\n CAN        receive ID=%x",hcan->pRxMsg->StdId);
        printf("\r\n CAN        receive length=%d        \r\n CAN        receive data:\r\n",hcan->pRxMsg->DLC);
        uint8_t j=hcan->pRxMsg->DLC;
        for(uint8_t i=0;i<j;i++)
        {
                printf(" %x        ",hcan->pRxMsg->Data);
        }
        printf("\r\n");
       
        //转发到CAN2端口
       
//
/*##-1- Configure CAN2 Transmission Massage #####################################*/
//hcan1.pTxMsg->StdId = hcan->pRxMsg->StdId;
//hcan1.pTxMsg->RTR = CAN_RTR_DATA;
//hcan1.pTxMsg->IDE = CAN_ID_STD;
//hcan1.pTxMsg->DLC = hcan->pRxMsg->DLC;
////hcan2.pTxMsg->Data = 'C';
////hcan2.pTxMsg->Data = 'A';
////hcan2.pTxMsg->Data = 'N';
////hcan2.pTxMsg->Data = ' ';
////hcan2.pTxMsg->Data = 'T';
////hcan2.pTxMsg->Data = 'e';
////hcan2.pTxMsg->Data = 's';
////hcan2.pTxMsg->Data = 't';
//        uint8_t j2=hcan->pRxMsg->DLC;
//        for(uint8_t i=0;i<j2;i++)
//        {
////                printf(" %x        ",hcan->pRxMsg->Data);
//                hcan1.pTxMsg->Data =hcan->pRxMsg->Data;
//        }
////        printf("\r\n");
//        HAL_CAN_Transmit(&hcan1, 10);
//       
       
//        __HAL_CAN_ENABLE_IT(hcan,CAN_IT_FMP0);//重新开启FIF00消息挂号中断               
        __HAL_CAN_ENABLE_IT(hcan,CAN_IT_FMP1);//重新开启FIF00消息挂号中断               
}
/* USER CODE END 4 */

/**
* @briefThis function is executed in case of error occurrence.
* @paramNone
* @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****/


ts2000 发表于 2017-1-3 08:40:33

学习一下!!!!
页: [1] 2
查看完整版本: STM32的CAN slave mode与master mode的区别是什么?