CANTX на ноге микроконтроллёра всегда держит 3.3В и только в момент передачи прижимает её к земле. Нога ISO1050, подключенная к ноге CANRX микроконтроллёра, всегда держит 4.5В и в момент приёма данных, прижимает её к земле.
На CAN шине, т.е. после интерфейса ISO1050, всё немного меняется. Сигнал передаётся в виде двух компонентов, H и L. При отсутствии пакетов на шине, оба компонента держатся на уровне 2.5В, формируя «нуль». При сигнале, H компонент возрастает относительно «нуля», а L компонент падает, позволяя нам увидеть вот такую картинку.
Разрешаем использование CAN в mcuconf.h
:
#define STM32_CAN_USE_CAN1 TRUE #define STM32_CAN_CAN1_IRQ_PRIORITY 11
Разрешаем использование CAN в halconf.h
:
#define HAL_USE_CAN TRUE #define CAN_USE_SLEEP_MODE TRUE
Рассмотрим случай, когда используется CAN на альтернативных выводах, т.е. на PB8 и PB9. Настраиваю его так:
#define VAL_GPIOBCRH 0x......B8
Кроме этого, надо указать, что CAN переопределён на альтернативные выводы:
void boardInit(void) { AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE | AFIO_MAPR_CAN_REMAP_REMAP2; }
А JTAG я всегда выключаю :)
Из документации (страница 645 RM0008) известно следующее:
BaudRate = 1 / NominalBitTime NominalBitTime = 1 * (tq + tBS1 + tBS2) где: tBS1 = tq * (TS1[3:0] + 1), tBS2 = tq * (TS2[2:0] + 1), tq = (BRP[9:0] + 1) x tPCLK, tPCLK = длительность одного цикла шины APB, BRP[9:0], TS1[3:0] и TS2[2:0] определены в регистре CAN_BTR.
В лоб делаем функцию вычисления скорости передачи по имеющимся параметрам:
def can_baud_rate(apb1, brp, ts1, ts2): Tpclk = 1 / apb1 Tq = (brp + 1) * Tpclk Tbs1 = (ts1 + 1) * Tq Tbs2 = (ts2 + 1) * Tq Tbit = 1 * Tq + Tbs1 + Tbs2 rate = 1 / Tbit return rate
Немного оптимизировав, получаем:
def optimized_can_baud_rate(apb1, brp, ts1, ts2): return apb1 / ((1 + brp) * (3 + ts1 + ts2))
Ещё есть онлайн калькулятор для параметров CAN пакета.
Конфигурационные параметры:
CAN_BTR_BRP(n)
- длительность кванта, n = [0..511];CAN_BTR_TS1(n)
- длительность до sample point, n = [1..16];CAN_BTR_TS2(n)
- длительность до transmit point, n = [1..8];CAN_BTR_SJW(n)
- длительность ресинхронизации, n = [1..4].