First release
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#include "DS_Accord_8_F-CAN.h"
|
||||
|
||||
// Внешний дескриптор CAN из main.c
|
||||
extern CAN_HandleTypeDef hcan;
|
||||
|
||||
// Массив пакетов симуляции
|
||||
volatile CanTaskTypeDef tasks[] = {
|
||||
// ID, DLC, Period, Alive, Last_Time, Start_Phase, { Исходные данные DATA[8] }
|
||||
{0x158, 8, 10, 0, 0, 0, {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00}}, // ECU Скорость
|
||||
{0x17C, 8, 10, 0, 0, 2, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, //
|
||||
{0x1A4, 8, 20, 0, 0, 4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // ABS/VSA Тормоза
|
||||
{0x324, 8, 20, 0, 0, 6, {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // MICU Кузов
|
||||
|
||||
// {0x490, 8, 20, 0, 0, 6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x491, 8, 20, 0, 0, 6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x492, 8, 20, 0, 0, 8, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x493, 8, 20, 0, 0, 8, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x494, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x495, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x496, 8, 20, 0, 0, 1, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x497, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x498, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x499, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49A, 8, 20, 0, 0, 5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49B, 8, 20, 0, 0, 5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49C, 8, 20, 0, 0, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49D, 8, 20, 0, 0, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49E, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49F, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}}
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t num_tasks = sizeof(tasks) / sizeof(tasks[0]);
|
||||
static const uint8_t alive_seq[] = {0, 1, 2, 3};
|
||||
|
||||
/**
|
||||
* @brief Главный диспетчер циклической симуляции пакетов для Honda Accord 8
|
||||
* @note Должен вызываться в основном бесконечном цикле while(1) в main.c
|
||||
*/
|
||||
void run_honda_simulation(void)
|
||||
{
|
||||
uint32_t current_tick = HAL_GetTick();
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint8_t tx_data[8]; // Временный буфер для формирования финального кадра
|
||||
uint32_t tx_mailbox;
|
||||
|
||||
for (uint8_t i = 0; i < num_tasks; i++)
|
||||
{
|
||||
// Настройка стартовой фазы при первом запуске
|
||||
if (tasks[i].last_time == 0)
|
||||
{
|
||||
tasks[i].last_time = current_tick + tasks[i].start_phase;
|
||||
}
|
||||
|
||||
// Проверка временной сетки
|
||||
if (current_tick < tasks[i].last_time)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Проверка свободного места в Mailbox пула
|
||||
if (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Сдвигаем временную метку на период вперед
|
||||
tasks[i].last_time += tasks[i].period;
|
||||
|
||||
// Копируем текущие данные из структуры во временный буфер отправки
|
||||
for (uint8_t b = 0; b < 8; b++)
|
||||
{
|
||||
tx_data[b] = tasks[i].data[b];
|
||||
}
|
||||
|
||||
// Конфигурируем заголовок CAN
|
||||
tx_header.StdId = tasks[i].id;
|
||||
tx_header.DLC = tasks[i].dlc;
|
||||
tx_header.RTR = CAN_RTR_DATA;
|
||||
tx_header.IDE = CAN_ID_STD;
|
||||
tx_header.TransmitGlobalTime = DISABLE;
|
||||
|
||||
// Расчитываем динамическую контрольную сумму Honda на основе текущих данных
|
||||
uint8_t current_alive = alive_seq[tasks[i].alive_cnt];
|
||||
uint8_t checksum_nibble = calc_honda_halfbyte_checksum(tx_header.StdId, tx_data, tx_header.DLC, current_alive);
|
||||
|
||||
// Внедряем Alive счетчик и чексумму в самый последний байт пакета
|
||||
tx_data[tx_header.DLC - 1] = (uint8_t)((current_alive << 4) | checksum_nibble);
|
||||
|
||||
// Отправляем пакет в пул Mailbox
|
||||
if (HAL_CAN_AddTxMessage(&hcan, &tx_header, tx_data, &tx_mailbox) == HAL_OK)
|
||||
{
|
||||
tasks[i].alive_cnt = (tasks[i].alive_cnt + 1) % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Математически выверенный алгоритм подсчета Check Byte для Accord 8 (Сумма полубайт + DLC)
|
||||
*/
|
||||
uint8_t calc_honda_halfbyte_checksum(uint16_t id, uint8_t *data, uint8_t dlc, uint8_t alive_val)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
// 1. Складываем полубайты 11-битного CAN ID
|
||||
sum += (id >> 8) & 0x0F;
|
||||
sum += (id >> 4) & 0x0F;
|
||||
sum += id & 0x0F;
|
||||
|
||||
// 2. Складываем полубайты тела пакета (все, кроме последнего контрольного байта)
|
||||
for (int i = 0; i < (dlc - 1); i++)
|
||||
{
|
||||
sum += (data[i] >> 4) & 0x0F;
|
||||
sum += data[i] & 0x0F;
|
||||
}
|
||||
|
||||
// 3. Добавляем длину пакета и шаг циклического счетчика
|
||||
sum += dlc & 0x0F;
|
||||
sum += alive_val & 0x0F;
|
||||
|
||||
// 4. Реализация правила дополнения до нуля (вычитание накопленного остатка из 16)
|
||||
return (uint8_t)((0x10 - (sum & 0x0F)) & 0x0F);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user