Перейти к содержанию
    

STM32F303K6 - виснет при приёме сообщений CAN

Приветствую всех,

прошу помощи; не получается принимать сообщения, как только микроконтроллер принимает сообщение он тут же подвисает

 

то есть светодиод мыргает ~2 раза в секунду и отправляет сообщения, это работает, отправленные сообщения вижу CAN анализатором, но как только я CAN анализатором отправляю любое сообщение проц подвисает и светодиод на PA1 мыргать перестаёт (похоже подвисает не core, а переферия потому что в ST-LINK core можно останавливать, запускать, ресететить, ничего не меняется пока не сделаешь system reset)

передачу сообщений в TIM2_IRQHandler отключал, ничего не меняется в поведении, всё также подвисает

если mode переключить в loopback то подвисает тут после ресета, очевидно при приёме своего же первого сообщения

--------------------------------------------------------------------------

подопытный: STM32F303K6

CAN driver: SN65HVD232D

внешний кварц 4 мгц, внутренний такт 72 мгц

IDE: Keil uVision 5

 

Заранее спасибо,

Станислав

 

#include "stm32f30x.h"

void TIM2_IRQHandler(void){
    CanTxMsg canMessage;
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1)){
        GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);
        
    }else{
        GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);
    }
    canMessage.StdId = 0x123;
    canMessage.ExtId = 0;
    canMessage.RTR = CAN_RTR_DATA;
    canMessage.IDE = CAN_ID_STD;
    canMessage.DLC = 8;
     
    canMessage.Data[0] = 0;
    canMessage.Data[1] = 1;
    canMessage.Data[2] = 2;
    canMessage.Data[3] = 3;
    canMessage.Data[4] = 4;
    canMessage.Data[5] = 5;
    canMessage.Data[6] = 6;
    canMessage.Data[7] = 7;
     
    CAN_Transmit(CAN1, &canMessage);
}
void USB_LP_CAN1_RX0_IRQHandler(void) {
    
}

