Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2022-янв-22 18:07

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 8 сообщений ] 
Автор Сообщение
 Заголовок сообщения: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-28 01:00 
Не в сети

Зарегистрирован: 2020-май-28 00:41
Сообщения: 7
Организация: Частное лицо
Пробую сделать прерывание по приему кадра (кадр отправляю с внешнего устройства), в отладчике вижу, что в буфер приходит пакет, но прерывание не приходит, код приложен ниже. Пробовал копировать таблицу векторов в 0x08000000, не помогло
#include "MDR32F9Qx_can.h"
#include "MDR32Fx.h"                    
#include "MDR32F9Qx_port.h"             
#include "MDR32F9Qx_rst_clk.h"
CAN_InitTypeDef CANInitStruct;
CAN_TxMsgTypeDef tx_frame;
CAN_RxMsgTypeDef rx_frame;
PORT_InitTypeDef PortInit;
void setup_port(void){
	PortInit.PORT_Pin = PORT_Pin_6; //6 номер пина
	PortInit.PORT_OE = PORT_OE_OUT; //порт настроен на выход  
	PortInit.PORT_FUNC= PORT_FUNC_ALTER; //альтернативная функция порта
	PortInit.PORT_MODE = PORT_MODE_DIGITAL; //цифровой режим 
	PortInit.PORT_SPEED = PORT_SPEED_FAST; //быстрая скорость питания
	PORT_Init(MDR_PORTA, &PortInit); //инициальзируем порт 
	PortInit.PORT_Pin = PORT_Pin_7; //7 номер пина
	PortInit.PORT_OE = PORT_OE_IN; //порт настроен на вход
	PortInit.PORT_FUNC= PORT_FUNC_ALTER; //альтернативная функция порта
	PortInit.PORT_MODE = PORT_MODE_DIGITAL; //цифровой режим
	PortInit.PORT_SPEED = PORT_SPEED_FAST; //быстрая скорость питания
	PORT_Init(MDR_PORTA, &PortInit); //инициальзируем порт 
}
void setup_can(void){
	CAN_DeInit(MDR_CAN1);
	MDR_RST_CLK->CAN_CLOCK |=(1<<24);
	CANInitStruct.CAN_ROP = DISABLE; // Прием собственных пакетов отключено
	CANInitStruct.CAN_SAP = DISABLE; // Подтверждение приема отключенособственных кадров 
	CANInitStruct.CAN_STM = DISABLE; // Режим самотестирования отключен
	CANInitStruct.CAN_ROM = DISABLE; // Режим "только чтение" отключен
	CANInitStruct.CAN_PSEG = CAN_PSEG_Mul_2TQ; // Битовый сегмент. Длительность PS
	CANInitStruct.CAN_SEG1 = CAN_SEG1_Mul_4TQ; // Битовый сегмент. Длительность PBS1 
	CANInitStruct.CAN_SEG2 = CAN_SEG2_Mul_1TQ; // Битовый сегмент. Длительность PBS2 
	CANInitStruct.CAN_SJW = CAN_SJW_Mul_2TQ; // Интервал перестройки сегментов 
	CANInitStruct.CAN_SB = CAN_SB_1_SAMPLE; // Режим выборки 
	CANInitStruct.CAN_BRP = 1; // Предделитель тактовой частоты 
	CANInitStruct.CAN_OVER_ERROR_MAX = 255; // Максимальное значение счетчика ошибок до установки флага 
	CAN_Init(MDR_CAN1, &CANInitStruct); //инициальзируем модуль CAN
}
void setup_irq(void){
	CAN_BufferRelease(MDR_CAN1, 6);
	CAN_ITConfig(MDR_CAN1, CAN_IT_GLBINTEN, ENABLE); //GLB_INT_EN = 1
	CAN_ITConfig(MDR_CAN1, CAN_IT_RXINTEN, ENABLE); //RX_INT_EN = 1
	CAN_Receive(MDR_CAN1, 6, ENABLE); // CAN_RX = 1
	CAN_RxITConfig(MDR_CAN1, 6, ENABLE); // CAN_INT_RX = 1
	NVIC_EnableIRQ(CAN1_IRQn);
	__enable_irq();
}
void CAN1_IRQHandler(void){
	tx_frame.PRIOR_0 = 1;
	tx_frame.IDE = CAN_ID_STD;
	tx_frame.ID = 0x001;
	tx_frame.DLC = 3;
	tx_frame.Data[0] = 0x00000ABC;
	tx_frame.Data[1] = 0x00000000;
	CAN_BufferRelease(MDR_CAN1, 5);
	CAN_Transmit(MDR_CAN1, 5, &tx_frame);
	NVIC_ClearPendingIRQ(CAN1_IRQn);
}
int main(void){
	MDR_RST_CLK->PER_CLOCK = 0xFFFFFFFF; //тактируем все
	SCB->VTOR=0x08000000; //копируем таблицу векторов
	__disable_irq(); 
	setup_port(); // настраиваем порт
	setup_can(); // настраиваем кан 
	setup_irq(); //включаем прерывания
	CAN_Cmd(MDR_CAN1, ENABLE); //включаем модуль CAN
	while(1);
}


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-28 10:59 
Не в сети

