Инструменты пользователя

Инструменты сайта


prog:can:can_test

Базовые сведения о протоколе CAN и реализация работы с разбором кадра данных в 1986BE92.

Подробную информацию о Controller Area Network можно прочесть в Википедии.

В статье будут приведены лишь базовые сведения и рассмотрена программа, которая отправляет с микроконтроллера 1986ВЕ92 стандартный кадр CAN со скоростью 500 Кбит/с. Для отслеживания кадра будем использовать осциллограф. Отметим, что реализация проекта очень простая и может использоваться абсолютно на любом микроконтроллере производства фирмы Миландр с поддержкой данного протокола.

Базовые сведения

  1. CAN (англ. Controller Area Network – локальная сеть контроллеров) – стандарт промышленной сети, ориентированный на объединение блоков управления, исполнительных устройств и датчиков в систему.
  2. CAN определяет только протокол передачи данных в отрыве от физического уровня. На практике, однако, под CAN обычно понимается сеть с топологией типа «шина», организованная на базе дифференциальной пары, имеющей сигналы CAN_H (can-high) и CAN_L (can-low)
  3. Для абстрагирования от среды передачи, стандарт CAN не использует такие понятия, как логические «0» и «1» при определении сигналов. Вместо этого применяются термины «доминантный» и «рецессивный», смысл которых состоит в том, что при одновременной передаче двумя источниками доминантного и рецессивного сигналов, принят будет только доминантный. Стандарт сети требует от физического уровня, фактически, единственного условия: подавление доминантным сигналом рецессивного (но не наоборот).
  4. Все устройства должны работать на одной скорости.
  5. Шина CAN обязательно должна терминироваться не зависимо от ее скорости. Это достигается путем установки резисторов на концах шины.
  6. Информация в сети CAN передается кадрами (англ. frame), имеющими определенную структуру. Кадры бывают следующие:
    1. Data Frame (Наиболее частый тип сообщений. Состоит из поля арбитража, поля данных, поля CRC и слота подтверждения)
    2. Remote Frame (То же, что и Data Frame, но без поля данных и с выставленным RTR в “1”. Производит инициацию одним из узлов сети передачи в сеть данных другим узлом).
    3. Error Frame (Это сообщение, которое явно нарушает формат сообщения CAN).
    4. Overload Frame (То же, что и Error Frame, но используется перегруженным узлом).
  7. Протокол CAN имеет пять механизмов обнаружения ошибок в сети:
    1. контроль передаваемых значений.
    2. вставка битов.
    3. проверка формы кадра.
    4. подтверждение приема.
    5. контрольная сумма.
  8. Использование арбитража. Поле арбитража используется в CAN для разрешения коллизий доступа к шине методом не деструктивного арбитража. Суть метода не деструктивного арбитража заключается в следующем: в случае, когда несколько контроллеров начинают одновременную передачу данных в сеть, каждый из них сравнивает бит конкурирующего контроллера со своим. Если значения этих битов равны, оба контроллера передают следующий бит. И так происходит до тех пор, пока значения передаваемых битов не окажутся различными. Теперь контроллер, который передавал логический ноль (более приоритетный сигнал), будет продолжать передачу, а другой (другие) - прервёт свою передачу до того времени, пока шина вновь не освободится. Конечно, если шина в данный момент занята, то устройство не начнет передачу до момента её освобождения. На картинке ниже наглядно показана работа арбитража в протоколе CAN.

Проект для передачи стандартного кадра CAN с его последующим разбором

Для начала не забудем около разъема CAN на отладочной плате поставить перемычку XP15 в положение 500 Кбит/с.

Код для стандартных настроек портов ввода/вывода не рассматривается, все данные можно посмотреть в стандартных примерах из пака для Keil. Особое внимание уделено настройке именно CAN-блока.

CAN-контроллер использует две линии обмена данными, обе должны быть сконфигурированы (CAN_RX - для приёма и CAN_TX - для передачи). На микроконтроллере 1986BE92 за CAN1 отвечают линии PA6 и PA7 соответственно. Стоит отметить, что функция порта альтернативная. После выполненных действий можно приступить к настройке CAN.

Для правильной инициализации модуля CAN нужно придерживаться следующей последовательности действий:

1. Включить тактирование модуля.

2. Сконфигурировать структуру CAN:

