реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32F303K6 - виснет при приёме сообщений CAN
lau-de
сообщение Dec 14 2016, 10:05
Сообщение #1





Группа: Новичок
Сообщений: 4
Регистрация: 14-12-16
Пользователь №: 94 629



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

то есть светодиод мыргает ~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) {
    }
}
Go to the top of the page
 
+Quote Post
novikovfb
сообщение Dec 14 2016, 10:10
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450



С STM32 не знаком, но разве в обработчике прерываний от CAN не надо принимать сообщение и сбрасывать флаг запроса прерывания? По симптомам похоже, что входит в бесконечный цикл обработки прерывания от CAN.
Go to the top of the page
 
+Quote Post
adnega
сообщение Dec 14 2016, 10:20
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



А почему обработчик прерывания пустой?
Код
void USB_LP_CAN1_RX0_IRQHandler(void) {
    
}
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Dec 14 2016, 10:46
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(novikovfb @ Dec 14 2016, 13:10) *
С 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.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
lau-de
сообщение Dec 14 2016, 20:19
Сообщение #5





Группа: Новичок
Сообщений: 4
Регистрация: 14-12-16
Пользователь №: 94 629



blush.gif
в 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);
}

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

Сообщение отредактировал lau-de - Dec 14 2016, 20:21
Прикрепленные файлы
Прикрепленный файл  stm32f30x_can.rar ( 9.6 килобайт ) Кол-во скачиваний: 8
 
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Dec 14 2016, 21:10
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Первоисточник - 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-модуля. Авось мысли какие-то полезные появятся...


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
lau-de
сообщение Dec 14 2016, 21:27
Сообщение #7





Группа: Новичок
Сообщений: 4
Регистрация: 14-12-16
Пользователь №: 94 629



так он даже не заходит в обработку прерывания;
void USB_LP_CAN1_RX0_IRQHandler(void) {
GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);
}
светодиод на PA2 не включает
включил дебагер на ST-LINK, как только оправляешь сообщение он на дебаггер уже не реагирует
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 15 2016, 06:27
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (lau-de @ Dec 14 2016, 23:27) *
как только оправляешь сообщение он на дебаггер уже не реагирует
Как это? Даже нельзя остановиться и посмотреть, куда занесло ядро и что лежит в регистрах периферии? Какие-то сообщения об ошибках появляются?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
lau-de
сообщение Dec 17 2016, 02:20
Сообщение #9





Группа: Новичок
Сообщений: 4
Регистрация: 14-12-16
Пользователь №: 94 629



надо было просто вместо общего startup_stm32f30x.s использовать startup_stm32f334x8.s
всё заработало, всем всё равно спасибо sm.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 15:39
Рейтинг@Mail.ru


Страница сгенерированна за 0.01449 секунд с 7
ELECTRONIX ©2004-2016