восстановление потеряной ветки...

- сделана привязка датчиков по индексу или по юзер байтам
This commit is contained in:
2025-02-06 13:06:18 +03:00
parent e188fc4074
commit 586907b339
103 changed files with 100586 additions and 0 deletions

View File

@@ -0,0 +1,230 @@
#include "onewire_it_driver.h"
#define owtim htim3
OneWire_ITHandleTypeDef honewire;
static OneWire_State ow_state = OW_IDLE;
static int32_t ow_delay_counter = 0; // Ñ÷åò÷èê âðåìåíè äëÿ çàäåðæåê
extern TIM_HandleTypeDef owtim;
extern OneWire_t OW;
void OneWireIT_Init(OneWire_ITHandleTypeDef *OW_IT) {
OW_IT->onewire = &OW;
// Ðàçðåøàåì ïðåðûâàíèå òàéìåðà
HAL_TIM_Base_Start_IT(&owtim);
}
void OneWire_AddOperation(OneWire_ITHandleTypeDef *OW_IT, void (*operation)(OneWire_t*), uint8_t *io_data_buffer)
{
uint8_t next_tail = (OW_IT->tail + 1) % OP_QUEUE_SIZE;
if (next_tail != OW_IT->head)
{ // Î÷åðåäü íå ïåðåïîëíåíà
OW_IT->operation_queue[OW_IT->tail] = operation;
OW_IT->tail = next_tail;
}
}
void OneWire_ProcessNextOperation(OneWire_ITHandleTypeDef *OW_IT) {
if (OW_IT->head != OW_IT->tail) { // Åñëè î÷åðåäü íå ïóñòà
void (*current_op)(OneWire_t*) = OW_IT->operation_queue[OW_IT->head];
current_op(OW_IT->onewire);
if(OW_IT->op_done)
{
OW_IT->op_done = 0;
OW_IT->head = (OW_IT->head + 1) % OP_QUEUE_SIZE; // Ïåðåõîäèì ê ñëåäóþùåé îïåðàöèè
}
}
}
void OneWireTIMHandler(TIM_HandleTypeDef *htim, OneWire_ITHandleTypeDef *OW_IT)
{
if (htim == &owtim)
{
if (ow_delay_counter > 0)
{
ow_delay_counter -= ONE_WIRE_TIMER_PERIOD_US; // Óìåíüøàåì ñ÷åò÷èê çàäåðæêè
}
OneWire_Reset_ITHandle(OW_IT->onewire);
// OneWire_ProcessNextOperation(OW_IT);
}
}
void OneWire_WriteBytes_IT(OneWire_ITHandleTypeDef *OW_IT)
{
static HAL_StatusTypeDef res;
if (OW_IT->current_byte_idx < OW_IT->data_len) // Åñëè íå îáðàáîòàíû âñå äàííûå
{
uint8_t byte = OW_IT->data[OW_IT->current_byte_idx]; // Áåðåì òåêóùèé áàéò äàííûõ
for (OW_IT->current_bit_idx = 0; OW_IT->current_bit_idx < 8; OW_IT->current_bit_idx++)
{
uint8_t bit = (byte >> (7 - OW_IT->current_bit_idx)) & 0x01; // Ïîëó÷àåì áèò èç áàéòà
OneWire_WriteBit_ITHandle(OW_IT->onewire, bit); // Ïèøåì ýòîò áèò â OneWire
}
OW_IT->current_byte_idx++; // Ïåðåõîäèì ê ñëåäóþùåìó áàéòó
}
else
{
OW_IT->current_byte_idx = 0; // Çàâåðøàåì îïåðàöèþ çàïèñè
OW_IT->op_done = 1;
}
}
void OneWire_ReadBytes_IT(OneWire_ITHandleTypeDef *OW_IT)
{
uint8_t bit;
if (OW_IT->current_byte_idx < OW_IT->data_len) // Åñëè íå îáðàáîòàíû âñå äàííûå
{
uint8_t byte = 0; // Äëÿ õðàíåíèÿ ïðî÷èòàííîãî áàéòà
for (OW_IT->current_bit_idx = 0; OW_IT->current_bit_idx < 8; OW_IT->current_bit_idx++)
{
OneWire_ReadBit_ITHandle(OW_IT->onewire, &bit); // ×èòàåì áèò
byte |= (bit << (7 - OW_IT->current_bit_idx)); // Ñîáèðàåì áàéò èç áèòîâ
}
OW_IT->data[OW_IT->current_byte_idx] = byte; // Ñîõðàíÿåì áàéò â áóôåð
OW_IT->current_byte_idx++; // Ïåðåõîäèì ê ñëåäóþùåìó áàéòó
}
else
{
OW_IT->current_byte_idx = 0; // Çàâåðøàåì îïåðàöèþ ÷òåíèÿ
OW_IT->head = (OW_IT->head + 1) % OP_QUEUE_SIZE; // Óáèðàåì âûïîëíåííóþ îïåðàöèþ èç î÷åðåäè
}
}
HAL_StatusTypeDef OneWire_ReadBit_ITHandle(OneWire_t *OW, uint8_t *bit) {
static uint8_t read_bit_step = 0;
switch (read_bit_step)
{
case 0:
// Ñíèæàåì ïèí íà 1 ìêñ äëÿ íà÷àëà ïåðåäà÷è áèòà
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
ow_delay_counter = ONEWIRE_READ_CMD_US; // Çàäåðæêà 1 ìêñ äëÿ ÷òåíèÿ áèòà
read_bit_step++;
return HAL_BUSY;
case 1:
// Ïîäíèìàåì ïèí è ïðîâåðÿåì ñîñòîÿíèå äëÿ ÷òåíèÿ áèòà
if (ow_delay_counter <= 0)
{
OneWire_Pin_Mode(OW, Input);
ow_delay_counter = ONEWIRE_READ_DELAY_US; // Çàäåðæêà ïåðåä ñ÷èòûâàíèåì
read_bit_step++;
}
return HAL_BUSY;
case 2:
// ×èòàåì ïèí íà 1 ìêñ äëÿ îïðåäåëåíèÿ áèòà
if (ow_delay_counter <= 0)
{
*bit = OneWire_Pin_Read(OW);
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US;
}
return HAL_BUSY;
case 3:
read_bit_step = 0; // Çàâåðøàåì êîìàíäó ÷òåíèÿ
ow_state = OW_IDLE;
return HAL_OK;
default:
read_bit_step = 3;
return HAL_ERROR;
}
}
HAL_StatusTypeDef OneWire_WriteBit_ITHandle(OneWire_t *OW, uint8_t bit)
{
static uint8_t write_bit_step = 0;
switch (write_bit_step)
{
case 0:
// Ïèøåì áèò 0 èëè 1
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
if (bit)
{
ow_delay_counter = ONEWIRE_WRITE_1_US; // Çàäåðæêà ìêñ äëÿ çàïèñè 1
}
else
{
ow_delay_counter = ONEWIRE_WRITE_0_US; // Çàäåðæêà ìêñ äëÿ çàïèñè 0
}
write_bit_step++;
return HAL_BUSY;
case 1:
// Çàâåðøàåì çàïèñü, ïîäíèìàåì ïèí
if (ow_delay_counter == 0)
{
OneWire_Pin_Mode(OW, Input);
if (bit) {
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US; // Çàäåðæêà ìêñ äëÿ çàâåðøåíèÿ çàïèñè 1
}
else
{
ow_delay_counter = ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US; // Çàäåðæêà ìêñ äëÿ çàâåðøåíèÿ çàïèñè 0
}
write_bit_step++;
}
return HAL_BUSY;
case 2:
OneWire_Pin_Mode(OW, Input);
// Çàâåðøàåì çàïèñü
write_bit_step = 0;
ow_state = OW_IDLE;
return HAL_OK;
default:
write_bit_step = 2;
return HAL_ERROR;
}
}
HAL_StatusTypeDef OneWire_Reset_ITHandle(OneWire_t *OW)
{
static uint8_t reset_step = 0;
static uint8_t rslt = 0;
GPIOC->ODR ^= (1<<13);
switch (reset_step)
{
case 0:
// Íà÷àëî êîìàíäû Reset - îïóñêàåì ïèí íà 480 ìêñ
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
ow_delay_counter = ONEWIRE_RESET_PULSE_US; // Óñòàíàâëèâàåì çàäåðæêó â 480 ìêñ
reset_step++;
return HAL_BUSY;
case 1:
// Ïðîâåðÿåì, ïðîøëà ëè çàäåðæêà 480 ìêñ
if (ow_delay_counter <= 0)
{
/* Release line and wait for 70us */
OneWire_Pin_Mode(OW, Input);
ow_delay_counter = ONEWIRE_PRESENCE_WAIT_US; // Óñòàíàâëèâàåì çàäåðæêó íà 70 ìêñ
reset_step++;
}
return HAL_BUSY;
case 2:
// Æäåì îòâåòà îò óñòðîéñòâà íà ïîäíÿòèå ïèíà
if (ow_delay_counter <= 0)
{
// ×èòàåì ïèí, åñëè óñòðîéñòâî îòâåòèëî
uint8_t rslt = OneWire_Pin_Read(OW);
reset_step++;
}
return HAL_BUSY;
case 3:
reset_step = 0; // Çàâåðøàåì êîìàíäó Reset
ow_delay_counter = ONEWIRE_PRESENCE_DURATION_US; // Óñòàíàâëèâàåì çàäåðæêó íà 70 ìêñ
ow_state = OW_IDLE;
return HAL_OK;
default:
reset_step = 3;
return HAL_ERROR;
}
}

