# SN65HVD230 ### Драйвер трансивера SN65HVD230 для STM32G0 (FDCAN) Легковесная, объектно-ориентированная библиотека на Си для работы с CAN-трансивером **SN65HVD230** (на базе плат типа MCU-230 / CJMCU-230) через аппаратный модуль **FDCAN** микроконтроллеров семейства **STM32G0**. Библиотека оптимизирована для работы в режиме классического CAN (Classic CAN) на максимальной скорости, так как на используемом модуле пин управления энергосбережением (`Rs`) аппаратно подтянут к GND. * * * ### 📌 Особенности реализации * **Чистый ООП-стиль на Си**: вся работа идет через дескриптор устройства `SN65HVD230_t`. * **Специализировано под STM32G0**: код очищен от лишних макросов препроцессора и завязан строго на архитектуру модуля FDCAN. * **Безопасность памяти**: полное отсутствие динамического выделения памяти (`malloc`). * **Контроль таймаутов**: функции отправки и приема снабжены блокирующими тайм-аутами для предотвращения зависания контроллера при сбоях на физическом уровне шины. * * * ### 🛠 Настройка периферии в STM32CubeMX Для корректной работы библиотеки настройте модуль FDCAN в графическом конфигураторе: 1. В разделе **Connectivity** выберите **FDCAN1**. 2. Установите режим **Operating Mode** в значение **Architecture**. 3. **Настройка тактирования (Bit Timings)**: * Настройте параметры `Nominal Prescaler`, `Time Seg1` и `Time Seg2` под требуемую скорость вашей сети (например, 250 или 500 кбит/с). * Режим `Frame Format` установите в **Classic CAN**. 4. Вкладка **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`.