can-sensor
Однокадровый транспорт SETCAN SETTINGS для привязки 64-битного ROM 1-Wire к локации «номер сборки + позиция» по шине CAN.
Ядро на C99: не включает заголовки периферии, не обращается к регистрам,
не пользуется прерываниями. Обмен идёт через таблицу CanSensor_Io,
которую заполняет порт платы.
Сообщение помещается в один Extended CAN-кадр: локация находится в Body 29-битного ID, а ROM — в восьми байтах payload:
запрос 0x17FEZZYY: DLC=0 — GET, DLC=8 — WRITE/REPLACE/CLEAR
ответ 0x1FFEZZYY: DLC=8 — текущий ROM, DLC=1 — код ошибки
Состав
| Файл | Что делает | Зависимости |
|---|---|---|
can_sensor.h, can_sensor.c |
сборка и разбор SETTINGS, повторы передачи, счётчики обмена | stdint.h |
ports/stm32f1/ |
опросный порт CAN1: GPIO, BTR, фильтр, mailbox/FIFO, тайм-аут ACK | CMSIS stm32f10x.h |
ZZ — номер сборки, YY — позиция. Нулевой ROM с DLC=8 очищает локацию.
Что нужно от платформы
uint8_t send(void *ctx, const CanSensor_Frame *frame); /* 1 — кадр принят */
uint8_t receive(void *ctx, CanSensor_Frame *frame); /* 1 — кадр получен */
receive необязателен: с нулевым полем узел работает только на передачу.
Быстрый старт
CanSensor link;
CanSensor_Io io = { .send = bxcan_send, .receive = bxcan_receive, .context = &board };
CanSensor_Config config;
CanSensor_ConfigDefault(&config); /* TX 0x1FFE0000, RX 0x17FE0000 */
CanSensor_Init(&link, &io, &config);
CanSensor_SendId(&link, position, assembly_serial, rom);
CanSensor_Message message;
if (CanSensor_Poll(&link, &message)) { /* принят идентификатор */ }
Порт STM32F1
Порт не использует STM32 HAL и не занимает прерывания. Скопируйте
ports/stm32f1/can_sensor_stm32f1_config.f103.template.h в приложение под
именем can_sensor_stm32f1_config.h, добавьте ports/stm32f1 в include path и
соберите can_sensor_stm32f1.c вместе с ядром:
CanSensorStm32F1_Port bxcan = {0};
CanSensor_Io io;
CanSensorStm32F1_Start(&bxcan, 500000U, 0x17F00000UL, 0x1FF00000UL, 0U);
io = CanSensorStm32F1_MakeIo(&bxcan);
CanSensor_Init(&link, &io, &config);
/* Из главного цикла: */
CanSensorStm32F1_Task(&bxcan, now_ms, 20U);
Фильтр порта принимает только Extended data-кадры. Маска задаётся приложением:
можно пропустить только SETTINGS либо оставить открытым MsgType для соседних
команд того же узла. CanSensorStm32F1_Receive() доступна отдельно, если перед
CanSensor_HandleFrame() приложению нужно разобрать такие команды самому.
Проверено в проектах
KONOR_ds18b20 — bxCAN на STM32F103C8T6. Естественная пара — ds18b20:
ROM-коды, найденные DS18B20_Search(), уходят в шину как есть.