View File

@@ -0,0 +1,51 @@
/**
******************************************************************************
* @file onewire.h
* @brief This file contains all the constants parameters for the OneWire
******************************************************************************
* @attention
* Usage:
* Uncomment LL Driver for HAL driver
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef ONEWIRE_IT_DRIVER_H
#define ONEWIRE_IT_DRIVER_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx.h"
#include "onewire.h"
#define ONE_WIRE_TIMER_PERIOD_US 1 // Ïåðèîä òàéìåðà â ìèêðîñåêóíäàõ (1 ìêñ)
#define OP_QUEUE_SIZE 10 // Áóôåð îïåðàöèé OneWire
typedef enum {
OW_RESET,
OW_READ_BIT,
OW_SET_BIT,
OW_RESET_BIT,
OW_IDLE
} OneWire_State;
typedef struct
{
OneWire_t *onewire;
uint8_t *data; // Áóôåð äëÿ äàííûõ (äëÿ çàïèñè è ÷òåíèÿ)
uint8_t data_len; // Äëèíà äàííûõ
uint8_t current_byte_idx; // Èíäåêñ òåêóùåãî áàéòà äëÿ çàïèñè/÷òåíèÿ
uint8_t current_bit_idx; // Èíäåêñ òåêóùåãî áèòà äëÿ çàïèñè/÷òåíèÿ
uint8_t head; // Èíäåêñ ïåðâîé îïåðàöèè â î÷åðåäè
uint8_t tail; // Èíäåêñ ïîñëåäíåé îïåðàöèè â î÷åðåäè
uint8_t op_done; // Èíäåêñ ïîñëåäíåé îïåðàöèè â î÷åðåäè
void (*operation_queue[OP_QUEUE_SIZE])(OneWire_t*); // Î÷åðåäü îïåðàöèé
}OneWire_ITHandleTypeDef;
extern OneWire_ITHandleTypeDef honewire;
void OneWireTIMHandler(TIM_HandleTypeDef *htim, OneWire_ITHandleTypeDef *OW);
void OneWireIT_Init(OneWire_ITHandleTypeDef *OW_IT);
HAL_StatusTypeDef OneWire_ReadBit_ITHandle(OneWire_t *OW, uint8_t *bit);
HAL_StatusTypeDef OneWire_WriteBit_ITHandle(OneWire_t *OW, uint8_t bit);
HAL_StatusTypeDef OneWire_Reset_ITHandle(OneWire_t *OW);
#endif /* ONEWIRE_IT_DRIVER_H */

