SN65HVD230
Драйвер трансивера SN65HVD230 для STM32G0 (FDCAN)
Легковесная, объектно-ориентированная библиотека на Си для работы с CAN-трансивером SN65HVD230 (на базе плат типа MCU-230 / CJMCU-230) через аппаратный модуль FDCAN микроконтроллеров семейства STM32G0.
Библиотека оптимизирована для работы в режиме классического CAN (Classic CAN) на максимальной скорости, так как на используемом модуле пин управления энергосбережением (Rs) аппаратно подтянут к GND.
📌 Особенности реализации
- Чистый ООП-стиль на Си: вся работа идет через дескриптор устройства
SN65HVD230_t. - Специализировано под STM32G0: код очищен от лишних макросов препроцессора и завязан строго на архитектуру модуля FDCAN.
- Безопасность памяти: полное отсутствие динамического выделения памяти (
malloc). - Контроль таймаутов: функции отправки и приема снабжены блокирующими тайм-аутами для предотвращения зависания контроллера при сбоях на физическом уровне шины.
🛠 Настройка периферии в STM32CubeMX
Для корректной работы библиотеки настройте модуль FDCAN в графическом конфигураторе:
- В разделе Connectivity выберите FDCAN1.
- Установите режим Operating Mode в значение Architecture.
- Настройка тактирования (Bit Timings):
- Настройте параметры
Nominal Prescaler,Time Seg1иTime Seg2под требуемую скорость вашей сети (например, 250 или 500 кбит/с). - Режим
Frame Formatустановите в Classic CAN.
- Настройте параметры
- Вкладка NVIC Settings:
- Включите прерывание FDCAN1 interrupt 0 (необходимо для работы системы уведомлений и прерываний).
🔌 Схема подключения (MCU-230 <-> STM32G0)
Контакт модуля MCU-230
Контакт STM32G0
Описание
3V3
3.3V
Питание модуля (от шины МК)
GND
GND
Общая земля
CTX
FDCAN1_TX
Линия передачи данных (настраивается в CubeMX)
CRX
FDCAN1_RX
Линия приема данных (настраивается в CubeMX)
CANH
Линия CAN_H
Прямой дифференциальный сигнал шины
CANL
Линия CAN_L
Инверсный дифференциальный сигнал шины
⚠️ Важное замечание по терминатору 120 Ом:
На плате MCU-230 уже распаян SMD-резистор 121 (120 Ом).
- Если в вашей тестовой сети всего два устройства — оставьте его.
- Если вы подключаете этот модуль к готовой существующей сети, где на концах уже установлены терминаторы — обязательно выпаяйте резистор 120 Ом с платы модуля, чтобы не просаживать импеданс шины.
🚀 Быстрый старт (Пример использования)
Добавьте файлы sn65hvd230_g0.h и sn65hvd230_g0.c в свой проект. Скопируйте следующую логику в файл main.c:
c
#include "sn65hvd230_g0.h"
/* Хэндлер FDCAN, сгенерированный CubeMX */
extern FDCAN_HandleTypeDef hfdcan1;
/* Создаем глобальный дескриптор нашего CAN-узла */
SN65HVD230_t can_node;
void main(void) {
// ... Автоматическая инициализация HAL, SystemClock, GPIO ...
// MX_FDCAN1_Init(); // Инициализация FDCAN из CubeMX
/* 1. Аппаратный сброс фильтров (Разрешаем прием ВСЕХ пакетов для теста) */
FDCAN_FilterTypeDef filter;
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0;
filter.FilterType = FDCAN_FILTER_RANGE;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = 0x000;
filter.FilterID2 = 0x7FF;
HAL_FDCAN_ConfigFilter(&hfdcan1, &filter);
/* 2. Инициализация структуры трансивера */
SN65HVD230_Init(&can_node, &hfdcan1);
/* 3. Запуск FDCAN шины */
SN65HVD230_Start(&can_node);
/* 4. Подготовка пакета для отправки */
CAN_Message_t tx_msg;
tx_msg.Identifier = 0x123; // ID сообщения
tx_msg.IdType = FDCAN_STANDARD_ID; // Стандартный 11-битный формат
tx_msg.TxFrameType = FDCAN_DATA_FRAME; // Кадр данных
tx_msg.DataLength = FDCAN_DLC_BYTES_4; // Будем отправлять 4 байта
tx_msg.Data[0] = 0xDE;
tx_msg.Data[1] = 0xAD;
tx_msg.Data[2] = 0xBE;
tx_msg.Data[3] = 0xEF;
while (1) {
/* Отправляем сообщение раз в секунду с таймаутом ожидания 50 мс */
SN65HVD230_Transmit(&can_node, &tx_msg, 50);
HAL_Delay(1000);
/* Неблокирующий опрос входящих сообщений (timeout = 0) */
CAN_Message_t rx_msg;
if (SN65HVD230_Receive(&can_node, &rx_msg, 0) == HAL_OK) {
// Если пришел пакет с ожидаемым ID, обрабатываем буфер rx_msg.Data
if (rx_msg.Identifier == 0x500) {
// Ваша логика обработки данных здесь...
}
}
}
}
Используйте код с осторожностью.
📝 API Справочник функций
HAL_StatusTypeDef SN65HVD230_Init(SN65HVD230_t *node, FDCAN_HandleTypeDef *hfdcan_handle)
Связывает структуру дескриптора со сгенерированным в CubeMX аппаратным хэндлером FDCAN.
- Возвращает:
HAL_OKпри успехе,HAL_ERRORесли переданы пустые указатели (NULL).
HAL_StatusTypeDef SN65HVD230_Start(SN65HVD230_t *node)
Включает прерывания по получению новых данных в FIFO 0 и переводит модуль FDCAN из режима инициализации в активный режим работы на шине.
HAL_StatusTypeDef SN65HVD230_Stop(SN65HVD230_t *node)
Переводит модуль FDCAN в режим инициализации, безопасно отключая узел от CAN-сети.
HAL_StatusTypeDef SN65HVD230_Transmit(SN65HVD230_t *node, CAN_Message_t *msg, uint32_t timeout_ms)
Отправляет классический CAN-кадр в шину. Если TX FIFO заполнено, функция будет ожидать освобождения ячейки в течение времени timeout_ms.
HAL_StatusTypeDef SN65HVD230_Receive(SN65HVD230_t *node, CAN_Message_t *msg, uint32_t timeout_ms)
Вычитывает входящий CAN-кадр из буфера FIFO 0 периферии. Если буфер пуст, функция ожидает появления сообщения в течение timeout_ms.
- Для неблокирующего опроса шины вызывайте функцию с аргументом
timeout_ms = 0.