// Структура для инициализации модуля CAN 
CAN_InitTypeDef CANInitStruct; 
// Конфигурация модуля CAN1 
CANInitStruct.CAN_ROP = DISABLE; // Прием собственных пакетов отключено
CANInitStruct.CAN_SAP = DISABLE; // Подтверждение приема отключено
// собственных кадров 
CANInitStruct.CAN_STM = DISABLE; // Режим самотестирования отключен
CANInitStruct.CAN_ROM = DISABLE; // Режим "только чтение" отключен
CANInitStruct.CAN_PSEG = CAN_PSEG_Mul_2TQ; // Битовый сегмент. Длительность PS
CANInitStruct.CAN_SEG1 = CAN_SEG1_Mul_4TQ; // Битовый сегмент. Длительность PBS1 
CANInitStruct.CAN_SEG2 = CAN_SEG2_Mul_3TQ; // Битовый сегмент. Длительность PBS2 
CANInitStruct.CAN_SJW = CAN_SJW_Mul_2TQ; // Интервал перестройки сегментов 
CANInitStruct.CAN_SB = CAN_SB_1_SAMPLE; // Режим выборки 
CANInitStruct.CAN_BRP = 15; // Предделитель тактовой частоты 
CANInitStruct.CAN_OVER_ERROR_MAX = 255; // Максимальное значение счетчика ошибок до установки флага 

3. Настроить аппаратные прерывания. В нашем проекте они использованы не будут.

4. Активировать модуль:

// Включение модуля CAN1 
CAN_Cmd(MDR_CAN1, ENABLE);

Для передачи данных в библиотеке предусмотрена специальная структура CAN_TxMsgTypeDef, которая настраивает фрейм передающих данных:

 // Формирование кадра данных 
CAN_TxMsgTypeDef tx_frame; 
tx_frame.ID = 0x19ABFFFF; // Идентификатор кадра данных 
tx_frame.PRIOR_0 = 1; // Приоритет кадра данных 
tx_frame.IDE = CAN_ID_STD; // Формат кадра данных - стандартный
tx_frame.DLC = 1; // Длина поля данных (в байтах) 
tx_frame.Data[0] = 0x000000AA; // Первые четыре байта данных 
tx_frame.Data[1] = 0x00000000; // Вторые четыре байта данных

При настройке стандартного идентификатора (содержит 11 бит) кадра данных следует помнить, что, согласно спецификации, для правильной настройки нужно задействовать биты с 18-го по 28-й. В нашей программе для стандартного идентификатора мы взяли число 19ABFFFF, и старшие 11 бит двоичного представления будут являться стандартным идентификатором.

Для передачи сформированного фрейма используем функцию:

// Передача кадра 
CAN_Transmit(MDR_CAN1, TX_BUFFER_NUMBER, &tx_frame);

Написание кода на этом этапе заканчивается, однако, если нужно принимать данные по CAN, то для этого используется буфер:

// Настройка буфера на прием кадров 
CAN_Receive(MDR_CAN1, RX_BUFFER_NUMBER, DISABLE); // Третий аргумент отвечает за возможность перезаписи принятых данных

И настройка структуры CAN_RxMsgTypeDef для приёма данных выполняется следующим образом:

// Структура для приема кадра 
CAN_RxMsgTypeDef rx_frame; 
// Извлечение данных из буфера 
CAN_GetRawReceivedData(MDR_CAN1, RX_BUFFER_NUMBER, &rx_frame);

Приём кадра данных осциллографом. Разбор кадра

Для подключения осциллографа используются линии CAN_H и CAN_L:

При подключении осциллографа к МК будет отображать непрерывный сигнал с нашим фреймом данных:

Бит sof указывает на начало передачи фрейма.

Бит RTR определяет тип кадра.

Бит IDE определяет формат кадра.

Бит R0 зарезервированный, и согласно протоколу должен иметь доминантное значение, то есть “0”.

Объем кадра у нас равен одному байту, это значение мы задавали в поле DLС при формировании кадра в коде.

На основании выбранного объема кадра мы видим один байт информации, который мы задали программно.

При увеличении объема кадра DLC, которое может быть в диапазоне от одного до восьми, будет наблюдаться расширение кадра пропорционально введенному количеству байт, а сами байты информации мы можем задавать в конфигурационных полях tx_frame.Data[0] и tx_frame.Data[1]

Frame Format

Фреймы стандартный и расширенный отличаются только полем арбитража и одним битом в поле контроля. Расширенный формат введен чтобы увеличить разрядность поля ID. Перестановки в битах, выделенные на картинке цветом, сделаны так, чтобы сохранилась совместимость со стандартным форматом фрейма.

Прерывания

Запрос на прерывание передачи (флаг CAN_TX[x] в регистре MDR_CANx→TX) происходит, когда разрешенный буфер на передачу НЕ имеет запроса на отправку сообщения (то есть когда TX_REQ = 0, регистр MDR_CANx→BUF_CON[x])

prog/can/can_test.txt · Последние изменения: 2019/11/07 09:53 — artem