View File

@@ -0,0 +1,159 @@
/**
******************************************************************************
* @file : onewire_uart.c
* @brief : Драйвер для работы с шиной 1-Wire через UART
* @author : MicroTechnics (microtechnics.ru)
******************************************************************************
@details
Этот файл реализует базовые функции для работы с 1-Wire через UART.
Он включает в себя методы для передачи и приёма битов и байтов, а также
выполнение reset-команды для устройств 1-Wire.
UART передает специально сформированные импульсы, эмулируя 1-Wire.
*****************************************************************************/
/* Includes ----------------------------------------------------------------*/
#include "onewire_uart.h"
/* Declarations and definitions --------------------------------------------*/
/* Functions ---------------------------------------------------------------*/
/**
* @brief Устанавливает скорость передачи данных для UART.
* @param huart Указатель на структуру UART
* @param baudrate Требуемая скорость передачи (бит/с)
* @details Функция изменяет скорость передачи UART в зависимости от используемой шины
* (PCLK1 или PCLK2). Это важно для эмуляции временных параметров 1-Wire.
*/
static void UARTSetBaudrate(UART_HandleTypeDef *huart, uint32_t baudrate)
{
uint32_t pclk = 0;
huart->Init.BaudRate = baudrate;
#if defined(USART6) && defined(UART9) && defined(UART10)
if ((huart->Instance == USART1) || (huart->Instance == USART6) ||
(huart->Instance == UART9) || (huart->Instance == UART10))
{
pclk = HAL_RCC_GetPCLK2Freq();
}
#elif defined(USART6)
if ((huart->Instance == USART1) || (huart->Instance == USART6))
{
pclk = HAL_RCC_GetPCLK2Freq();
}
#else
if (huart->Instance == USART1)
{
pclk = HAL_RCC_GetPCLK2Freq();
}
#endif /* USART6 */
else
{
pclk = HAL_RCC_GetPCLK1Freq();
}
#if defined(USART_CR1_OVER8)
if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
{
huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
}
else
{
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
}
#else
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
#endif /* USART_CR1_OVER8 */
}
/**
* @brief Передает и принимает один бит через 1-Wire.
* @param huart Указатель на структуру UART
* @param bit Бит для передачи (0 или 1)
* @return Полученный бит (0 или 1)
* @details Передача осуществляется отправкой специального импульса, длина которого определяет передаваемый бит.
* Ответное значение читается сразу после передачи.
*/
uint8_t OneWireUART_ProcessBit(UART_HandleTypeDef *huart, uint8_t bit)
{
uint8_t txData;
uint8_t rxData = 0x00;
if (bit == 1)
{
txData = ONEWIRE_PULSE_SHORT; // Короткий импульс для передачи '1'
}
else
{
txData = ONEWIRE_PULSE_LONG; // Длинный импульс для передачи '0'
}
HAL_UART_Transmit(huart, &txData, 1, ONEWIRE_UART_TIMEOUT);
HAL_UART_Receive(huart, &rxData, 1, ONEWIRE_UART_TIMEOUT);
return rxData;
}
/**
* @brief Передает и принимает байт через 1-Wire.
* @param huart Указатель на структуру UART
* @param byte Отправляемый байт
* @return Принятый байт
* @details Отправляет 8 бит последовательно, используя @ref OneWire_ProcessBit.
* Каждый полученный бит собирается в байт и возвращается.
*/
uint8_t OneWireUART_ProcessByte(UART_HandleTypeDef *huart, uint8_t byte)
{
uint8_t rxByte = 0x00;
uint8_t txBit = 0;
uint8_t rxBit = 0;
for (uint8_t i = 0; i < ONEWIRE_BITS_NUM; i++)
{
txBit = (byte >> i) & 0x01; // Извлекаем очередной бит для отправки
uint8_t tempRxData = OneWireUART_ProcessBit(huart, txBit);
if (tempRxData == 0xFF)
{
rxBit = 1; // В случае высокого уровня на линии интерпретируем как '1'
}
else
{
rxBit = 0;
}
rxByte |= (rxBit << i); // Собираем принятые биты в байт
}
return rxByte;
}
/**
* @brief Выполняет 1-Wire Reset и проверяет наличие устройств на шине.
* @param huart Указатель на структуру UART
* @return HAL Status
* @details Процедура Reset требует изменения скорости UART, чтобы сформировать
* большой по длительности импульс сброса. Если устройство ответило, шина в рабочем состоянии.
*/
HAL_StatusTypeDef OneWireUART_Reset(UART_HandleTypeDef *huart)
{
HAL_StatusTypeDef status = HAL_OK;
uint8_t txByte = ONEWIRE_RESET;
uint8_t rxByte = 0x00;
UARTSetBaudrate(huart, ONEWIRE_RESET_BAUDRATE); // Устанавливаем низкую скорость для Reset-импульса
HAL_UART_Transmit(huart, &txByte, 1, ONEWIRE_UART_TIMEOUT);
HAL_UART_Receive(huart, &rxByte, 1, ONEWIRE_UART_TIMEOUT);
UARTSetBaudrate(huart, ONEWIRE_BAUDRATE); // Возвращаем стандартную скорость
if (rxByte == txByte)
{
status = HAL_ERROR; // Если ответ совпадает с отправленным байтом, значит, устройств нет
}
return status;
}

