Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Правильная инициализация CAN в STM32F103
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
LEXIS
Есть контроллер STM32F103C6, инициализирую CAN модуль на скорость 500 кб/с. На этой скорости работает. Потом по CAN шине приходит команда на смену скорости - меняю, например, на 600 кб/с. - не работает, хотя если принудительно задать эту скорость изначально - то работает. Как правильно надо менять скорость во время работы.
Функция настройки скорости ниже (опущена инициализация портов, фильтров и прерываний):
CODE

void CAN_Config(unsigned int bitrate)//Kbit/sec
{
char BitTimeCAN=0;

CAN_DeInit(CANx);
CAN_StructInit(&CAN_InitStructure);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* 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;

/* CAN Baudrate */
// SetSpeed (bitrate/1000);
switch (bitrate)
{
case 1000: BitTimeCAN = 0;break;
case 950: BitTimeCAN = 1;break;
case 900: BitTimeCAN = 2;break;
case 850: BitTimeCAN = 3;break;
case 800: BitTimeCAN = 4;break;
case 750: BitTimeCAN = 5;break;
case 700: BitTimeCAN = 6;break;
case 650: BitTimeCAN = 7;break;
case 600: BitTimeCAN = 8;break;
case 550: BitTimeCAN = 9;break;
case 500: BitTimeCAN = 10;break;
case 450: BitTimeCAN = 11;break;
case 400: BitTimeCAN = 12;break;
case 350: BitTimeCAN = 13;break;
case 300: BitTimeCAN = 14;break;
case 250: BitTimeCAN = 15;break;
case 200: BitTimeCAN = 16;break;
case 150: BitTimeCAN = 17;break;
case 125: BitTimeCAN = 18;break;
case 100: BitTimeCAN = 19;break;
case 50: BitTimeCAN = 20;break;
case 10: BitTimeCAN = 21;break;
}

CAN_InitStructure.CAN_SJW = CAN_BTR[BitTimeCAN][0];
CAN_InitStructure.CAN_BS1 = CAN_BTR[BitTimeCAN][1];
CAN_InitStructure.CAN_BS2 = CAN_BTR[BitTimeCAN][2];
CAN_InitStructure.CAN_Prescaler = CAN_BTR[BitTimeCAN][3];
CAN_Init(CANx, &CAN_InitStructure);

}


Именно эта функция вызывает смену скорости.
pavel-pervomaysk
Изначально шина задумана так, что скорость в ней одинакова для всех устройств.
Когда ID-шников не хватает, используют 29 bit.

Если есть устройста, работающие на другой скорости, ставится шлюз gateway.

Так для примера: есть N устройств, работающих по UART, там кто меняет скорость во время обмена?
SSerge
Работающий CAN нужно перевести в режим инициализации, поменять настройки и снова включить в Normal mode.
пункт "24.4.1 Initialization mode" в реф. мануале.
LEXIS
Цитата
Если есть устройста, работающие на другой скорости, ставится шлюз gateway.

Смысл изменения скорости не в том, чтобы соединить разноскоростные устройства, а для тонкой настройки по месту, например, при шумном канале уменьшать скорость. При этом изменение скорости будет происходить для всех устройств одновременно. Либо настраивать запрограммированное устройство на другую скорость.

Цитата
"24.4.1 Initialization mode"

В моем мануале это 23.4.1. или у Вас какой-то другой?

Добавил как написано в мануале
Код
  CAN_DeInit(CANx);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
  CAN1->MCR |= CAN_MCR_INRQ;    // wait while CAN entered to initialization mode    
  while (!(CAN1->MSR & CAN_MSR_INAK));    // CAN to initialization mode
  CAN_StructInit(&CAN_InitStructure);


Как обычно инициализируется, но скорость не переключает.
Golikov A.
а если сохранить желаемую скорость во флешке и перегрузиться?
я так понимаю смена скорости процесс не постоянный, случаи с настройкой прибора метод с перезагрузкой устраивает полностью. А в боевом режиме, скорее тоже подойдет...

зато безопасно и работоспособно 100%
prgjz
А обратно?
CAN->MCR &= ~CAN_MCR_INRQ; // в нормальный модус
LEXIS
Цитата
CAN->MCR &= ~CAN_MCR_INRQ; // в нормальный модус

Это делается в CAN_Init(CANx, &CAN_InitStructure);

Цитата
а если сохранить желаемую скорость во флешке и перегрузиться?

вапиант хороший, а как програмно сделать рестарт?
Golikov A.
книжку надо читать как в стм это делается.

но в любом случае можно и вочь дог дернуть)
SSerge
Устроить ресет процессору можно функцией NVIC_SystemReset() из core_cm3.h
или напрямую записью в регистр SCB->AIRCR.

Но можно сделать ресет и персонально для CAN через регистр RCC->_APB1RSTR.
esaulenka
Цитата(Golikov A. @ Feb 25 2015, 09:35) *
а если сохранить желаемую скорость во флешке и перегрузиться?

С ума посходили.
Оно и так нормально работает: initialization mode, настройка регистров, normal mode.

У нас STM32F4xx, но не думаю, что там какие-то отличия...
LEXIS
Спасибо запомощь, проблему решил следующим образом: Остановил прерывания, изменил скорость, разрешил заново прерывания. Может из-за этого не работало, но теперь скорость можно менять налету.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.