Arlleex 131 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба Приветствую! Поделитесь, пожалуйста, адекватным калькулятором битовой скорости CAN 2.0B. Перепробовал кучу - во всех разные косяки: какие-то не могут расчитать для < 50кбит/с, какие-то просто не работают. Нужно получить таблицу настроек скоростей, поэтому под рукой хотелось бы иметь удобный калькулятор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба 1 час назад, Arlleex сказал: Нужно получить таблицу настроек скоростей, поэтому под рукой хотелось бы иметь удобный калькулятор. Вы бы хоть указали для какого МК.... А то у меня в XMC4xxx как-то так: Скрытый текст #define CLKKIT2(tseg1, tseg2) \ ((((tseg2 > 4) ? 3: tseg2 - 2) | tseg1 - 1 << 2 | tseg2 - 1 << 6) * \ assert_static(1 + tseg1 + tseg2 > 7 && tseg1 > 2 && tseg1 < 17 && tseg2 > 1 && tseg2 < 9)) #define CLKKIT(tq) CLKKIT2(tq) //CAN.NODE[].BTR: TSEG1, TSEG2 #define BIT_TQ_12 7, 4 #define BIT_TQ_13 8, 4 #define BIT_TQ_15 10, 4 #define BIT_TQ_16 10, 5 #define BIT_TQ_18 11, 6 #define BIT_TQ_20 13, 6 #define BIT_TQ_22 14, 7 #define BIT_TQ_24 15, 8 #define BIT_TQ_25 16, 8 #define FDR_STEP_72000000 4 #define FDR_STEP_80000000 4 #define FDR_STEP_100000000 5 #define FDR_STEP_108000000 9 #define FDR_STEP_120000000 6 #define FDR_STEP_128000000 8 #define FDR_STEP_132000000 11 #define FDR_STEP_140000000 7 #define FDR_STEP_144000000 9 //наборы для инициализации CAN.NODE[].BTR для разных PBCLK_MH #define CANCLKKIT_1M0_72000000 CLKKIT(BIT_TQ_18) #define CANCLKKIT_1M0_80000000 CLKKIT(BIT_TQ_20) #define CANCLKKIT_1M0_100000000 CLKKIT(BIT_TQ_20) #define CANCLKKIT_1M0_108000000 CLKKIT(BIT_TQ_12) #define CANCLKKIT_1M0_120000000 CLKKIT(BIT_TQ_20) #define CANCLKKIT_1M0_128000000 CLKKIT(BIT_TQ_16) #define CANCLKKIT_1M0_132000000 CLKKIT(BIT_TQ_12) #define CANCLKKIT_1M0_140000000 CLKKIT(BIT_TQ_20) #define CANCLKKIT_1M0_144000000 CLKKIT(BIT_TQ_16) #define CANCLKKIT_0M8_72000000 CLKKIT(BIT_TQ_18) #define CANCLKKIT_0M8_80000000 CLKKIT(BIT_TQ_25) #define CANCLKKIT_0M8_100000000 CLKKIT(BIT_TQ_25) #define CANCLKKIT_0M8_108000000 CLKKIT(BIT_TQ_15) #define CANCLKKIT_0M8_120000000 CLKKIT(BIT_TQ_25) #define CANCLKKIT_0M8_128000000 CLKKIT(BIT_TQ_20) #define CANCLKKIT_0M8_132000000 CLKKIT(BIT_TQ_15) #define CANCLKKIT_0M8_140000000 CLKKIT(BIT_TQ_25) #define CANCLKKIT_0M8_144000000 CLKKIT(BIT_TQ_20) #define CLKKIT_SELECT(pbclk, base) ( \ (pbclk == 144000000) ? CANCLKKIT_##base##_144000000: \ (pbclk == 140000000) ? CANCLKKIT_##base##_140000000: \ (pbclk == 132000000) ? CANCLKKIT_##base##_132000000: \ (pbclk == 128000000) ? CANCLKKIT_##base##_128000000: \ (pbclk == 120000000) ? CANCLKKIT_##base##_120000000: \ (pbclk == 108000000) ? CANCLKKIT_##base##_108000000: \ (pbclk == 100000000) ? CANCLKKIT_##base##_100000000: \ (pbclk == 80000000) ? CANCLKKIT_##base##_80000000: \ (pbclk == 72000000) ? CANCLKKIT_##base##_72000000: \ assert_static(0)) #define FDR_STEP(pbclk) ( \ (pbclk == 144000000) ? FDR_STEP_144000000: \ (pbclk == 140000000) ? FDR_STEP_140000000: \ (pbclk == 132000000) ? FDR_STEP_132000000: \ (pbclk == 128000000) ? FDR_STEP_128000000: \ (pbclk == 120000000) ? FDR_STEP_120000000: \ (pbclk == 108000000) ? FDR_STEP_108000000: \ (pbclk == 100000000) ? FDR_STEP_100000000: \ (pbclk == 80000000) ? FDR_STEP_80000000: \ (pbclk == 72000000) ? FDR_STEP_72000000: \ assert_static(0)) #define TQ_SJW(clkkit) (((clkkit) >> 0 & 3) + 1) #define TQ_TSEG1(clkkit) (((clkkit) >> 2 & 15) + 1) #define TQ_TSEG2(clkkit) (((clkkit) >> 6 & 7) + 1) __packed struct CfgCan { //конфиг CAN enum { //[бод] возможные скорости RATE_1M, RATE_800K, RATE_500K, RATE_250K, RATE_200K, RATE_125K, RATE_100K, RATE_62K5, RATE_50K, RATE_40K, RATE_n}; ... }; static u32 const canRates[] = {1000000, 800000, 500000, 250000, 200000, 125000, 100000, 62500, 50000, 40000}; ... static void CanOn(CfgMain const *cfg, int ix) { enum {CLKKIT_0M8 = CLKKIT_SELECT(PBCLK_MH, 0M8), CLKKIT_1M0 = CLKKIT_SELECT(PBCLK_MH, 1M0)}; uint i, i1, rate; canCurRate[ix] = rate = cfg->can.port[ix].baud; HwRegsCAN::T_NODE volatile *node = &CAN.NODE[(ix == CfgCan::IX_INT) ? nCAN_int: nCAN_ext]; node->CR = B0 | B6; u32 j = PBCLK_MH / FDR_STEP(PBCLK_MH) / (1 + TQ_TSEG1(CLKKIT_1M0) + TQ_TSEG2(CLKKIT_1M0)); i = CLKKIT_1M0; if (rate == CfgCan::RATE_800K) { j = PBCLK_MH / FDR_STEP(PBCLK_MH) / (1 + TQ_TSEG1(CLKKIT_0M8) + TQ_TSEG2(CLKKIT_0M8)); i = CLKKIT_0M8; } node->BTR = j / canRates[rate] - 1 | i << 6; node->SR = 0; node->ECNT = 96 << 16; node->FCR = 3 << 19; ... но что-то сомневаюсь, что Вам поможет... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба STM32F4. К сожалению, выяснил, что 800кбит/с не получится задать при своей частоте шины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба На XMC4xxx можно и 1000кбод и 800кбод хоть на 144МГц хоть на 120МГц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 16 февраля, 2022 Опубликовано 16 февраля, 2022 · Жалоба 2 часа назад, jcxz сказал: На XMC4xxx можно и 1000кбод и 800кбод хоть на 144МГц хоть на 120МГц. Ну, в свой девайс лапы в лапы XMC4 вместо STM32 я не запаяю В XMC, как я понял, есть дробный предделитель на входе baudrate-делителя CAN-периферии. В моем случае я просто откажусь от реализации данной битовой скорости (позволительно). Вообще у меня список скоростей из 10к-, 20к-, 50к-, 100к-, 125к-, 250к-, 500к-, 800к- и 1000кбит/с. Все получил, кроме 800. Можно, конечно, частотой APB поиграться, но что-то уже лень. Глядишь, какая-нибудь другая битовая скорость отвалится Пока что, в общем, отложу этот вопрос на попозже. Может и реализую. P.S. А вообще, мудреный он, этот XMC. Гибкий это, конечно, да, но на фоне других МК "поднять UART за 10 минут" не получится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 17 февраля, 2022 Опубликовано 17 февраля, 2022 · Жалоба Цитата Все получил, кроме 800. Если тактовая 72 МГц - 800К - вроде кратная частота - должно получиться. Я с STM не работал, но вроде принцип у всех похожий, только по регистрам по разному раскидывают. Попробуйте след. метод. 72М/800К = 90 - один бит CAN должен быть 90 тактов кварца. Эти 90 тактов нужно разбить на кванты (Tq) должно получиться от 4 до 24 квантов для целочисленного деления подходят значения 5*18, 9*10, 15*6 Удобнее выбрать пару 18*5 (чем больше сегментов - тем больше вариантов распределения), Тогда предделитель BRP должен быть 5 (в регистр чаще всего записывается N-1) 1 квант - это синхроимпульс (обязательный), оставшиеся 17 квантов нужно распределить по сегментам, Чаще всего увеличивают первые два сегмента, чтобы сместить точку выборки к концу посылки. Как выбирают SJW не помню на вскидку. Не нужно забывать что длина сегментов ограничена (в регистрах либо 3 поля по 3 бита - каждый сегмент от 1 до 8, либо первые 2 сегмента объединяют и тогда первое поле 4 бита от 1 до 16, второе поле от 1 до 8). 17 квантов я бы распределил так 8 - PROP, 6 - SEG1, 3 - SEG2. Точка выборки получается - около 83% (1 - SEG2/18) (или 14 + 3 если первые два сегмента в одно поле) Попробуйте. Удачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 17 февраля, 2022 Опубликовано 17 февраля, 2022 · Жалоба Спасибо конечно, но все это я и сам понимаю. Я не просто так написал Цитата STM32F4. К сожалению, выяснил, что 800кбит/с не получится задать при своей частоте шины. Частота шины APB у меня не может быть произвольной: на нее завязано много чего Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 19 февраля, 2022 Опубликовано 19 февраля, 2022 · Жалоба 16.02.2022 в 18:57, Arlleex сказал: В XMC, как я понял, есть дробный предделитель на входе baudrate-делителя CAN-периферии. Имеется, но я его не использую. Так как он задаёт общую частоту для всех CAN-интерфейсов МК, а они у меня в устройстве работают на независимых скоростях. Да и без дробного нормально получается - не нужен он для 1000 / 800 кбод. При старте ПО: CAN.FDR = 1 << 14 | 1024 - FDR_STEP(PBCLK_MH); { u32 dummy = CAN.FDR; } и больше CAN.FDR не трогается. Не зависимо от изменения bitrate на любом CAN-интерфейсе. Цитата Вообще у меня список скоростей из 10к-, 20к-, 50к-, 100к-, 125к-, 250к-, 500к-, 800к- и 1000кбит/с. Все получил, кроме 800. Можно, конечно, частотой APB поиграться, но что-то уже лень. Глядишь, какая-нибудь другая битовая скорость отвалится А я получил и 1000 и 800 и все производные вниз от 1000. При одной и той частоте периферийной шины (у меня это PBCLK_MH). Я специально привёл кусок инициализации CAN-интерфейса где это делаю. Со всеми макросами. Но Вы похоже не смотрели его. Конкретно: расчёт содержимого node->BTR (CAN_NBTRx). Ничего там сложного нет. И не дробный делитель не нужен, ни менять частоту шины тоже не нужно. По-крайней мере в XMC с евойным CAN_NBTRx. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 19 февраля, 2022 Опубликовано 19 февраля, 2022 · Жалоба 9 часов назад, jcxz сказал: А я получил и 1000 и 800 и все производные вниз от 1000. При одной и той частоте периферийной шины (у меня это PBCLK_MH). Частота APB у меня 42МГц. 42/0.8 = 52.5 -> не целое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 19 февраля, 2022 Опубликовано 19 февраля, 2022 · Жалоба 1 час назад, Arlleex сказал: Частота APB у меня 42МГц. 42/0.8 = 52.5 -> не целое. Ну так поменять её на 40 или 44 или любую другую, кратную 4МГц. Неужели так сложно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться