Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с CAN.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Jenya7
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
CODE
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 и посылаю пакет. На скопе вижу сигнал а прерывание не происходит.
CODE
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;
}

Где может быть проблема?
KRS
CAN_InitStructure.CAN_BS1 = 10;
CAN_InitStructure.CAN_BS2 = 7;

А это нормальная конфигурация?
Просто обычно sample point все таки в 87.5 или 75% должна быть...
Хотя 60% в принципе допустимо...


Jenya7
Цитата(KRS @ May 4 2016, 20:45) *
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) не уверен что она правильная.
romas2010
Цитата(Jenya7 @ May 4 2016, 16:37) *
CAN не принимает данные.
..............
Где может быть проблема?


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

По своему опыту-выбирайте PLL для проектов с CAN кратно 16 МГц, большой диапазон скоростей и совместимости с другими устройствами
Jenya7
Цитата(romas2010 @ May 4 2016, 21:02) *
Несовпадение скоростей
1) ко всем значениям сегментов фазы 1 и 2 и предделителя надо учитывать еще +1 типа BS1=3,-значит на самом деле он равен 4..
2) каков предделитель на шину APB1 с которой тактируется CAN?...от нее и считается предделитель

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

у меня стоит осцилятор 10М на плате. поэтому я выираю RCC_CFGR_PLLMULL7 что дает мне 70М. попробую сейчас +1.
romas2010
Цитата(Jenya7 @ May 4 2016, 19:07) *
у меня стоит осцилятор 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,прекрасно описано в мануале на микроконтроллер
Jenya7
Цитата(romas2010 @ May 4 2016, 21:22) *
Дело не в осцилляторе на плате,а в частоте шины 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,прекрасно описано в мануале на микроконтроллер

спасибо. вроде понял. sm.gif

а что SJW в формуле не учитывается?
KRS
Цитата(Jenya7 @ May 5 2016, 09:18) *
спасибо. вроде понял. sm.gif

а что 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
golf2109
для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов
Сергей Борщ
QUOTE (golf2109 @ May 9 2016, 07:13) *
лучше использовать CubeMX или программки вроде CAN-калькуляторов
Чем лучше? Предстоит погрузиться в тему CAN, хотелось бы заранее узнать о нюансах.
amiller
Цитата(golf2109 @ May 9 2016, 07:13) *
для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов

Тут наверное следует добавить: Если опыта маловато или документацию плохо изучили или принципы работы CAN туманны...
golf2109
Цитата(Сергей Борщ @ May 9 2016, 11:58) *
Чем лучше? Предстоит погрузиться в тему CAN, хотелось бы заранее узнать о нюансах.

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

Цитата(amiller @ May 9 2016, 12:25) *
Тут наверное следует добавить: Если опыта маловато или документацию плохо изучили или принципы работы CAN туманны...

даже если много опыта и большое желание почитать документацию, то сделать например
ремап пинов и инициализацию для случая CAN bus например для STM32F042F4 получится
с помощью CubeMX намного быстрее и проще...
хотя, если есть желание набраться опыта и почитать докумантацию, а самое главное есть начальство оплачивающее !!!
самообразование разработчика в рабочее время, когда проект должен быть сделан "на вчера"....
Ruslan-maniak
лично я использую следующую формулу для расчёта прескаллера
Код
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 - заданная вами частота
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.