View File

@@ -0,0 +1,61 @@
/**
******************************************************************************
* @file : onewire_uart.h
* @brief : 1-Wire driver
* @author : MicroTechnics (microtechnics.ru)
*****************************************************************************/
#ifndef ONEWIRE_UART_H
#define ONEWIRE_UART_H
/* Includes ----------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/* Declarations and definitions --------------------------------------------*/
extern UART_HandleTypeDef huart1;
#define onewire_uart (&huart1)
#define ONEWIRE_BAUDRATE 115200
#define ONEWIRE_RESET_BAUDRATE 9600
#define ONEWIRE_UART_TIMEOUT 10
#define ONEWIRE_BITS_NUM 8
/**
* @brief Êîììàíäû OneWire
* @details Îïðåäåëÿåò áàéòû äëÿ uart, êîòîðûå áóäóò
* ôîðìèðîâàòü íåîáõîäèìóþ äëèíó èìïóëüñà äëÿ ðàçíûõ êîììàíä
*/
typedef enum
{
ONEWIRE_RESET = 0xF0, /*!< @brief Èìïóëüñ äëèíîé 520ìêñ äëÿ êîìàíäû Reset (9600bod)
@details 1-Wire òðåáóåò èìïóëüñ äëèòåëüíîñòüþ >480ìêñ */
ONEWIRE_PULSE_SHORT = 0xFF, /*!< @brief Èìïóëüñ äëèíîé 8.7 ìêñ äëÿ çàïèñè "1"/÷òåíèÿ áèòà (115200bod)
@details 1-Wire òðåáóåò èìïóëüñ äëèòåëüíîñòüþ 1-15ìêñ */
ONEWIRE_PULSE_LONG = 0x00, /*!< @brief èìïóëüñ äëèíîé 78.3 ìêñ äëÿ çàïèñè "0" (115200bod)
@details 1-Wire òðåáóåò èìïóëüñ äëèòåëüíîñòüþ 60-120ìêñ */
// ONEWIRE_PULSE_1_15US = 0xFF,
// ONEWIRE_PULSE_60_120US = 0x00,
}ONEWIRE_Commands;
/* Functions ---------------------------------------------------------------*/
/* Âûïîëíÿåò 1-Wire Reset è ïðîâåðÿåò íàëè÷èå óñòðîéñòâ íà øèíå */
HAL_StatusTypeDef OneWireUART_Reset(UART_HandleTypeDef *huart);
/* Ïåðåäàåò è ïðèíèìàåò áàéò ÷åðåç 1-Wire */
uint8_t OneWireUART_ProcessByte(UART_HandleTypeDef *huart, uint8_t byte);
/* Ïåðåäàåò è ïðèíèìàåò îäèí áèò ÷åðåç 1-Wire */
uint8_t OneWireUART_ProcessBit(UART_HandleTypeDef *huart, uint8_t bit);
#endif // #ifndef ONEWIRE_UART_H