LEXIS 0 23 февраля, 2015 Опубликовано 23 февраля, 2015 · Жалоба Есть контроллер STM32F103C6, инициализирую CAN модуль на скорость 500 кб/с. На этой скорости работает. Потом по CAN шине приходит команда на смену скорости - меняю, например, на 600 кб/с. - не работает, хотя если принудительно задать эту скорость изначально - то работает. Как правильно надо менять скорость во время работы. Функция настройки скорости ниже (опущена инициализация портов, фильтров и прерываний): 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 0 23 февраля, 2015 Опубликовано 23 февраля, 2015 · Жалоба Изначально шина задумана так, что скорость в ней одинакова для всех устройств. Когда ID-шников не хватает, используют 29 bit. Если есть устройста, работающие на другой скорости, ставится шлюз gateway. Так для примера: есть N устройств, работающих по UART, там кто меняет скорость во время обмена? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 23 февраля, 2015 Опубликовано 23 февраля, 2015 · Жалоба Работающий CAN нужно перевести в режим инициализации, поменять настройки и снова включить в Normal mode. пункт "24.4.1 Initialization mode" в реф. мануале. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LEXIS 0 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба Если есть устройста, работающие на другой скорости, ставится шлюз 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 0 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба а если сохранить желаемую скорость во флешке и перегрузиться? я так понимаю смена скорости процесс не постоянный, случаи с настройкой прибора метод с перезагрузкой устраивает полностью. А в боевом режиме, скорее тоже подойдет... зато безопасно и работоспособно 100% Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prgjz 0 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба А обратно? CAN->MCR &= ~CAN_MCR_INRQ; // в нормальный модус Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LEXIS 0 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба CAN->MCR &= ~CAN_MCR_INRQ; // в нормальный модус Это делается в CAN_Init(CANx, &CAN_InitStructure); а если сохранить желаемую скорость во флешке и перегрузиться? вапиант хороший, а как програмно сделать рестарт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба книжку надо читать как в стм это делается. но в любом случае можно и вочь дог дернуть) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба Устроить ресет процессору можно функцией NVIC_SystemReset() из core_cm3.h или напрямую записью в регистр SCB->AIRCR. Но можно сделать ресет и персонально для CAN через регистр RCC->_APB1RSTR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 25 февраля, 2015 Опубликовано 25 февраля, 2015 · Жалоба а если сохранить желаемую скорость во флешке и перегрузиться? С ума посходили. Оно и так нормально работает: initialization mode, настройка регистров, normal mode. У нас STM32F4xx, но не думаю, что там какие-то отличия... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LEXIS 0 28 февраля, 2015 Опубликовано 28 февраля, 2015 · Жалоба Спасибо запомощь, проблему решил следующим образом: Остановил прерывания, изменил скорость, разрешил заново прерывания. Может из-за этого не работало, но теперь скорость можно менять налету. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться