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

Проблема с CAN.

CAN не принимает данные.

У меня внешний кристал 10М. Поэтому

/*  PLL configuration: PLLCLK = HSE * 7 = 70 MHz */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL7);

Исходя из этого настраиваю CAN baud rate 125kBit

static void CAN_Config(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 NVIC_InitTypeDef  NVIC_InitStructure;
 CAN_InitTypeDef		CAN_InitStructure;
 CAN_FilterInitTypeDef  CAN_FilterInitStructure;

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

 /* Enable GPIO clock */
 RCC_AHBPeriphClockCmd(CAN_GPIO_CLK, ENABLE);

 /* Connect CAN pins to AF7 */
 GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
 GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT); 

 /* Configure CAN RX and TX pins */
 GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
 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(CAN_GPIO_PORT, &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);

 /* CAN configuration ********************************************************/  
 /* Enable CAN clock */
 RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

 /* CAN register init */
 CAN_DeInit(CANx);
 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 = DISABLE;
 CAN_InitStructure.CAN_RFLM = DISABLE;
 CAN_InitStructure.CAN_TXFP = DISABLE;
 CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

  //70 / ((3+7+10) * 28) = 125000
 CAN_InitStructure.CAN_SJW = 3;

 CAN_InitStructure.CAN_BS1 = 10;
 CAN_InitStructure.CAN_BS2 = 7;
 CAN_InitStructure.CAN_Prescaler = 28;
 CAN_Init(CANx, &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 = 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);

 /* Transmit Structure preparation 
 TxMessage.StdId = 0x321;
 TxMessage.ExtId = 0x01;
 TxMessage.RTR = CAN_RTR_DATA;
 TxMessage.IDE = CAN_ID_STD;
 TxMessage.DLC = 1;  */

 /* Enable FIFO 0 message pending Interrupt */
  CAN1->IER |= CAN_IER_FMPIE0 | CAN_IER_ERRIE | CAN_IER_BOFIE | CAN_IER_EPVIE;
 //CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}

Запускаю утилиту CAN Monitor и посылаю пакет. На скопе вижу сигнал а прерывание не происходит.

void USB_LP_CAN1_RX0_IRQHandler(void)
{
//FIFO Overrun error
if (CAN1->RF0R & CAN_RF0R_FOVR0)
{
	CAN1->RF0R &= ~CAN_RF0R_FOVR0;
	CAN1->RF0R |= CAN_RF0R_RFOM0;   /* release FIFO */
	return;
}

//FIFO Full - ready to read data
if (CAN1->RF0R & CAN_RF0R_FULL0)
{
	CAN1->RF0R &= ~CAN_RF0R_FULL0;
	can_idx=0;
	while (CAN1->RF0R & CAN_RF0R_FMP0)
	{
		memcpy(can_rx_packet+can_idx, (uint8_t *) &CAN1->sFIFOMailBox[0].RDLR, 4);
		can_idx += 4;
		memcpy(can_rx_packet+can_idx, (uint8_t *) &CAN1->sFIFOMailBox[0].RDHR, 4);
		can_idx += 4;

		CAN1->RF0R |= CAN_RF0R_RFOM0;	/* release FIFO to read next message */
	}

	data_ready = 1;
}

Где может быть проблема?

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

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


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

CAN_InitStructure.CAN_BS1 = 10;

CAN_InitStructure.CAN_BS2 = 7;

 

А это нормальная конфигурация?

Просто обычно sample point все таки в 87.5 или 75% должна быть...

Хотя 60% в принципе допустимо...

 

 

 

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


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

CAN_InitStructure.CAN_BS1 = 10;

CAN_InitStructure.CAN_BS2 = 7;

 

А это нормальная конфигурация?

Просто обычно sample point все таки в 87.5 или 75% должна быть...

Хотя 60% в принципе допустимо...

я не уверен что я правильно конфигурирую baud rate. я пользуюсь формулой baud rate = F / ((sjw + bs1 + bs2) * bpr) не уверен что она правильная.

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


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

CAN не принимает данные.

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

Где может быть проблема?

 

Несовпадение скоростей

1) ко всем значениям сегментов фазы 1 и 2 и предделителя надо учитывать еще +1 типа BS1=3,-значит на самом деле он равен 4..

2) каков предделитель на шину APB1 с которой тактируется CAN?...от нее и считается предделитель

 

