release 0.5 (*API CHANGED)
- чуть переделаны некоторые дефайны для универсализации - смена направления сделана через указател на функцию, а не глобальный дефайн - добавлен бета осцилограф модбас - некоторый рефакторинг
This commit is contained in:
145
Src/modbus_oscil.c
Normal file
145
Src/modbus_oscil.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file modbus_oscil.c
|
||||
* @brief Модуль для реализации осциллографа через MODBUS.
|
||||
*******************************************************************************
|
||||
* @details
|
||||
* Файл содержит реализацию функций для работы с буфером осциллографа.
|
||||
*
|
||||
* @section oscil_functions Функции
|
||||
* - MB_Oscil_Init() — Инициализация структуры осциллографа
|
||||
* - MB_Oscil_Add() — Добавление данных в буфер
|
||||
* - MB_Oscil_UpdateTail() — Обновление указателя Tail
|
||||
******************************************************************************/
|
||||
#include "modbus_oscil.h"
|
||||
|
||||
#ifdef MODBUS_ENABLE_OSCIL
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Инициализация структуры осциллографа
|
||||
* @param oscil Указатель на структуру осциллографа
|
||||
* @param BufferSize Размер буфера в Modbus регистрах (max 125)
|
||||
* @param NumbOfChannels Количество каналов (должно быть четным)
|
||||
* @param SampleTime Период дискретизации
|
||||
* @return HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef MB_Oscil_Init(MB_OscilTypeDef *oscil, uint8_t BufferSize, uint8_t NumbOfChannels, uint16_t SampleTime)
|
||||
{
|
||||
if(!oscil || (BufferSize >= MbData_size) || (NumbOfChannels > 15) || !SampleTime)
|
||||
return HAL_ERROR;
|
||||
|
||||
if(NumbOfChannels % 2 != 0)
|
||||
return HAL_ERROR;
|
||||
|
||||
oscil->Config.BufferSize = BufferSize;
|
||||
oscil->Config.NumbOfChannels = NumbOfChannels;
|
||||
oscil->Config.SampleTime = SampleTime;
|
||||
oscil->Config.LastTick = 0;
|
||||
oscil->Preamble.Head = 0;
|
||||
oscil->Preamble.Tail = 0;
|
||||
oscil->Config.Overrun = 0;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Инициализация структуры осциллографа
|
||||
* @param oscil Указатель на структуру осциллографа
|
||||
* @param BufferSize Размер буфера в Modbus регистрах (max 125)
|
||||
* @param NumbOfChannels Количество каналов (должно быть четным)
|
||||
* @param SampleTime Период дискретизации
|
||||
* @return HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef MB_Oscil_Set_SampleTime(MB_OscilTypeDef *oscil, uint16_t SampleTime)
|
||||
{
|
||||
if(!oscil || !SampleTime)
|
||||
return HAL_ERROR;
|
||||
|
||||
oscil->Config.SampleTime = SampleTime;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Добавление данных всех каналов в буфер
|
||||
* @param oscil Указатель на структуру осциллографа
|
||||
* @param Data Массив с данными каналов (длина = NumbOfChannels)
|
||||
* @return HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef MB_Oscil_Add(MB_OscilTypeDef *oscil, uint8_t *Data)
|
||||
{
|
||||
if(!oscil || !Data)
|
||||
return HAL_ERROR;
|
||||
|
||||
if(local_time() - oscil->Config.LastTick < oscil->Config.SampleTime)
|
||||
return HAL_BUSY;
|
||||
|
||||
oscil->Config.LastTick = local_time();
|
||||
|
||||
uint8_t head_max = oscil->Config.BufferSize * 2;
|
||||
uint8_t start_pos = oscil->Preamble.Head;
|
||||
uint8_t channels = oscil->Config.NumbOfChannels;
|
||||
uint8_t tail = oscil->Preamble.Tail;
|
||||
|
||||
// Пишем данные
|
||||
for(uint8_t i = 0; i < channels; i++)
|
||||
{
|
||||
uint8_t write_pos = (start_pos + i) % head_max;
|
||||
oscil->Data[write_pos] = Data[i];
|
||||
}
|
||||
|
||||
// Новое положение Head
|
||||
uint8_t new_head = (start_pos + channels) % head_max;
|
||||
|
||||
// Проверяем, есть ли непрочитанные данные (Tail != Head)
|
||||
// if(tail != start_pos) {
|
||||
// Если есть непрочитанные данные, проверяем не перетерли ли мы их
|
||||
if(start_pos < new_head) {
|
||||
// Линейный случай
|
||||
if(tail > start_pos && tail <= new_head) {
|
||||
oscil->Preamble.Tail = (new_head + 1) % head_max;
|
||||
oscil->Config.Overrun = 1;
|
||||
}
|
||||
} else if(start_pos > new_head) {
|
||||
// Кольцевой случай (было переполнение)
|
||||
if(tail > start_pos || tail <= new_head) {
|
||||
oscil->Preamble.Tail = (new_head + 1) % head_max;
|
||||
oscil->Config.Overrun = 1;
|
||||
}
|
||||
}
|
||||
// }
|
||||
oscil->Preamble.Head = new_head;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Обновление указателя Tail
|
||||
* @param oscil Указатель на структуру осциллографа
|
||||
* @return HAL Status
|
||||
*
|
||||
* @details Вызывается после того, как данные были прочитаны через Modbus.
|
||||
* Tail устанавливается на следующий байт за Head.
|
||||
*/
|
||||
HAL_StatusTypeDef MB_Oscil_UpdateTail(MB_OscilTypeDef *oscil)
|
||||
{
|
||||
if(!oscil)
|
||||
return HAL_ERROR;
|
||||
|
||||
// Сдвигаем Tail на следующий байт за Head
|
||||
uint8_t head_max = oscil->Config.BufferSize * 2;
|
||||
oscil->Preamble.Tail = oscil->Preamble.Head;
|
||||
|
||||
if(oscil->Preamble.Tail >= head_max)
|
||||
oscil->Preamble.Tail = 0;
|
||||
|
||||
oscil->Config.Overrun = 0;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif //MODBUS_ENABLE_OSCIL
|
||||
Reference in New Issue
Block a user