Емельянов Эдуард Владимирович (eddy_em) wrote,
Емельянов Эдуард Владимирович
eddy_em

Category:

Релюшки на CAN-шине


Закончил с прошивкой для новой железяки.

Как "наследница" USB-CAN переходника, она умеет все то же самое + несколько специфичных вещей (опрос четырех кнопок, измерение двух внешних каналов АЦП с напряжениями до 5В и до 12В, оперирование четырьмя внешними светодиодами, управление тремя ШИМ-каналами с заполнением 0..255, управление двумя релюшками). Вот меню доступа по USB:
'0' - turn relay0 on(1) or off(0)
'1' - turn relay1 on(1) or off(0)
'a' - add ID to ignore list (max 10 IDs)
'A' - get ADC values @ all 4 channels
'b' - get buttons' state
'C' - reinit CAN with given baudrate
'd' - delete ignore list
'f' - add/delete filter, format: bank# FIFO# mode(M/I) num0 [num1 [num2 [num3]]]
'F' - send/clear flood message: F ID byte0 ... byteN
'I' - read CAN ID
'l' - list all active filters
'm' - get MCU temp & Vdd
'o' - turn nth LED OFF
'O' - turn nth LED ON
'p' - print ignore buffer
'P' - pause/resume in packets displaying
'R' - software reset
's/S' - send data over CAN: s ID byte0 .. byteN
'T' - get time from start (ms)
'w' - get PWM settings
'W' - set PWM @nth channel (ch: 0..2, PWM: 0..255)

К сожалению, оказалось, что STM32F042 не умеет программный переход в режим DFU: там есть защита, не позволяющая запустить бутлоадер, если в первых 4 байтах флеш-памяти не пусто! А если стереть эту первую страницу, то и МК подыхает... В общем, для прошивки я оставил лишь в режиме DEBUG возможность стереть первую страницу флеш-памяти, чтобы потом, переподключив питание, запустить МК в режиме DFU. Очень уж не хотелось подпаивать временные проводочки для подключения st-link.
При работе с CAN входящий протокол достаточно простой: железяка реагирует на идентификатор, выставленный перемычками на плате. При запуске этот адрес считывается, и нулевой фильтр (пользователю не позволяется его менять или удалять) принимает сообщения с заданным ID. Если получено пустое сообщение, то оно "отпинговывается" обратно, нет — анализируется байт 0 пришедших данных (это — команда). Команда может быть одна из:
typedef enum{
    CAN_CMD_PING,   // ping (without setter)
    CAN_CMD_RELAY,  // relay get/set
    CAN_CMD_PWM,    // PWM get/set
    CAN_CMD_ADC,    // get ADC (without setter)
    CAN_CMD_MCU,    // MCU T and Vdd
    CAN_CMD_LED,    // LEDs get/set
    CAN_CMD_BTNS,   // get Buttons state (without setter)
    CAN_CMD_TMS,    // get time from start (in ms)
    CAN_CMD_ERRCMD, // wrong command
    CAN_CMD_SETFLAG = 0x80 // command is setter
} CAN_commands;

Начиная с кода 8 (CAN_CMD_ERRCMD) команда считается ошибочной (обратно отправляется пакет с одним байтом, где кодом команды является этот самый errcmd). Если в команде установлен старший бит (CAN_CMD_SETFLAG), и она имеет не только геттер, но и сеттер, анализируются следующие байты данных и выполняется соответствующий сеттер (а после все равно вызывается геттер).
Обратный пакет имеет идентификатор, равный 0x100 + CANID, поэтому при совместной работе с CANopen устройствами нужно аккуратно выбирать идентификатор железяки, чтобы случайно что-нибудь не поломать. Если ответом является "pong", то посылается пустой блок данных. Если нет, байт 0 содержит полученную команду (с уже очищенным флагом-сеттером).
Большинство команд передает данные в формате little endian, кроме состояния АЦП (там bigendian-подобное смешанное черт знает что).

  • CAN_CMD_ADC имеет только геттер, поле данных в байтах 1..6 содержит смешанные по 12бит показания АЦП (каналы 5В, 12В и внутренние - температура МК и Vdd).

  • CAN_CMD_BTNS тоже без сеттера, здесь data[1] - номер кнопки, data[2] - ее состояние (значение enum keyevent), data[4..7] (для выравнивания) - время наступления событий в условных мс от запуска МК или переполнения счетчика времени (uint32_t, little endian).

  • CAN_CMD_LED имеет сеттер, в этом случае data[1] входящего потока задает состояние соответствующего светодиода (если бит N установлен, светодиод включается, нет - гаснет), в ответе data[1] указывает на текущее состояние светодиодов (аналогично сеттеру).

  • CAN_CMD_MCU без геттера, в data[2,3] содержится температура МК (T*10℃, little endian int16_t), в полях data[4,5] - значение Vdd (V*100, little endian uint16_t).

  • CAN_CMD_PWM позволяет задавать и читать заполнение соответствующих ШИМ каналов, поля у сеттера и геттера аналогичны: data[1..3] - соответствующее значение заполнения (0..255) ШИМ для каналов 0..2.

  • CAN_CMD_RELAY управляет релюшкой, поля сеттеров и геттеров тоже аналогичны: биты 0 и 1 в data[1] отражают состояние соответствующей релюхи (1 - включено, 0 - выключено).

  • CAN_CMD_TMS содержит в полях data[4..7] время Tms (little endian uint32_t).


Проверил работу, передавая данные с моего CAN-USB.
Себестоимость изделия получилась недорогой, т.к. использован МК из партии, закупленной около трех лет назад — до выдуманного "крЫзиса". Сейчас же если и удастся урвать STM32F042C6T6 рублей за 600, то стоимость всего остального будет меньше.
Reposted from dreamwidth: https://eddy-em.dreamwidth.org/295145.html.
Tags: stm32, железяки
Subscribe

  • Новая железяка - продолжение

    Шел третий день отпуска… Когда собирал железяку, возник насущный вопрос: а сможет ли такой слабенький движочек гонять такую дурищу (прежде всего —…

  • Новая железяка для БТА/Ц1000

    Уже больше полугода занимаюсь разработкой, вот, наконец-то в мастерских взялись за меня и начали выдавать первые детали. Сегодня сделал тестовую…

  • Пара зарядок с али

    3 августа заказал пару новых зарядок (нонче такое дело, что зарядок много не бывает). Сегодня получил. Обозреваю. Первая зарядка. Аж три USB и типа…

promo eddy_em september 3, 12:13 8
Buy for 10 tokens
Уже больше полугода занимаюсь разработкой, вот, наконец-то в мастерских взялись за меня и начали выдавать первые детали. Сегодня сделал тестовую сборку (как обычно, местами пришлось "доработать напильником"): Пока прибор без названия (да и как-то не лезет в голову ничего, у меня нет…
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic
  • 0 comments