По своему опыту-выбирайте PLL для проектов с CAN кратно 16 МГц, большой диапазон скоростей и совместимости с другими устройствами

 

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


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

Несовпадение скоростей

1) ко всем значениям сегментов фазы 1 и 2 и предделителя надо учитывать еще +1 типа BS1=3,-значит на самом деле он равен 4..

2) каков предделитель на шину APB1 с которой тактируется CAN?...от нее и считается предделитель

 

По своему опыту-выбирайте PLL для проектов с CAN кратно 16 МГц, большой диапазон скоростей и совместимости с другими устройствами

у меня стоит осцилятор 10М на плате. поэтому я выираю RCC_CFGR_PLLMULL7 что дает мне 70М. попробую сейчас +1.

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


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

у меня стоит осцилятор 10М на плате. поэтому я выираю RCC_CFGR_PLLMULL7 что дает мне 70М. попробую сейчас +1.

Дело не в осцилляторе на плате,а в частоте шины APB1

 

к примеру PLL=96 MHz...выбираем делитель APB1=4 получаем 24 Мгц...тогда 24000000/125000=192

то есть получаем (1+BS1+1+BS2+1)*(prescaler+1)=192

соотношение BS2/BS1 должно быть ое 2\3 до 3\4...ну типа 66..75%

 

ну на самом деле не важна PLL важно понимание формулы расчета..как получит PLL,прекрасно описано в мануале на микроконтроллер

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


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

Дело не в осцилляторе на плате,а в частоте шины APB1

 

к примеру PLL=96 MHz...выбираем делитель APB1=4 получаем 24 Мгц...тогда 24000000/125000=192

то есть получаем (1+BS1+1+BS2+1)*(prescaler+1)=192

соотношение BS2/BS1 должно быть ое 2\3 до 3\4...ну типа 66..75%

 

ну на самом деле не важна PLL важно понимание формулы расчета..как получит PLL,прекрасно описано в мануале на микроконтроллер

спасибо. вроде понял. :)

 

а что SJW в формуле не учитывается?

Изменено пользователем Jenya7

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


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

спасибо. вроде понял. :)

 

а что SJW в формуле не учитывается?

не учитывается!

SJW должен быть <= BS2, обычно он равен (4 - 1) = 3

 

 

соотношение BS2/BS1 должно быть ое 2\3 до 3\4...ну типа 66..75%

можно и так считать,

но формально позиция sample point

(1+BS1+1)/(1+BS1+1+BS2+1) = от 0.5 до 0.9

но обычно используют 0.75 или 0.875

 

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


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

для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов

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


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

лучше использовать CubeMX или программки вроде CAN-калькуляторов
Чем лучше? Предстоит погрузиться в тему CAN, хотелось бы заранее узнать о нюансах.

 

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


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

для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов

Тут наверное следует добавить: Если опыта маловато или документацию плохо изучили или принципы работы CAN туманны...

 

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


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

Чем лучше? Предстоит погрузиться в тему CAN, хотелось бы заранее узнать о нюансах.

лучше тем, что в CubeMX для конфигурации временных параметров CAN bus

применяетмя некое подобие калькулятора и при выборе параметров

CAN трудно ошибиться

 

Тут наверное следует добавить: Если опыта маловато или документацию плохо изучили или принципы работы CAN туманны...

даже если много опыта и большое желание почитать документацию, то сделать например

ремап пинов и инициализацию для случая CAN bus например для STM32F042F4 получится

с помощью CubeMX намного быстрее и проще...

хотя, если есть желание набраться опыта и почитать докумантацию, а самое главное есть начальство оплачивающее !!!

самообразование разработчика в рабочее время, когда проект должен быть сделан "на вчера"....

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


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

лично я использую следующую формулу для расчёта прескаллера

uint16_t prescaler = clocks.PCLK1_Frequency/((can->definitions.CAN_SJW + 1 + can->definitions.CAN_BS1 + 1 + can->definitions.CAN_BS2 + 1) * can->baudrate);

 

где clocks.PCLK1_Frequency - частота тактирования периферии,

can->definitions.CAN_SJW = CAN_SJW_1tq,

can->definitions.CAN_BS1 = CAN_BS1_10tq,

can->definitions.CAN_BS2 = CAN_BS2_7tq,

can->baudrate - заданная вами частота

 

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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