Зарегистрирован: 2010-авг-30 19:12
Сообщения: 555
Переносить таблицу нет смысла, при старте программы она уже там (это работа загрузчика от производителя).
1.Рекомендую сравнить имя функции-обработчика прерывания CAN1_IRQHandler с указанным в таблице в файле startup.s03 Различия в имени (в том числе в регистре верхний/нижний) приводит к неправильной линковке.
2.После приема данных проверить отладчиком содержимое регистров - то есть что все флаги, разрешения и проч выставлены. CAN - вроде не из того набора переферии, что при чтении (в том числе отладчиком) сбрасывает часть флагов.


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-28 13:43 
Не в сети

Зарегистрирован: 2020-май-28 00:41
Сообщения: 7
Организация: Частное лицо
редактор писал(а): *
Переносить таблицу нет смысла, при старте программы она уже там (это работа загрузчика от производителя).
1.Рекомендую сравнить имя функции-обработчика прерывания CAN1_IRQHandler с указанным в таблице в файле startup.s03 Различия в имени (в том числе в регистре верхний/нижний) приводит к неправильной линковке.
2.После приема данных проверить отладчиком содержимое регистров - то есть что все флаги, разрешения и проч выставлены. CAN - вроде не из того набора переферии, что при чтении (в том числе отладчиком) сбрасывает часть флагов.
1)Проверил имя обработчика - оно совпадает с именем в файле startup/
2)Проверил все флаги работают, флаг о том, что в буфер пришло сообщение тоже работает.


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-28 16:48 
Не в сети

Зарегистрирован: 2009-сен-21 12:39
Сообщения: 598
В своём коде после настройки и разрешения прерываний CAN вызовите функцию NVIC_SetPendingIRQ(CAN1_IRQn). При нормальной настройке должны попасть в обработчик, если нет, то ищите чего не хватает в настройках.


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-28 18:56 
Не в сети

Зарегистрирован: 2020-май-28 00:41
Сообщения: 7
Организация: Частное лицо
ЧумА писал(а): *
В своём коде после настройки и разрешения прерываний CAN вызовите функцию NVIC_SetPendingIRQ(CAN1_IRQn). При нормальной настройке должны попасть в обработчик, если нет, то ищите чего не хватает в настройках.
Вызвал данную функции, обработчик вызвался один раз именно на этой команде, по приему так и не работает прерывание.


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-29 02:00 
Не в сети

Зарегистрирован: 2020-май-28 00:41
Сообщения: 7
Организация: Частное лицо
Проблема решена. Не взводился флаг RX_READY, хотя флаг RX_FULL у буфера был взведен. Проблема в неправильной работе команды
Цитата:
CAN_RxITConfig(MDR_CAN1, 6, ENABLE); // CAN_INT_RX = 1
при замене ее на
MDR_CAN1->INT_RX |= (1<<6);
контроллер начал корректно обрабатывать прерывания.


Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-30 01:33 
Не в сети

Зарегистрирован: 2018-мар-18 15:49
Сообщения: 276
Организация: StartMilandr.ru
MDR32F9Qx_can.с:
@param  Buffer_IT: specifies the reception buffers to enable or disable interrupts of.
  *         Each buffer is designated by bit number in the mask. See @CAN_Buffer_Interrupts
  *         group.

void CAN_RxITConfig(MDR_CAN_TypeDef* CANx, uint32_t Buffer_IT, FunctionalState NewState)
{
  uint32_t tmpreg;

  tmpreg = CANx->INT_RX;

  if (NewState != DISABLE)
  {
    tmpreg |= Buffer_IT;
  }
  else
  {
    tmpreg &= ~Buffer_IT;
  }

  CANx->INT_RX = tmpreg;
}
MDR32F9Qx_can.h:
/** @defgroup CAN_Buffer_Interrupts CAN Buffer Interrupts
  * @{
  */

#define CAN_BUFFER_0               (((uint32_t)0x1) <<  0)
#define CAN_BUFFER_1               (((uint32_t)0x1) <<  1)
#define CAN_BUFFER_2               (((uint32_t)0x1) <<  2)
...



Вернуться к началу
 Заголовок сообщения: Re: Не работает прерывание по CAN
СообщениеДобавлено: 2020-май-30 21:05 
Не в сети

Зарегистрирован: 2018-янв-05 23:41
Сообщения: 375
Организация: ФГУП "РФЯЦ-ВНИИЭФ"
danil_rom писал(а): *
Проблема в неправильной работе команды
Проблема в неправильном использовании функции :)
Параметр надо задавать в виде битовой маски (1<<6) или, как и задумывалось программистами, именованными константами: CAN_BUFFER_6.


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 8 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 7 гостей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти: 

cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB