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消息挂号中断
}
}
找到解决CAN2接收问题的办法了
上面的代码中
将
sFilterConfig.FilterNumber = 0;
修改为:
sFilterConfig.FilterNumber = 14;
就可以解决了。:lol CAN1口是master mode,而CAN2口是slave mode。。。。
跟这个SLAVEMODE是没有关系的,这个只是说CAN2是没有自己的过滤器,而是共享了CAN1的过滤器组,所以CAN2就叫SLAVE了。
你的问题可以这样排查:
CAN2能接收到数据吗?
CAN2单独能发送数据吗?
任风吹吹 发表于 2016-12-31 16:24
CAN1口是master mode,而CAN2口是slave mode。。。。
跟这个SLAVEMODE是没有关系的,这个只是说CAN2是没有 ...
好的,谢谢!我按这个思路查一遍 顶起顶起 :lol:lol:lol:lol 二楼回答正确,你需要回答这两个问题 :lol:lol:lol:lol:lol:lol:lol:lol:lol 本帖最后由 奏奏奏 于 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****/
学习一下!!!!
页:
[1]
2