Forum: Mikrocontroller und Digitale Elektronik STM32F429 CAN will nicht empfangen


von W. M. (muhh)


Lesenswert?

Hey Leute,

ich versuche gerade das CAN2-Modul des STM32F429 zum laufen zu bekommen.

Mein Vorhaben:

Ich benutze CAN1 um Nachrichten zu schicken und CAN2 um diese zu 
empfangen. Dabei soll das Interrupt (CAN2_RX0_IRQn) beim Empfangen 
ausgelöst, der Inhalt der Nachricht überprüft und dann eine LED 
getooglet werden.

Das ganze läuft über einen CAN-Bus der mit 2x120Ohm Widerständen 
terminiert wird und die TI ISO1050 als CAN-Treiber benutzt. Auf dem 
Oszilloskop sehe ich die Nachricht die von CAN1 geschickt wird, das 
Interrupt wird jedoch nicht ausglöst...

Hier ist der Code der das bewerkstelligen soll:
1
#include "main.h"
2
#include "stm32f4xx_gpio.h"
3
#include "stm32f4xx_rcc.h"
4
#include "stm32f4xx_tim.h"
5
#include "stm32f4xx_spi.h"
6
#include "stm32f4xx_exti.h"
7
#include "stm32f4xx_can.h"
8
#include "misc.h"
9
10
void Delay(volatile uint32_t nCount) {
11
  while(nCount--);
12
}
13
14
int main(void)
15
{
16
  SystemInit(); // Activate Oscillator Settings (SysClk = 168MHz, AHB1 = APB2 = 84 MHz, APB1 = 42MHz)
17
18
  // Create InitStructures
19
  GPIO_InitTypeDef GPIO_InitStructure[3];
20
  CAN_InitTypeDef CAN_InitStructure;
21
  NVIC_InitTypeDef NVIC_InitStructure[2];
22
  EXTI_InitTypeDef EXTI_InitStructure;
23
24
  // Enable Peripheral Clocks
25
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOG, ENABLE);
26
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);
27
28
  // Configure GPIOs
29
  GPIO_InitStructure[0].GPIO_Pin = GPIO_Pin_0;
30
  GPIO_InitStructure[0].GPIO_Mode = GPIO_Mode_IN;
31
  GPIO_InitStructure[0].GPIO_Speed = GPIO_Speed_100MHz;
32
  GPIO_InitStructure[0].GPIO_OType = GPIO_OType_PP;
33
  GPIO_InitStructure[0].GPIO_PuPd = GPIO_PuPd_NOPULL;
34
35
  GPIO_InitStructure[1].GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_8 | GPIO_Pin_9;
36
  GPIO_InitStructure[1].GPIO_Mode = GPIO_Mode_AF;
37
  GPIO_InitStructure[1].GPIO_Speed = GPIO_Speed_100MHz;
38
  GPIO_InitStructure[1].GPIO_OType = GPIO_OType_PP;
39
  GPIO_InitStructure[1].GPIO_PuPd = GPIO_PuPd_NOPULL;
40
41
  GPIO_InitStructure[2].GPIO_Pin = GPIO_Pin_13;
42
  GPIO_InitStructure[2].GPIO_Mode = GPIO_Mode_OUT;
43
  GPIO_InitStructure[2].GPIO_Speed = GPIO_Speed_100MHz;
44
  GPIO_InitStructure[2].GPIO_OType = GPIO_OType_PP;
45
  GPIO_InitStructure[2].GPIO_PuPd = GPIO_PuPd_NOPULL;
46
47
  GPIO_Init(GPIOA, &GPIO_InitStructure[0]);
48
  GPIO_Init(GPIOB, &GPIO_InitStructure[1]);
49
  GPIO_Init(GPIOG, &GPIO_InitStructure[2]);
50
51
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2);
52
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2);
53
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1);
54
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1);
55
56
  // Configure CAN1,CAN2
57
  CAN_InitStructure.CAN_Prescaler = 9;
58
  CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
59
  CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;
60
  CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
61
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
62
  CAN_InitStructure.CAN_TTCM = DISABLE;
63
  CAN_InitStructure.CAN_ABOM = DISABLE;
64
  CAN_InitStructure.CAN_AWUM = DISABLE;
65
  CAN_InitStructure.CAN_NART = ENABLE;
66
  CAN_InitStructure.CAN_RFLM = DISABLE;
67
  CAN_InitStructure.CAN_TXFP = DISABLE;
68
69
  CAN_Init(CAN1, &CAN_InitStructure);
70
  CAN_Init(CAN2, &CAN_InitStructure);
71
72
  CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);  // CAN2 Interrupt on Message Reception at FIFO0
73
74
  // Configure NVCI for Interrupt on EXTI0
75
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
76
77
  NVIC_InitStructure[0].NVIC_IRQChannel = EXTI0_IRQn;
78
  NVIC_InitStructure[0].NVIC_IRQChannelCmd = ENABLE;
79
  NVIC_InitStructure[0].NVIC_IRQChannelPreemptionPriority = 0;