int main() {
    
    GPIO_InitTypeDef GPIO_InitStructure;
    CAN_InitTypeDef CAN_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
    TIM_OCInitTypeDef TIM_OC_InitStructure;
    //CanTxMsg canMessage;

    SystemInit();
    SystemCoreClockUpdate();

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure); //LED1 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2

    GPIO_Init(GPIOA, &GPIO_InitStructure); //LED2

       
    /* CAN GPIOs configuration **************************************************/

    /* Connect CAN pins to AF9 */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_9);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_9); 
    
    /* Configure CAN RX and TX pins */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* NVIC configuration *******************************************************/
    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    
    /* CAN configuration ********************************************************/  
    /* Enable CAN clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    
    /* CAN register init */
    CAN_DeInit(CAN1);
    CAN_StructInit(&CAN_InitStructure);

    /* CAN cell init */
    CAN_InitStructure.CAN_TTCM = DISABLE;
    CAN_InitStructure.CAN_ABOM = DISABLE;
    CAN_InitStructure.CAN_AWUM = DISABLE;
    CAN_InitStructure.CAN_NART = ENABLE;
    CAN_InitStructure.CAN_RFLM = DISABLE;
    CAN_InitStructure.CAN_TXFP = DISABLE;
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//CAN_Mode_LoopBack//CAN_Mode_Normal
    CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
        
    /* CAN Baudrate = 500KBps (CAN clocked at 36 MHz) */
    CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
    CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    CAN_InitStructure.CAN_Prescaler = 2;
    CAN_Init(CAN1, &CAN_InitStructure);

    /* CAN filter init */
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    //CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0401 << 5;
    //CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
    //CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    
    
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
    
    /* Enable FIFO 0 message pending Interrupt */
    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    
    //TIMER BLINK LED
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBase_InitStructure.TIM_Period = 500; //1999
    TIM_TimeBase_InitStructure.TIM_Prescaler = 17999;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_Cmd(TIM2, ENABLE);
    
    while(1) {
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С STM32 не знаком, но разве в обработчике прерываний от CAN не надо принимать сообщение и сбрасывать флаг запроса прерывания? По симптомам похоже, что входит в бесконечный цикл обработки прерывания от CAN.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А почему обработчик прерывания пустой?

void USB_LP_CAN1_RX0_IRQHandler(void) {
    
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С STM32 не знаком, но разве в обработчике прерываний от CAN не надо принимать сообщение и сбрасывать флаг запроса прерывания? По симптомам похоже, что входит в бесконечный цикл обработки прерывания от CAN.

Ага. Нужно хотя бы сбросить флаг "в буфере что-то есть"

 

Bit 1 FMPIE0: FIFO message pending interrupt enable

0: No interrupt generated when state of FMP[1:0] bits are not 00b.

1: Interrupt generated when state of FMP[1:0] bits are not 00b.

 

FMP0[1:0]: FIFO 0 message pending

These bits indicate how many messages are pending in the receive FIFO.

FMP is increased each time the hardware stores a new message in to the FIFO. FMP is

decreased each time the software releases the output mailbox by setting the RFOM0 bit.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:blush:

в standard peripheral library (файл приложил) написано буквально следующее:

(+) Receive Interrupts:

(++) CAN_IT_FMP0.

(++) CAN_IT_FMP1: FIFO 0 and FIFO1 message pending Interrupts;

If enabled, these interrupt sources are pending when messages

are pending in the receive FIFO.

The corresponding interrupt pending bits are cleared only by hardware.

 

попробовал им не поверить, добавил в функцию void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT) новый case:

void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_CLEAR_IT(CAN_IT));

  switch (CAN_IT)
  {
        case CAN_IT_FMP0:
      /* Clear CAN_RF0R_FMP0 (rc_w1)*/ 
      CANx->RF0R |= CAN_RF0R_RFOM0;
      CANx->RF0R = CAN_RF0R_FMP0;
      break;

........................................

 

и сделал

void USB_LP_CAN1_RX0_IRQHandler(void) {

CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);

}

 

ничего не поменялось, также виснет при как только на шине появляется сообщение

stm32f30x_can.rar

Изменено пользователем lau-de

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Первоисточник - reference manual:

http://www.st.com/content/ccc/resource/tec....DM00043574.pdf

 

И там вполне понятно написано:

 

FIFO management

Starting from the empty state, the first valid message received is stored in the FIFO which

becomes pending_1. The hardware signals the event setting the FMP[1:0] bits in the

CAN_RFR register to the value 01b. The message is available in the FIFO output mailbox.

The software reads out the mailbox content and releases it by setting the RFOM bit in the

CAN_RFR register. The FIFO becomes empty again. If a new valid message has been

received in the meantime, the FIFO stays in pending_1 state and the new message is

available in the output mailbox.

 

 

Честно говоря, я не пробовал ни Ваш способ (скинуть флажок FIFO, не вычитывая сообщения), ни вообще STM32F3xx.

Но модули CAN в 105, 205 и 405 контроллерах работают не первый год, прямо по вышеотцитированному алгоритму.

 

 

Раз уж отладчика нет (очень зря. Как раз в таких ситуациях полезно), попробуйте прямо из прерывания отправлять в шину содержимое регистров CAN-модуля. Авось мысли какие-то полезные появятся...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так он даже не заходит в обработку прерывания;

void USB_LP_CAN1_RX0_IRQHandler(void) {

GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);

}

светодиод на PA2 не включает

включил дебагер на ST-LINK, как только оправляешь сообщение он на дебаггер уже не реагирует

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как только оправляешь сообщение он на дебаггер уже не реагирует
Как это? Даже нельзя остановиться и посмотреть, куда занесло ядро и что лежит в регистрах периферии? Какие-то сообщения об ошибках появляются?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

надо было просто вместо общего startup_stm32f30x.s использовать startup_stm32f334x8.s

всё заработало, всем всё равно спасибо :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...