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

 
 
 
Reply to this topicStart new topic
> Проблема с CAN., STM32F303
Jenya7
сообщение May 4 2016, 13:37
Сообщение #1


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



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;
}

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

Сообщение отредактировал IgorKossak - May 5 2016, 08:18
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
Go to the top of the page
 
+Quote Post
KRS
сообщение May 4 2016, 15:45
Сообщение #2


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



CAN_InitStructure.CAN_BS1 = 10;
CAN_InitStructure.CAN_BS2 = 7;

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


Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 4 2016, 16:01
Сообщение #3


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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) не уверен что она правильная.
Go to the top of the page
 
+Quote Post
romas2010
сообщение May 4 2016, 16:02
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 25-11-11
Пользователь №: 68 515



Цитата(Jenya7 @ May 4 2016, 16:37) *
CAN не принимает данные.
..............
Где может быть проблема?


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

По своему опыту-выбирайте PLL для проектов с CAN кратно 16 МГц, большой диапазон скоростей и совместимости с другими устройствами
Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 4 2016, 16:07
Сообщение #5


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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.
Go to the top of the page
 
+Quote Post
romas2010
сообщение May 4 2016, 16:22
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 25-11-11
Пользователь №: 68 515



Цитата(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,прекрасно описано в мануале на микроконтроллер
Go to the top of the page
 
+Quote Post
Jenya7
сообщение May 5 2016, 06:18
Сообщение #7


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(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 в формуле не учитывается?

Сообщение отредактировал Jenya7 - May 5 2016, 06:21
Go to the top of the page
 
+Quote Post
KRS
сообщение May 5 2016, 09:43
Сообщение #8


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(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
Go to the top of the page
 
+Quote Post
golf2109
сообщение May 9 2016, 04:13
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 15-04-10
Из: Kiev
Пользователь №: 56 654



для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 9 2016, 08:58
Сообщение #10


Гуру
******

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



QUOTE (golf2109 @ May 9 2016, 07:13) *
лучше использовать CubeMX или программки вроде CAN-калькуляторов
Чем лучше? Предстоит погрузиться в тему CAN, хотелось бы заранее узнать о нюансах.


--------------------
На любой вопрос даю любой ответ
"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
amiller
сообщение May 9 2016, 09:25
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Цитата(golf2109 @ May 9 2016, 07:13) *
для установки CAN timing лучше использовать CubeMX или программки вроде CAN-калькуляторов

Тут наверное следует добавить: Если опыта маловато или документацию плохо изучили или принципы работы CAN туманны...
Go to the top of the page
 
+Quote Post
golf2109
сообщение May 11 2016, 01:27
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 66
Регистрация: 15-04-10
Из: Kiev
Пользователь №: 56 654



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

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

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

даже если много опыта и большое желание почитать документацию, то сделать например
ремап пинов и инициализацию для случая CAN bus например для STM32F042F4 получится
с помощью CubeMX намного быстрее и проще...
хотя, если есть желание набраться опыта и почитать докумантацию, а самое главное есть начальство оплачивающее !!!
самообразование разработчика в рабочее время, когда проект должен быть сделан "на вчера"....
Go to the top of the page
 
+Quote Post
Ruslan-maniak
сообщение May 17 2016, 10:36
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 27-12-12
Из: Томск
Пользователь №: 74 999



лично я использую следующую формулу для расчёта прескаллера
Код
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 - заданная вами частота
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 04:03
Рейтинг@Mail.ru


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