80
  NVIC_InitStructure[0].NVIC_IRQChannelSubPriority = 1;
81
82
  NVIC_InitStructure[1].NVIC_IRQChannel = CAN2_RX0_IRQn;
83
  NVIC_InitStructure[1].NVIC_IRQChannelCmd = ENABLE;
84
  NVIC_InitStructure[1].NVIC_IRQChannelPreemptionPriority = 0;
85
  NVIC_InitStructure[1].NVIC_IRQChannelSubPriority = 0;
86
87
  NVIC_Init(&NVIC_InitStructure[0]);
88
  NVIC_Init(&NVIC_InitStructure[1]);
89
90
  // Configure ExternalInterrupt for EXTI_Line0
91
92
  EXTI_InitStructure.EXTI_Line = EXTI_Line0;
93
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
94
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
95
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
96
  EXTI_Init(&EXTI_InitStructure);
97
98
  NVIC_EnableIRQ(EXTI0_IRQn);  // Enable EXTI0 global Interrupt
99
  NVIC_EnableIRQ(CAN2_RX0_IRQn);  // Enable CAN2 global Interrupt
100
101
  while(1) // Zum Debuggen dauerhaft CAN-Nachrichten schicken
102
  {
103
  CanTxMsg canMessage;
104
105
  canMessage.StdId = 0x000;
106
  canMessage.ExtId = 0;
107
  canMessage.RTR = CAN_RTR_DATA;
108
  canMessage.IDE = CAN_ID_STD;
109
  canMessage.DLC = 1;
110
  canMessage.Data[0] = 0xAA;
111
112
  CAN_Transmit(CAN1, &canMessage);
113
  }
114
}  // end main
115
116
void EXTI0_IRQHandler(void)
117
{
118
  EXTI_ClearITPendingBit(EXTI_Line0);
119
120
  // Create CAN TxMessage Structure
121
  CanTxMsg canMessage;
122
123
  canMessage.StdId = 0x000;
124
  canMessage.ExtId = 0;
125
  canMessage.RTR = CAN_RTR_DATA;
126
  canMessage.IDE = CAN_ID_STD;
127
  canMessage.DLC = 1;
128
  canMessage.Data[0] = 0xAA;
129
130
  CAN_Transmit(CAN1, &canMessage);
131
}
132
133
void CAN2_RX0_IRQHandler(void)
134
{
135
  NVIC_ClearPendingIRQ(CAN2_RX0_IRQn);
136
  CanRxMsg RxMessage;
137
  CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);
138
  if(RxMessage.Data[0] == 0xAA)
139
  {
140
    GPIO_ToggleBits(GPIOG, GPIO_Pin_13);
141
  }
142
}

Viele Grüße

von Rainer M. (excogitator)


Lesenswert?

Ich bin mir nicht ganz sicher, aber musste man beim STM32 zum Empfang 
von CAN-Nachrichten nicht noch die Eingangsfilter setzen?

Gruß
Rainer

von W. M. (muhh)


Lesenswert?

Rainer M. schrieb:
> Ich bin mir nicht ganz sicher, aber musste man beim STM32 zum Empfang
> von CAN-Nachrichten nicht noch die Eingangsfilter setzen?

Das war das Problem, habe es jetzt hinbekommen. Sehr komisch das man die 
Filter nicht einfach alle ausschalten kann um alles durchzulassen. 
Vielleicht habe ich die Stelle im Reference Manual aber auch 
übersehen...

von Ramachandran Mahalingam (Gast)


Lesenswert?

How did you solve that Problem..Even I am facing the same problem after 
initalizing the filters

von Disko (Gast)


Lesenswert?

You have to also enable can1. The Filter for can2 are defined in can1 at 
normaly filterbank 14. But you can change it.

von ABCD (Gast)


Lesenswert?

I hav already enable my clock and init of CAN1.

Should I even enable the filter of CAN1?

Herwith I am attaching the pgm.

/**
  ************************************************************************ 
******
  * File Name          : main.c
  * Date               : 11/12/2014 15:46:18
  * Description        : Main program body
  ************************************************************************ 
******
  *
  * COPYRIGHT(c) 2014 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 "stm32f4xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables 
---------------------------------------------------------*/
//CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

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

/* USER CODE BEGIN PFP */

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

  CAN_FilterConfTypeDef hcan2Filter;
hcan2Filter.FilterNumber = 14;                       // Specifies the 
filter which will be initialized
hcan2Filter.FilterMode = CAN_FILTERMODE_IDLIST;          // Specifies 
the filter mode to be initialized.
hcan2Filter.FilterScale = CAN_FILTERSCALE_32BIT;          // Specifies 
the filter scale.
hcan2Filter.FilterIdHigh = 0x00;                      // Specifies the 
filter identification number (MSBs for a 32-bit configuration, first one 
for a 16-bit configuration).
hcan2Filter.FilterIdLow = 0x00;                      // Specifies the 
filter identification number (LSBs for a 32-bit configuration, second 
one for a 16-bit configuration).
hcan2Filter.FilterMaskIdHigh = 0x00;                    // Specifies the 
filter mask number or identification number, according to the mode (MSBs 
for a 32-bit configuration, first one for a 16-bit configuration).
hcan2Filter.FilterMaskIdLow = 0x00;                    // Specifies the 
filter mask number or identification number, according to the mode (LSBs 
for a 32-bit configuration, second one for a 16-bit configuration).
hcan2Filter.FilterFIFOAssignment = CAN_FILTER_FIFO1;                  // 
Specifies the FIFO (0 or 1) which will be assigned to the filter.
hcan2Filter.FilterActivation = ENABLE;                  // Enable or 
disable the filter.
hcan2Filter.BankNumber = 14;                      // Select the start 
slave bank filter
HAL_CAN_ConfigFilter(&hcan2, &hcan2Filter);

  /* USER CODE BEGIN 2 */

  GPIO_InitTypeDef  GPIO_Initpins;

 GPIO_Initpins.Mode = GPIO_MODE_OUTPUT_PP ;
 GPIO_Initpins.Pin = GPIO_PIN_5|GPIO_PIN_7;
 GPIO_Initpins.Pull = GPIO_NOPULL  ;
 GPIO_Initpins.Speed = GPIO_SPEED_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_Initpins);

 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET);
  /* USER CODE END 2 */

  /* USER CODE BEGIN 3 */
  /* Infinite loop */
 CanTxMsgTypeDef TxMess;

 TxMess.StdId = 0x123;
 //TxMess.ExtId = 0x13375000;
 TxMess.DLC = 0x1;
 TxMess.Data[0] = 0xAA;
 TxMess.IDE = CAN_ID_STD ;
 TxMess.RTR = CAN_RTR_DATA;
 hcan2.pTxMsg = &TxMess;

HAL_CAN_Transmit(&hcan2,50);




HAL_CAN_Receive_IT(&hcan2,CAN_FIFO1);
HAL_Delay(50);

CanRxMsgTypeDef RxMess;

RxMess.StdId = 0x741;
RxMess.DLC = 1;
RxMess.IDE = CAN_ID_STD;
RxMess.Data[0] = 0x11;
//RxMess.FMI = 0x14;
RxMess.FIFONumber = CAN_FIFO0;;
RxMess.ExtId = 0;
RxMess.RTR = CAN_RTR_DATA;
hcan2.pRxMsg = &RxMess;
while(1){
  HAL_CAN_Receive(&hcan2,CAN_FIFO1,0);
HAL_Delay(50);
}
  /* USER CODE END 3 */

}

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

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  __PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

}

/* CAN1 init function */
void MX_CAN1_Init(void)
{

 hcan1.Instance = CAN1;
 hcan1.Init.Prescaler = 16;
 hcan1.Init.Mode = CAN_MODE_NORMAL;
 hcan1.Init.SJW = CAN_SJW_1TQ;
 hcan1.Init.BS1 = CAN_BS1_1TQ;
  hcan1.Init.BS2 = CAN_BS2_1TQ;
 hcan1.Init.TTCM = DISABLE;
 hcan1.Init.ABOM = DISABLE;
  hcan1.Init.AWUM = DISABLE;
 hcan1.Init.NART = DISABLE;
  hcan1.Init.RFLM = DISABLE;
  hcan1.Init.TXFP = DISABLE;
 HAL_CAN_Init(&hcan1);

}

/* CAN2 init function */
void MX_CAN2_Init(void)
{

  hcan2.Instance = CAN2;
  hcan2.Init.Prescaler = 2;
  hcan2.Init.Mode = CAN_MODE_NORMAL;
  hcan2.Init.SJW = CAN_SJW_1TQ;
  hcan2.Init.BS1 = CAN_BS1_5TQ;
  hcan2.Init.BS2 = CAN_BS2_2TQ;
  hcan2.Init.TTCM = DISABLE;
  hcan2.Init.ABOM = ENABLE;
  hcan2.Init.AWUM = ENABLE;
  hcan2.Init.NART = DISABLE;
  hcan2.Init.RFLM = DISABLE;
  hcan2.Init.TXFP = ENABLE;
  HAL_CAN_Init(&hcan2);


}

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __GPIOH_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
 __GPIOD_CLK_ENABLE();
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#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****/

von Disko (Gast)


Lesenswert?

1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
3
NVIC_EnableIRQ(CAN2_RX0_IRQn);
4
CAN2_start_Bank = (CAN1->FMR >> 8);            // Default:  0x0EFilterNumber += CAN2_start_Bank;  
5
FilterBit    = 1UL << FilterNumber;CAN1->FMR  |=   CAN_FMR_FINIT;                             /* set InitMode for filter banks */
6
CAN1->FA1R &=  ~(FilterBit);                                      /*deactivate filter              */
7
CAN1->FS1R |=   (FilterBit);                                      /* set32-bit scale configuration    */
8
9
.
10
...

von ABCD M. (ramachandran_m)


Lesenswert?

I have even tried this but still I am not able to receive any message 
from PCAN device ...My problem is while debugging it always runs through 
the timeout function and it doesnt come out of the loop

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.