init proj

This commit is contained in:
2025-06-24 19:06:17 +03:00
parent 295c52a068
commit 93ab91eb16
117 changed files with 113513 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "def.h"
//extern uint8_t devices_found ;
extern uint8_t roms[MAX_DEVICES][8];
extern char rx_buffer[64];
extern TEMP temp_sense[30];
extern uint8_t init;
int test_var=0;
//void handle_command(char* cmd)
//
//{
// if (strncmp(cmd, "list", 4) == 0)
// {
// printf("find %d devices:\r\n", devices_found);
// for (int i = 0; i < devices_found; i++)
// {
// printf("Device #%d: ", i);
// for (int j = 0; j < 8; j++)
// printf("%02X ", roms[i][j]);
// printf("\r\n");
// }
// }
// else if (strncmp(cmd, "temp all", 8) == 0)
// {
// for (int i = 0; i < devices_found; i++)
// {
// ds_reset();
// ds_write_byte(0x55);
// for (int j = 0; j < 8; j++)
// ds_write_byte(roms[i][j]);
// ds_write_byte(0x44);
// }
// HAL_Delay(750);
// for (int i = 0; i < devices_found; i++)
// {
// ds_reset();
// ds_write_byte(0x55);
// for (int j = 0; j < 8; j++)
// ds_write_byte(roms[i][j]);
// ds_write_byte(0xBE);
// uint8_t tl = ds_read_byte();
// uint8_t th = ds_read_byte();
// int16_t t = (th << 8) | tl;
// float temp = t / 16.0;
// printf("T[%d] = %.2f C\r\n", i, temp);
// }
// }
// else if (strncmp(cmd, "temp ", 5) == 0)
// {
// int id = atoi(&cmd[5]);
// if (id < 0 || id >= devices_found)
// {
// printf("unknown ID\r\n");
// return;
// }
// ds_reset();
// ds_write_byte(0x55);
// for (int j = 0; j < 8; j++)
// ds_write_byte(roms[id][j]);
// ds_write_byte(0x44);
// HAL_Delay(750);
// ds_reset();
// ds_write_byte(0x55);
// for (int j = 0; j < 8; j++)
// ds_write_byte(roms[id][j]);
// ds_write_byte(0xBE);
// uint8_t tl = ds_read_byte();
// uint8_t th = ds_read_byte();
// int16_t t = (th << 8) | tl;
// float temp = t / 16.0;
// printf("T[%d] = %.2f C\r\n", id, temp);
// }
// else if (strncmp(cmd, "ts_1_open_minus",15 ) == 0)
// {
// temp_sense[0].t_open-=1;
//
// }
// else if (strncmp(cmd, "ts_1_open_plus",14 ) == 0)
// {
// temp_sense[0].t_open+=1;
//
// }
// else if (strncmp(cmd, "ts_1_close_minus",16 ) == 0)
// {
// temp_sense[0].t_close-=1;
//
// }
// else if (strncmp(cmd, "ts_1_close_plus",15 ) == 0)
// {
//
// temp_sense[0].t_close+=1;
// }
// else if (strncmp(cmd, "init",4 ) == 0)
// {
// init=1;
// printf("init %s\r\n", "OK");
// }
// else if
// (strncmp(cmd, "set_temp ", 9) == 0)
// {
// uint8_t sense_num = (atoi(&cmd[9])&0x7c0)>>10;
// int parse_uart=atoi(&cmd[10]);
//
// temp_sense[sense_num].t_set=(float)parse_uart/10.;
// printf("temp_sense %i %s\r\n",sense_num, "OK");
//
//
// }
// else if (strncmp(cmd, "temp ", 5) == 0)
// {
//
//
// }
// else
// {
// printf("unknown CMD: %s\r\n", cmd);
// for (int i=0;i<63;i++)
// rx_buffer[i]=0;
//
// }
//}

106
john103C6T6/Core/Src/adc.c Normal file
View File

@@ -0,0 +1,106 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.c
* @brief This file provides code for the configuration
* of the ADC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
ADC_HandleTypeDef hadc1;
/* ADC1 init function */
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* ADC1 clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspDeInit 0 */
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC1_CLK_DISABLE();
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,646 @@
/**
******************************************************************************
* @file dallas_tools.c
* @brief Драйвер для работы с датчиками температуры DS18B20
******************************************************************************
@details
Библиотека предназначена для работы с цифровыми датчиками температуры DS18B20
по однопроводному интерфейсу 1-Wire. Реализована поддержка инициализации, поиска,
добавления и работы с несколькими датчиками.
@verbatim
==============================================================================
## Основные задачи библиотеки ##
==============================================================================
Эта библиотека предоставляет следующие основные функции:
(+) Инициализация шины 1-Wire и обнаружение подключённых датчиков
(+) Инициализация структуры датчика по:
- ROM-адресу
- пользовательским байтам (TH, TL, UserByte3, UserByte4)
- порядковому номеру в списке найденных устройств
(+) Конфигурация разрешения измерения
(+) Чтение температуры
(+) Замена «потерянного» датчика
(+) Деинициализация структуры датчика
==============================================================================
## Быстрый старт ##
==============================================================================
Пример последовательности инициализации и использования:
1. Определение пина и таймера для OneWire в ow_port.h:
#define OW_GPIO_Port GPIOB
#define OW_Pin_Numb 0
#define OW_Pin (1<<OW_Pin_Numb)
#define OW_TIM TIM3
#define OW_TIM_1US_PERIOD 24
2. Подключение библиотеки и настройка таймеров:
#include "dallas_tools.h"
MX_TIM_Init();
3. Инициализация шины и поиск датчиков:
Dallas_BusFirstInit(&htim);
4. Инициализация датчика Dallas_SensorHandleTypeDef по одному из методов:
sens1.Init.init_func = &Dallas_SensorInitByInd; // по индексу
sens1.Init.InitParam.Ind = 0; // порядковый номер найденного датика для инициализации
sens2.Init.init_func = &Dallas_SensorInitByROM; // по ROM-адресу
sens2.Init.InitParam.ROM = 0; // ROM датика для инициализации
sens3.Init.init_func = &Dallas_SensorInitByUserBytes; // по пользовательским байтам
sens3.Init.InitParam.UserBytes.UserByte1 = 1; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte2 = 2; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte3 = 3; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte4 = 4; // UseBytes датика для инициализации
5. Инициализация структуруы датчика:
Dallas_AddNewSensors(&hdallas, &sens);
6. Работа с датчиком:
Dallas_StartConvertTAll(hdallas, DALLAS_WAIT_BUS, 0);
Dallas_ReadTemperature(&sens);
==============================================================================
## Требуемые зависимости ##
==============================================================================
Для работы библиотеки требуется:
- Драйвер OneWire (файлы onewire.c/h и ow_port.c/.h)
- Драйвер DS18B20 (файлы ds18b20.c/h)
@endverbatim
==============================================================================
*****************************************************************************/
/* Includes ----------------------------------------------------------------*/
#include "dallas_tools.h"
#include "string.h"
/* Declarations and definitions --------------------------------------------*/
DALLAS_HandleTypeDef hdallas;
/* Functions ---------------------------------------------------------------*/
/**
* @brief Функция для иниицализации шины OW для датчиков
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_BusFirstInit(TIM_HandleTypeDef *htim)
{
if(htim == NULL)
return HAL_ERROR;
HAL_StatusTypeDef result;
HAL_TIM_Base_Start(htim);
hdallas.onewire = &OW;
hdallas.ds_devices = &DS;
OW.DataPin = OW_Pin;
OW.DataPort = OW_GPIO_Port;
/* Инициализация onewire и поиск датчиков*/
OneWire_Init(&OW);
return DS18B20_Search(&DS, &OW) != HAL_OK;
}
/**
* @brief Функция для иниицализации нового датчика в структуре
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_AddNewSensors(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
sensor->hdallas = hdallas;
result = sensor->Init.init_func(hdallas, sensor);
return result;
}
/**
* @brief Функция для нахождения нового датчика на место потерянного
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_ReplaceLostedSensor(DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
result = Dallas_IsConnected(sensor);
if(sensor->isLost)
{
if(DS18B20_Search(sensor->hdallas->ds_devices, sensor->hdallas->onewire) != HAL_OK)
return HAL_ERROR;
if(sensor->Init.init_func(sensor->hdallas, sensor) != HAL_OK)
return HAL_ERROR;
return HAL_OK;
}
else
{
return HAL_BUSY; // датчик не потерян
}
}
/**
* @brief Запускает измерение температуры на всех датчиках
* @param hdallas Указатель на хендл для общения с датчиками
* @param waitCondition Условие ожидания завершения преобразования
* @param dallas_delay_ms Время ожидания окончания конверсии
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_StartConvertTAll(DALLAS_HandleTypeDef *hdallas, DALLAS_WaitConvertionTypeDef waitCondition, uint8_t dallas_delay_ms)
{
HAL_StatusTypeDef result;
uint8_t rxDummyData;
if(hdallas == NULL)
return HAL_ERROR;
// Отправка команды начала преобразования температуры
result = DS18B20_StartConvTAll(hdallas->onewire);
if(result != HAL_OK)
{
return result;
}
// // Проверка что преобразование началось
// if(OneWire_ReadBit(onewire) == 1)
// return HAL_ERROR;
// Ожидание завершения преобразования, путем проверки шины
if (waitCondition == DALLAS_WAIT_BUS)
{
result = DS18B20_WaitForEndConvertion(hdallas->onewire);
return result;
}
// Ожидание завершения преобразования, путем задержки
if (waitCondition == DALLAS_WAIT_DELAY)
{
uint32_t delayValueMs = 0;
switch (dallas_delay_ms)
{
case DALLAS_CONFIG_9_BITS:
delayValueMs = DALLAS_DELAY_MS_9_BITS;
break;
case DALLAS_CONFIG_10_BITS:
delayValueMs = DALLAS_DELAY_MS_10_BITS;
break;
case DALLAS_CONFIG_11_BITS:
delayValueMs = DALLAS_DELAY_MS_11_BITS;
break;
case DALLAS_CONFIG_12_BITS:
delayValueMs = DALLAS_DELAY_MS_12_BITS;
break;
default:
break;
}
HAL_Delay(delayValueMs);
}
return result;
}
/**
* @brief Измеряет температуру на датчике
* @param sensor Указатель на структуру датчика
* @param waitCondition Условие ожидания завершения преобразования
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_ConvertT(DALLAS_SensorHandleTypeDef *sensor, DALLAS_WaitConvertionTypeDef waitCondition)
{
HAL_StatusTypeDef result;
uint8_t rxDummyData;
if(sensor == NULL)
return HAL_ERROR;
if(sensor->isInitialized == 0)
return HAL_ERROR;
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_IsConnected(sensor);
if (result != HAL_OK)
return result;
// Отправка команды начала преобразования температуры
result = DS18B20_StartConvT(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM);
if(result != HAL_OK)
{
return result;
}
// Ожидание завершения преобразования, путем проверки шины
if (waitCondition == DALLAS_WAIT_BUS)
{
result = DS18B20_WaitForEndConvertion(sensor->hdallas->onewire);
if(result == HAL_TIMEOUT)
{
sensor->f.timeout_convertion_cnt++;
}
return result;
}
// Ожидание завершения преобразования, путем задержки
if (waitCondition == DALLAS_WAIT_DELAY)
{
uint32_t delayValueMs = 0;
switch (sensor->hdallas->scratchpad.ConfigRegister)
{
case DALLAS_CONFIG_9_BITS:
delayValueMs = DALLAS_DELAY_MS_9_BITS;
break;
case DALLAS_CONFIG_10_BITS:
delayValueMs = DALLAS_DELAY_MS_10_BITS;
break;
case DALLAS_CONFIG_11_BITS:
delayValueMs = DALLAS_DELAY_MS_11_BITS;
break;
case DALLAS_CONFIG_12_BITS:
delayValueMs = DALLAS_DELAY_MS_12_BITS;
break;
default:
break;
}
HAL_Delay(delayValueMs);
}
/* Не считываем температуру, если не выбрано ожидание окончания преобразования */
if(waitCondition != DALLAS_WAIT_NONE)
{
result = Dallas_ReadTemperature(sensor);
}
return result;
}
/**
* @brief Читает измеренную датчиком температуру
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_ReadTemperature(DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
if(sensor->isInitialized == 0)
return HAL_ERROR;
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_IsConnected(sensor);
if (result != HAL_OK)
{
return result;
}
result = DS18B20_CalcTemperature(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, (uint8_t *)&sensor->hdallas->scratchpad, &sensor->temperature);
if (result != HAL_OK)
{
sensor->f.read_temperature_err_cnt++;
return result;
}
return HAL_OK;
}
/**
* @brief Проверяет подключен ли датчик (чтение scratchpad)
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_IsConnected(DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
result = Dallas_ReadScratchpad(sensor);
if (result == HAL_OK)
{
sensor->isConnected = 1;
sensor->isLost = 0;
return HAL_OK;
}
else
{
sensor->temperature = 0;
if(sensor->isConnected == 1)
{
sensor->f.disconnect_cnt++;
}
sensor->isLost = 1;
sensor->isConnected = 0;
// Dallas_ReplaceLostedSensor(sensor);
return HAL_BUSY; // использую busy, чтобы отличать ситуацию от HAL_ERROR
}
}
/**
* @brief Записывает пользовательские байты
* @param sensor Указатель на структуру датчика
* @param UserBytes12 Пользовательские байты 1 и 2
* @param UserBytes34 Пользовательские байты 3 и 4
* @param UserBytesMask Маска, какие байты записывать, а какие нет
* @retval HAL Status
* @details старший байт - UserByte4/UserByte2, младший - UserByte3/UserByte1.
*/
HAL_StatusTypeDef Dallas_WriteUserBytes(DALLAS_SensorHandleTypeDef *sensor, uint16_t UserBytes12, uint16_t UserBytes34, uint8_t UserBytesMask)
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
if(sensor->isInitialized == 0)
return HAL_ERROR;
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_IsConnected(sensor);
if (result != HAL_OK)
return result;
result = DS18B20_WriteUserBytes(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, UserBytes12, UserBytes34, UserBytesMask);
if (result != HAL_OK)
{
sensor->f.write_err_cnt++;
return result;
}
result = Dallas_ReadScratchpad(sensor);
if (result != HAL_OK)
{
return result;
}
return result;
}
HAL_StatusTypeDef Dallas_ReadScratchpad(DALLAS_SensorHandleTypeDef *sensor)
{
if(sensor == NULL)
return HAL_ERROR;
return DS18B20_ReadScratchpad(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, (uint8_t *)&sensor->hdallas->scratchpad);
}
/**
* @brief Инициализирует структуру датчика по ROM
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t ROM[8] = {0};
ROM[0] = (sensor->Init.InitParam.ROM >> (7*8)) & 0xFF;
ROM[1] = (sensor->Init.InitParam.ROM >> (6*8)) & 0xFF;
ROM[2] = (sensor->Init.InitParam.ROM >> (5*8)) & 0xFF;
ROM[3] = (sensor->Init.InitParam.ROM >> (4*8)) & 0xFF;
ROM[4] = (sensor->Init.InitParam.ROM >> (3*8)) & 0xFF;
ROM[5] = (sensor->Init.InitParam.ROM >> (2*8)) & 0xFF;
ROM[6] = (sensor->Init.InitParam.ROM >> (1*8)) & 0xFF;
ROM[7] = (sensor->Init.InitParam.ROM >> (0*8)) & 0xFF;
if(DS18B20_IsValidAddress(ROM) != HAL_OK)
return HAL_ERROR;
uint8_t comparebytes = DALLAS_ROM_SIZE;
int ROM_ind = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
comparebytes = DALLAS_ROM_SIZE;
for(int rom_byte = 0; rom_byte < DALLAS_ROM_SIZE; rom_byte++)
{
if(hdallas->ds_devices->DevAddr[i][rom_byte] == ROM[rom_byte])
comparebytes--;
}
if(comparebytes == 0)
{
ROM_ind = i;
break;
}
}
/* Проверка присутствует ли выбранный датчик на линии */
if(comparebytes == 0)
{
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[ROM_ind]);
return result;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief Инициализирует структуру датчика по пользовательским байтам
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t UserByte1 = sensor->Init.InitParam.UserBytes.UserByte1;
uint8_t UserByte2 = sensor->Init.InitParam.UserBytes.UserByte2;
uint8_t UserByte3 = sensor->Init.InitParam.UserBytes.UserByte3;
uint8_t UserByte4 = sensor->Init.InitParam.UserBytes.UserByte4;
uint8_t UserByte12Cmp = 0;
uint8_t UserByte34Cmp = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
/* Проверка присутствует ли выбранный датчик на линии */
result = DS18B20_ReadScratchpad(hdallas->onewire, (uint8_t *)&hdallas->ds_devices->DevAddr[i], (uint8_t *)&hdallas->scratchpad);
if (result != HAL_OK)
return result;
/* Сравнение UserByte1 и UserByte2, если они не равны нулю */
if(UserByte1 | UserByte2)
{
if( (hdallas->scratchpad.tHighRegister == UserByte1) &&
(hdallas->scratchpad.tLowRegister == UserByte2))
{
UserByte12Cmp = 1;
}
}/* Если сравнение UserByte1 и UserByte2 не выбрано, то считаем что они совпадают */
else
{
UserByte12Cmp = 1;
}
/* Сравнение UserByte3 и UserByte4, если они не равны нулю */
if(UserByte3 | UserByte4)
{
if( (hdallas->scratchpad.UserByte3 == UserByte3) &&
(hdallas->scratchpad.UserByte4 == UserByte4))
{
UserByte34Cmp = 1;
}
}/* Если сравнение UserByte3 и UserByte4 не выбрано, то считаем что они одинаковые */
else
{
UserByte34Cmp = 1;
}
/* Если нашли нужный датчик - завершаем поиск */
if(UserByte12Cmp && UserByte34Cmp)
{
// sensor->isInitialized = 1;
// sensor->Init.init_func = (HAL_StatusTypeDef (*)())Dallas_SensorInitByUserBytes;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[i]);
return result;
}
}
sensor->sensROM = 0;
/* Возвращаем ошибку если не нашли */
return HAL_ERROR;
}
/**
* @brief Инициализирует структуру датчика по порядковому номеру
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
* @details Порядковый номер датчика в списке найденных.
* Т.е. каким по счету этот датчик был найден
*/
HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[sensor->Init.InitParam.Ind]);
return result;
}
/**
* @brief Инициализирует датчик для работы
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @param ROM ROM датчика, который надо инициализировать
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE])
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
if(hdallas == 0)
return HAL_ERROR;
sensor->hdallas = hdallas;
sensor->sensROM = 0;
sensor->sensROM = *(uint64_t *)(ROM);
// for(int i = 0; i < DALLAS_ROM_SIZE; i++)
// sensor->sensROM |= ((uint64_t)(*ROM)[i] << (56 - 8*i));
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_ReadScratchpad(sensor);
if (result == HAL_OK)
{
/* Установка разрешения */
result = DS18B20_SetResolution(hdallas->onewire, (uint8_t *)ROM, sensor->Init.Resolution);
if (result == HAL_OK)
{
sensor->isInitialized = 1;
return HAL_OK;
}
else
{
sensor->isInitialized = 0;
return result;
}
}
else
{
sensor->isInitialized = 0;
return result;
}
}
/**
* @brief Деинициализирует структуру датчика
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor)
{
if(sensor == NULL)
return HAL_ERROR;
memset(&sensor->f, 0, sizeof(sensor->f));
sensor->isConnected = 0;
sensor->isInitialized = 0;
sensor->isLost = 0;
sensor->temperature = 0;
sensor->sensROM = 0;
return HAL_OK;
}

View File

@@ -0,0 +1,607 @@
/**
******************************************************************************
* @file ds18b20_driver.c
* @brief This file includes the HAL/LL driver for DS18B20 1-Wire Digital
* Thermometer
******************************************************************************
*/
#include "ds18b20_driver.h"
DS18B20_Drv_t DS;
OneWire_t OW;
/**
* @brief The function is used to check valid DS18B20 ROM
* @retval Return in OK = 1, Failed = 0
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_IsValidAddress(uint8_t *ROM)
{
if(ROM == NULL)
return HAL_ERROR;
uint8_t check_family = (*ROM == DS18B20_FAMILY_CODE);
/* Calculate CRC */
uint8_t crc = OneWire_CRC8(ROM, 7);
uint8_t check_crc = (crc == ROM[7]);
/* Checks if first byte is equal to DS18B20's family code */
if(check_family && check_crc)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief The function is used to check valid DS18B20 ROM
* @retval Return in OK = 1, Failed = 0
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_IsValid(uint8_t *ROM)
{
if(ROM == NULL)
return HAL_ERROR;
if(*ROM == DS18B20_FAMILY_CODE)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief The function is used to get resolution
* @retval Return value in 9 - 12
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
*/
uint8_t DS18B20_GetResolution(OneWire_t* OW, uint8_t *ROM) {
uint8_t conf;
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
/* Check valid ROM */
if (DS18B20_IsValid(ROM) != HAL_OK)
return 0;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 4 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
/* 5th byte of scratchpad is configuration register */
conf = OneWire_ReadByte(OW);
/* Return 9 - 12 value according to number of bits */
return ((conf & 0x60) >> 5) + 9;
}
/**
* @brief The function is used as set resolution
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Resolution Resolution in 9 - 12
*/
HAL_StatusTypeDef DS18B20_SetResolution(OneWire_t* OW, uint8_t *ROM,
DS18B20_Res_t Resolution)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t th, tl, conf;
/* Check valid ROM */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
th = OneWire_ReadByte(OW);
tl = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
/* Set choosed resolution */
conf = Resolution;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, th);
OneWire_WriteByte(OW, tl);
OneWire_WriteByte(OW, conf);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
/**
* @brief The function is used as start selected ROM device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_StartConvT(OneWire_t* OW, uint8_t *ROM)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
/* Check if device is DS18B20 */
if(DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Start temperature conversion */
OneWire_WriteByte(OW, DS18B20_CMD_CONVERT);
return HAL_OK;
}
/**
* @brief The function is used as start all ROM device
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_StartConvTAll(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
/* Reset pulse */
OneWire_Reset(OW);
/* Skip rom */
OneWire_WriteByte(OW, ONEWIRE_CMD_SKIPROM);
/* Start conversion on all connected devices */
OneWire_WriteByte(OW, DS18B20_CMD_CONVERT);
return HAL_OK;
}
/**
* @brief The function is used as read temreature from device and store in selected
* destination
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Destination Pointer to return value
*/
HAL_StatusTypeDef DS18B20_CalcTemperature(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad, float *Destination)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
if(Scratchpad == NULL)
return HAL_ERROR;
if(Destination == NULL)
return HAL_ERROR;
uint16_t temperature;
uint8_t resolution;
int8_t digit, minus = 0;
float decimal;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* First two bytes of scratchpad are temperature values */
temperature = Scratchpad[0] | (Scratchpad[1] << 8);
/* Reset line */
OneWire_Reset(OW);
/* Check if temperature is negative */
if (temperature & 0x8000) {
/* Two's complement, temperature is negative */
temperature = ~temperature + 1;
minus = 1;
}
/* Get sensor resolution */
resolution = Scratchpad[4];
/* Store temperature integer digits and decimal digits */
digit = temperature >> 4;
digit |= ((temperature >> 8) & 0x7) << 4;
/* Store decimal digits */
switch (resolution) {
case DS18B20_RESOLUTION_9BITS: {
decimal = (temperature >> 3) & 0x01;
decimal *= (float)DS18B20_DECIMAL_STEP_9BIT;
} break;
case DS18B20_RESOLUTION_10BITS: {
decimal = (temperature >> 2) & 0x03;
decimal *= (float)DS18B20_DECIMAL_STEP_10BIT;
} break;
case DS18B20_RESOLUTION_11BITS: {
decimal = (temperature >> 1) & 0x07;
decimal *= (float)DS18B20_DECIMAL_STEP_11BIT;
} break;
case DS18B20_RESOLUTION_12BITS: {
decimal = temperature & 0x0F;
decimal *= (float)DS18B20_DECIMAL_STEP_12BIT;
} break;
default: {
*Destination = 0;
return HAL_ERROR;
}
}
/* Check for negative part */
decimal = digit + decimal;
if (minus) {
decimal = 0 - decimal;
}
/* Set to pointer */
*Destination = decimal;
/* Return HAL_OK, temperature valid */
return HAL_OK;
}
/**
* @brief The function is used as read scratchpad from device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Destination Pointer to Scratchpad array
*/
HAL_StatusTypeDef DS18B20_ReadScratchpad(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
if(Scratchpad == NULL)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Get data */
for (int i = 0; i < 9; i++) {
/* Read byte by byte */
Scratchpad[i] = OneWire_ReadByte(OW);
}
/* Calculate CRC */
uint8_t crc = OneWire_CRC8(Scratchpad, 8);
/* Check if CRC is ok */
if (crc != Scratchpad[8]) {
/* CRC invalid */
return HAL_ERROR;
}
return HAL_OK;
}
/**
* @brief The function is used to wait for end of convertion
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_WaitForEndConvertion(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
uint32_t tickstart = HAL_GetTick();
/* Wait until line is released, then coversion is completed */
while(OneWire_ReadBit(OW) == 0)
{
if(HAL_GetTick() - tickstart > DS18B20_DELAY_MS_MAX)
return HAL_TIMEOUT; // end of convertion has not come
}
return HAL_OK; // convertion done
}
/**
* @brief The function is used to wait for end of convertion without blocking
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_WaitForEndConvertion_NonBlocking(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
/* If line is pull down - conversion is ongoing */
if(OneWire_ReadBit(OW) == 0)
return HAL_BUSY;
else
return HAL_OK; // convertion done
}
/**
* @brief The function is used as set temperature alarm range on
* selected device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Low Low temperature alarm, value > -55, 0 = reset
* @param High High temperature alarm,, value < 125, 0 = reset
*/
HAL_StatusTypeDef DS18B20_SetTempAlarm(OneWire_t* OW, uint8_t *ROM, int8_t Low,
int8_t High)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t tl, th, conf;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
Low = ((Low < -55) || (Low == 0)) ? -55 : Low;
High = ((High > 125) || (High == 0)) ? 125 : High;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
th = OneWire_ReadByte(OW);
tl = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
th = (uint8_t)High;
tl = (uint8_t)Low;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, th);
OneWire_WriteByte(OW, tl);
OneWire_WriteByte(OW, conf);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
/**
* @brief The function is used as set user bytes with mask
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param UserBytes12 First 2 User Bytes (tHigh and tLow)
* @param UserBytes34 Second 2 User Bytes
* @param UserBytesMask Which User Bytes write, and which ignore
*/
HAL_StatusTypeDef DS18B20_WriteUserBytes(OneWire_t* OW, uint8_t *ROM, int16_t UserBytes12,
int16_t UserBytes34, uint8_t UserBytesMask)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t ub1, ub2, conf, ub3, ub4;
uint8_t UserByte1 = UserBytes12 & 0xFF;
uint8_t UserByte2 = UserBytes12 >> 8;
uint8_t UserByte3 = UserBytes34 & 0xFF;
uint8_t UserByte4 = UserBytes34 >> 8;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
ub1 = OneWire_ReadByte(OW);
ub2 = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
ub3 = OneWire_ReadByte(OW);
ub4 = OneWire_ReadByte(OW);
/* If user bytes in mask */
if(UserBytesMask & (1<<0))
{
ub1 = UserByte1;
}
if(UserBytesMask & (1<<1))
{
ub2 = UserByte2;
}
if(UserBytesMask & (1<<2))
{
ub3 = UserByte3;
}
if(UserBytesMask & (1<<3))
{
ub4 = UserByte4;
}
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, ub1);
OneWire_WriteByte(OW, ub2);
OneWire_WriteByte(OW, conf);
OneWire_WriteByte(OW, ub3);
OneWire_WriteByte(OW, ub4);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
///**
// * @brief The function is used as search device that had temperature alarm
// * triggered and store it in DS18B20 alarm data structure
// * @retval status of search, OK = 1, Failed = 0
// * @param DS DS18B20 HandleTypedef
// * @param OW OneWire HandleTypedef
// */
//uint8_t DS18B20_AlarmSearch(DS18B20_Drv_t *DS, OneWire_t* OW)
//{
// uint8_t t = 0;
// /* Reset Alarm in DS */
// for(uint8_t i = 0; i < OW->RomCnt; i++)
// {
// for(uint8_t j = 0; j < 8; j++)
// {
// DS->AlmAddr[i][j] = 0;
// }
// }
// /* Start alarm search */
// while (OneWire_Search(OW, DS18B20_CMD_ALARM_SEARCH))
// {
// /* Store ROM of device which has alarm flag set */
// OneWire_GetDevRom(OW, DS->AlmAddr[t]);
// t++;
// }
// return (t > 0) ? 1 : 0;
//}
/**
* @brief The function is used to initialize the DS18B20 sensor, and search
* for all ROM along the line. Store in DS18B20 data structure
* @retval Rom detect status, OK = 1, No Rom detected = 0
* @param DS DS18B20 HandleTypedef
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_Search(DS18B20_Drv_t *DS, OneWire_t *OW)
{
if(OW == NULL)
return HAL_ERROR;
OW->RomCnt = 0;
/* Search all OneWire devices ROM */
while(1)
{
/* Start searching for OneWire devices along the line */
if(OneWire_Search(OW, ONEWIRE_CMD_SEARCHROM) != 1) break;
/* Get device ROM */
OneWire_GetDevRom(OW, DS->DevAddr[OW->RomCnt]);
OW->RomCnt++;
}
for(int i = OW->RomCnt; i < DS18B20_DEVICE_AMOUNT; i++)
{
for(int j = 0; j < 8; j++)
DS->DevAddr[i][j] = 0;
}
if(OW->RomCnt > 0)
return HAL_OK;
else
return HAL_BUSY;
}

112
john103C6T6/Core/Src/gpio.c Normal file
View File

@@ -0,0 +1,112 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, One_wire_Pin|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = One_wire_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(One_wire_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PA2 PA3 PA4 PA5
PA6 PA7 PA8 PA9
PA10 */
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9
|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 PB1 PB2 PB10
PB11 PB12 PB13 PB14
PB15 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

398
john103C6T6/Core/Src/main.c Normal file
View File

@@ -0,0 +1,398 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dallas_tools.h"
#include "def.h"
#include <stdio.h>
#include "rs_message.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint16_t iter,cnt=5;
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
float temperature;
extern uint8_t roms[MAX_DEVICES][8];
//extern uint8_t devices_found ;
uint8_t init=1;
//TEMP temp_sense[30];
float set_temp_old[30];
char rx_buffer[64];
uint8_t rx_index = 0;
char command_ready = 0;
uint8_t uart_byte = 0;
uint8_t first_in=1;
DALLAS_SensorHandleTypeDef sens[30];
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM1_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
//TIM1->DIER |= TIM_DIER_UIE;
// HAL_TIM_Base_MspInit(&htim1);
// HAL_TIM_Base_Start(&htim1);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR^=(1<<13);
HAL_Delay(50);
GPIOC->ODR&=~(1<<13);
//DS18B20_Init(GPIOA, GPIO_PIN_1);
MODBUS_FirstInit();
uint8_t uart_byte = 0;
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
//HAL_UART_Receive_IT(&huart1, &uart_byte, 1);
Dallas_BusFirstInit(&htim1);
// èíèöèàëèçàöèÿ ïî ïîðÿäêó íàéäåííûõ äàò÷èêîâ
// Èíèöèàëèçàöèÿ ïî èíäåêñó (ïîðÿäêîâîìó íîìåðó íàéäåííîãî äàò÷èêà)
for ( int i=0; i<hdallas.onewire->RomCnt;i++)
{
// Èíèöèàëèçàöèÿ ïî ROM-àäðåñó
//sens[i].Init.init_func = &Dallas_SensorInitByROM;
// sens[i].Init.InitParam.ROM = rom_address;
sens[i].Init.InitParam.Ind = i;
sens[i].Init.init_func = &Dallas_SensorInitByInd;
sens[i].Init.Resolution = DALLAS_CONFIG_9_BITS;
sens[i].set_temp =20.;
sens[i].hyst =3;
Dallas_AddNewSensors(&hdallas, &sens[i]);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (init)
{
init=0;
// init_all_T_sense();
DS18B20_Search(&DS, &OW);
}
Dallas_StartConvertTAll(&hdallas,DALLAS_WAIT_BUS,0);
for(int i=0;i<hdallas.onewire->RomCnt;i++)
{
Dallas_ReadTemperature(&sens[i]);
sens[i].set_temp = MB_DATA.InRegs.set_Temp[i];
MB_DATA.InRegs.sens_Temp[i]=sens[i].temperature*10;
if (sens[i].temperature<sens[i].set_temp-sens[i].hyst)
{
GPIOC->ODR|=1<<13;
}
else
if (sens[i].temperature>sens[i].set_temp+sens[i].hyst)
{
GPIOC->ODR&=~(1<<13);
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//iwdg_refresh();
//HAL_Delay(200);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
void iwdg_refresh(void)
{
IWDG->KR = 0xAAAA; // Ñáðîñèòü òàéìåð
}
//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
//{
// if (huart->Instance == USART1)
// {
// if(first_in)
// {
// first_in=0;
// rx_index = 0;
//
// }
//
//
//
// static uint8_t ch;
// HAL_UART_Receive_IT(&huart1, &ch, 1);
// if (ch == '\r' || ch == '\n')
// {
// rx_buffer[rx_index] = 0;
// command_ready = 1;
// rx_index = 0;
// first_in=1;
//
// }
// else
// {
// if (rx_index < sizeof(rx_buffer) - 1)
// {
// rx_buffer[rx_index++] = ch;
// }
// }
// }
//}
//uint16_t handle_valves(TEMP* tmp_sense )
//{
//
// if (temp_sense[0].state==STATE_OPEN_VALVE)
// {
// GPIOC->ODR|=1<<14;
// }
// else
// if (temp_sense[0].state==STATE_CLOSE_VALVE)
// {
// GPIOC->ODR&=~(1<<14);
// }
//
// return 1;
//
//}
//void init_all_T_sense(void)
//{
// //ds_search_devices();
// for(int i=0;i<hdallas.onewire->RomCnt;i++)
//{
// temp_sense[i].id[0]=roms[i][0]<<0|roms[i][1]<<8|roms[i][2]<<16|roms[i][3]<<24;
// temp_sense[i].id[1]=roms[i][4]<<0|roms[i][5]<<8|roms[i][6]<<16|roms[i][7]<<24;
// temp_sense[i].count =i+1;
// temp_sense[i].location=1;
// temp_sense[i].t_open=22;
// temp_sense[i].t_close=18;
// temp_sense[i].status_T_sense=1;
//}
//}
/* USER CODE END 4 */
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM3 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM3) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

View File

@@ -0,0 +1,379 @@
/**
******************************************************************************
* @file onewire.c
* @brief This file includes the HAL/LL driver for OneWire devices
******************************************************************************
*/
#include "onewire.h"
/**
* @brief The internal function is used to write bit
* @param OW OneWire HandleTypedef
* @param bit bit in 0 or 1
*/
void OneWire_WriteBit(OneWire_t* OW, uint8_t bit)
{
if(OW == NULL)
return;
#ifndef ONEWIRE_UART_H
__disable_irq();
if(bit)
{
/* Set line low */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
/* Forming pulse */
OneWire_Delay_us(ONEWIRE_WRITE_1_US);
/* Release line (pull up line) */
OneWire_Pin_Mode(OW, Input);
/* Wait for 55 us and release the line */
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US);
OneWire_Pin_Mode(OW, Input);
}else{
/* Set line low */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
/* Forming pulse */
OneWire_Delay_us(ONEWIRE_WRITE_0_US);
/* Release line (pull up line) */
OneWire_Pin_Mode(OW, Input);
/* Wait for 5 us and release the line */
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US);
OneWire_Pin_Mode(OW, Input);
}
__enable_irq();
#else
OneWireUART_ProcessBit(onewire_uart, bit);
#endif
}
/**
* @brief The function is used to read bit
* @retval bit
* @param OW OneWire HandleTypedef
*/
uint8_t OneWire_ReadBit(OneWire_t* OW)
{
if(OW == NULL)
return 0;
__disable_irq();
uint8_t bit = 0;
#ifndef ONEWIRE_UART_H
/* Line low */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
OneWire_Delay_us(ONEWIRE_READ_CMD_US);
/* Release line */
OneWire_Pin_Mode(OW, Input);
OneWire_Delay_us(ONEWIRE_READ_DELAY_US);
/* Read line value */
bit = OneWire_Pin_Read(OW);
/* Wait 50us to complete 60us period */
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US);
__enable_irq();
#else
bit = OneWireUART_ProcessBit(onewire_uart, 1);
#endif
/* Return bit value */
return bit;
}
/**
* @brief The function is used to write byte
* @param OW OneWire HandleTypedef
* @param byte byte to write
*/
void OneWire_WriteByte(OneWire_t* OW, uint8_t byte)
{
if(OW == NULL)
return;
#ifndef ONEWIRE_UART_H
uint8_t bit = 8;
/* Write 8 bits */
while (bit--) {
/* LSB bit is first */
OneWire_WriteBit(OW, byte & 0x01);
byte >>= 1;
}
#else
OneWireUART_ProcessByte(onewire_uart, byte);
#endif
}
/**
* @brief The function is used to read byte
* @retval byte from device
* @param OW OneWire HandleTypedef
*/
uint8_t OneWire_ReadByte(OneWire_t* OW)
{
if(OW == NULL)
return 0;
uint8_t byte = 0;
#ifndef ONEWIRE_UART_H
uint8_t bit = 8;
while (bit--) {
byte >>= 1;
byte |= (OneWire_ReadBit(OW) << 7);
}
#else
byte = OneWireUART_ProcessByte(onewire_uart, 0xFF);
#endif
return byte;
}
/**
* @brief The function is used to reset device
* @retval respond from device
* @param OW OneWire HandleTypedef
*/
uint8_t OneWire_Reset(OneWire_t* OW)
{
if(OW == NULL)
return 1;
#ifndef ONEWIRE_UART_H
/* Line low, and wait 480us */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
OneWire_Delay_us(ONEWIRE_RESET_PULSE_US);
/* Release line and wait for 70us */
OneWire_Pin_Mode(OW, Input);
OneWire_Delay_us(ONEWIRE_PRESENCE_WAIT_US);
/* Check bit value */
uint8_t rslt = OneWire_Pin_Read(OW);
/* Delay for 410 us */
OneWire_Delay_us(ONEWIRE_PRESENCE_DURATION_US);
#else
uint8_t rslt = 0;
if(OneWireUART_Reset(onewire_uart) == HAL_OK)
rslt = 0;
else
rslt = 1;
#endif
return rslt;
}
/**
* @brief The function is used to search device
* @retval Search result
* @param OW OneWire HandleTypedef
*/
uint8_t OneWire_Search(OneWire_t* OW, uint8_t Cmd)
{
if(OW == NULL)
return 0;
uint8_t id_bit_number = 1;
uint8_t last_zero = 0;
uint8_t rom_byte_number = 0;
uint8_t search_result = 0;
uint8_t rom_byte_mask = 1;
uint8_t id_bit, cmp_id_bit, search_direction;
/* if the last call was not the last one */
if (!OW->LastDeviceFlag)
{
if (OneWire_Reset(OW))
{
OW->LastDiscrepancy = 0;
OW->LastDeviceFlag = 0;
OW->LastFamilyDiscrepancy = 0;
return 0;
}
// issue the search command
OneWire_WriteByte(OW, Cmd);
// loop to do the search
do {
// read a bit and its complement
id_bit = OneWire_ReadBit(OW);
cmp_id_bit = OneWire_ReadBit(OW);
// check for no devices on 1-wire
if ((id_bit == 1) && (cmp_id_bit == 1))
{
break;
} else {
// all devices coupled have 0 or 1
if (id_bit != cmp_id_bit)
{
search_direction = id_bit; // bit write value for search
} else {
/* if this discrepancy if before the Last Discrepancy
* on a previous next then pick the same as last time */
if (id_bit_number < OW->LastDiscrepancy)
{
search_direction = ((OW->RomByte[rom_byte_number] & rom_byte_mask) > 0);
} else {
// if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == OW->LastDiscrepancy);
}
// if 0 was picked then record its position in LastZero
if (search_direction == 0)
{
last_zero = id_bit_number;
// check for Last discrepancy in family
if (last_zero < 9)
{
OW->LastFamilyDiscrepancy = last_zero;
}
}
}
/* set or clear the bit in the ROM byte rom_byte_number
* with mask rom_byte_mask */
if (search_direction == 1)
{
OW->RomByte[rom_byte_number] |= rom_byte_mask;
} else {
OW->RomByte[rom_byte_number] &= ~rom_byte_mask;
}
// serial number search direction write bit
OneWire_WriteBit(OW, search_direction);
/* increment the byte counter id_bit_number and shift the
* mask rom_byte_mask */
id_bit_number++;
rom_byte_mask <<= 1;
/* if the mask is 0 then go to new SerialNum byte
* rom_byte_number and reset mask */
if (rom_byte_mask == 0)
{
rom_byte_number++;
rom_byte_mask = 1;
}
}
} while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7
if the search was successful then */
if (!(id_bit_number < 65))
{
/* search successful so set LastDiscrepancy, LastDeviceFlag,
* search_result */
OW->LastDiscrepancy = last_zero;
// check for last device
if (OW->LastDiscrepancy == 0) {
OW->LastDeviceFlag = 1;
}
search_result = 1;
}
}
/* if no device found then reset counters so next 'search' will be like a
* first */
if (!search_result || !OW->RomByte[0])
{
OW->LastDiscrepancy = 0;
OW->LastDeviceFlag = 0;
OW->LastFamilyDiscrepancy = 0;
search_result = 0;
}
return search_result;
}
/**
* @brief The function is used get ROM full address
* @param OW OneWire HandleTypedef
* @param ROM Pointer to device ROM
*/
void OneWire_GetDevRom(OneWire_t* OW, uint8_t *ROM)
{
for (uint8_t i = 0; i < 8; i++) {
*(ROM + i) = OW->RomByte[i];
}
}
/**
* @brief The function is used to initialize OneWire Communication
* @param OW OneWire HandleTypedef
*/
void OneWire_Init(OneWire_t* OW)
{
OneWire_Pin_Mode(OW, Output);
OneWire_Pin_Level(OW, 1);
OneWire_Delay_us(1000);
OneWire_Pin_Level(OW, 0);
OneWire_Delay_us(1000);
OneWire_Pin_Level(OW, 1);
OneWire_Delay_us(2000);
/* Reset the search state */
OW->LastDiscrepancy = 0;
OW->LastDeviceFlag = 0;
OW->LastFamilyDiscrepancy = 0;
OW->RomCnt = 0;
}
/**
* @brief The function is used selected specific device ROM
* @param OW OneWire HandleTypedef
* @param ROM Pointer to device ROM
*/
void OneWire_MatchROM(OneWire_t* OW, uint8_t *ROM)
{
OneWire_WriteByte(OW, ONEWIRE_CMD_MATCHROM);
for (uint8_t i = 0; i < 8; i++)
{
OneWire_WriteByte(OW, *(ROM + i));
}
}
/**
* @brief The function is used to access to all ROM
* @param OW OneWire HandleTypedef
*/
void OneWire_Skip(OneWire_t* OW)
{
OneWire_WriteByte(OW, ONEWIRE_CMD_SKIPROM);
}
/**
* @brief The function is used check CRC
* @param Addr Pointer to address
* @param ROM Number of byte
*/
uint8_t OneWire_CRC8(uint8_t *Addr, uint8_t Len)
{
uint8_t crc = 0;
uint8_t inbyte, i, mix;
while (Len--)
{
inbyte = *Addr++;
for (i = 8; i; i--)
{
mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
crc ^= (mix) ? 0x8C : 0;
inbyte >>= 1;
}
}
return crc;
}

View File

@@ -0,0 +1,122 @@
/**
******************************************************************************
* @file ow_port.c
* @brief This file includes the driver for port for OneWire purposes
******************************************************************************
*/
#include "ow_port.h"
#include "onewire.h"
#include "tim.h"
uint32_t pin_pos = (OW_Pin_Numb < 8) ? (OW_Pin_Numb * 4) : ((OW_Pin_Numb - 8) * 4);
/**
* @brief The internal function is used as gpio pin mode
* @param OW OneWire HandleTypedef
* @param Mode Input or Output
*/
void OneWire_Pin_Mode(OneWire_t* OW, PinMode Mode)
{
#ifdef CMSIS_Driver
volatile uint32_t *config_reg = (OW_Pin_Numb < 8) ? &(OW->DataPort->CRL) : &(OW->DataPort->CRH);
// —брос текущих 4 бит (CNF + MODE)
*config_reg &= ~(0xF << pin_pos);
if (Mode == Input)
{
// ¬ход с подт¤жкой или без Ц например, CNF = 0b01, MODE = 0b00
// «десь устанавливаем вход с подт¤жкой:
*config_reg |= (0x8 << pin_pos); // CNF=10, MODE=00 (вход с подт¤жкой)
OW->DataPort->ODR |= (1 << OW_Pin_Numb); // ¬ключить подт¤жку вверх
}
else
{
// ¬ыход push-pull, 2 ћ√ц Ц MODE = 0b10, CNF = 0b00
*config_reg |= (0x2 << pin_pos);
}
#else
#ifdef LL_Driver
if(Mode == Input)
{
LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_INPUT);
}else{
LL_GPIO_SetPinMode(OW->DataPort, OW->DataPin, LL_GPIO_MODE_OUTPUT);
}
#else
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = OW->DataPin;
if(Mode == Input)
{
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
}else{
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
}
HAL_GPIO_Init(OW->DataPort, &GPIO_InitStruct);
#endif
#endif
}
/**
* @brief The internal function is used as gpio pin level
* @param OW OneWire HandleTypedef
* @param Mode Level: Set/High = 1, Reset/Low = 0
*/
void OneWire_Pin_Level(OneWire_t* OW, uint8_t Level)
{
#ifdef CMSIS_Driver
if (Level != GPIO_PIN_RESET)
{
OW->DataPort->BSRR = OW->DataPin;
}
else
{
OW->DataPort->BSRR = (uint32_t)OW->DataPin << 16u;
}
#else
#ifdef LL_Driver
if(Level == 1)
{
LL_GPIO_SetOutputPin(OW->DataPort, OW->DataPin);
}else{
LL_GPIO_ResetOutputPin(OW->DataPort, OW->DataPin);
}
#else
HAL_GPIO_WritePin(OW->DataPort, OW->DataPin, Level);
#endif
#endif
}
/**
* @brief The internal function is used to read data pin
* @retval Pin level status
* @param OW OneWire HandleTypedef
*/
uint8_t OneWire_Pin_Read(OneWire_t* OW)
{
#ifdef CMSIS_Driver
return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0;
#else
#ifdef LL_Driver
return ((OW->DataPort->IDR & OW->DataPin) != 0x00U) ? 1 : 0;
#else6
return HAL_GPIO_ReadPin(OW->DataPort, OW->DataPin);
#endif
#endif
}
uint32_t tim_1us_period = OW_TIM_1US_PERIOD;
void OneWire_Delay_us(uint32_t us)
{
uint32_t ticks = us * tim_1us_period;
uint16_t start = OW_TIM->CNT;
uint32_t elapsed = 0;
uint16_t prev = start;
while (elapsed < ticks)
{
uint16_t curr = OW_TIM->CNT;
uint16_t delta = (uint16_t)(curr - prev); // учЄт переполнени¤
elapsed += delta;
prev = curr;
}
}

View File

@@ -0,0 +1,87 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
*/
__HAL_AFIO_REMAP_SWJ_NOJTAG();
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,136 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_timebase_tim.c
* @brief HAL time base based on the hardware TIM.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_tim.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim3;
/* Private function prototypes -----------------------------------------------*/
void TIM3_IRQHandler(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief This function configures the TIM3 as a time base source.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
* @param TickPriority: Tick interrupt priority.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
RCC_ClkInitTypeDef clkconfig;
uint32_t uwTimclock, uwAPB1Prescaler = 0U;
uint32_t uwPrescalerValue = 0U;
uint32_t pFLatency;
HAL_StatusTypeDef status = HAL_OK;
/* Enable TIM3 clock */
__HAL_RCC_TIM3_CLK_ENABLE();
/* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Get APB1 prescaler */
uwAPB1Prescaler = clkconfig.APB1CLKDivider;
/* Compute TIM3 clock */
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
{
uwTimclock = HAL_RCC_GetPCLK1Freq();
}
else
{
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
}
/* Compute the prescaler value to have TIM3 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
/* Initialize TIM3 */
htim3.Instance = TIM3;
/* Initialize TIMx peripheral as follow:
+ Period = [(TIM3CLK/1000) - 1]. to have a (1/1000) s time base.
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+ ClockDivision = 0
+ Counter direction = Up
*/
htim3.Init.Period = (1000000U / 1000U) - 1U;
htim3.Init.Prescaler = uwPrescalerValue;
htim3.Init.ClockDivision = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
status = HAL_TIM_Base_Init(&htim3);
if (status == HAL_OK)
{
/* Start the TIM time Base generation in interrupt mode */
status = HAL_TIM_Base_Start_IT(&htim3);
if (status == HAL_OK)
{
/* Enable the TIM3 global Interrupt */
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
/* Configure the TIM IRQ priority */
HAL_NVIC_SetPriority(TIM3_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
status = HAL_ERROR;
}
}
}
/* Return function status */
return status;
}
/**
* @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM3 update interrupt.
* @param None
* @retval None
*/
void HAL_SuspendTick(void)
{
/* Disable TIM3 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim3, TIM_IT_UPDATE);
}
/**
* @brief Resume Tick increment.
* @note Enable the tick increment by Enabling TIM3 update interrupt.
* @param None
* @retval None
*/
void HAL_ResumeTick(void)
{
/* Enable TIM3 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
}

View File

@@ -0,0 +1,313 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "rs_message.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart1;
extern TIM_HandleTypeDef htim3;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M3 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles TIM1 break interrupt.
*/
void TIM1_BRK_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_BRK_IRQn 0 */
/* USER CODE END TIM1_BRK_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_BRK_IRQn 1 */
/* USER CODE END TIM1_BRK_IRQn 1 */
}
/**
* @brief This function handles TIM1 update interrupt.
*/
void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
//GPIOC->ODR^=(1<<13);
/* USER CODE END TIM1_UP_IRQn 1 */
}
/**
* @brief This function handles TIM1 trigger and commutation interrupts.
*/
void TIM1_TRG_COM_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_TRG_COM_IRQn 0 */
/* USER CODE END TIM1_TRG_COM_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_TRG_COM_IRQn 1 */
/* USER CODE END TIM1_TRG_COM_IRQn 1 */
}
/**
* @brief This function handles TIM1 capture compare interrupt.
*/
void TIM1_CC_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_CC_IRQn 0 */
/* USER CODE END TIM1_CC_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_CC_IRQn 1 */
/* USER CODE END TIM1_CC_IRQn 1 */
}
/**
* @brief This function handles TIM2 global interrupt.
*/
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */
RS_TIM_Handler(&hmodbus1);
/* USER CODE END TIM2_IRQn 1 */
}
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
static uint8_t first_in=1;
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
if (first_in)
{
first_in=0;
}
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
RS_UART_Handler(&hmodbus1);
/* USER CODE END USART1_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,406 @@
/**
******************************************************************************
* @file system_stm32f1xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
*
* 1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
* factors, AHB/APBx prescalers and Flash settings).
* This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f1xx_xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
* configure the system clock before to branch to main program.
*
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
* the product used), refer to "HSE_VALUE".
* When HSE is used as system clock source, directly or through PLL, and you
* are using different crystal you have to adapt the HSE value to your own
* configuration.
*
******************************************************************************
* @attention
*
* Copyright (c) 2017-2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f1xx_system
* @{
*/
/** @addtogroup STM32F1xx_System_Private_Includes
* @{
*/
#include "stm32f1xx.h"
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Defines
* @{
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */
/*!< Uncomment the following line if you need to use external SRAM */
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Variables
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 8000000;
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
* @{
*/
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
* that HSE_VALUE is same as the real frequency of the crystal used.
* Otherwise, this function may have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
* @param None
* @retval None
*/
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
#if defined(STM32F105xC) || defined(STM32F107xC)
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
#endif /* STM32F105xC */
#if defined(STM32F100xB) || defined(STM32F100xE)
uint32_t prediv1factor = 0U;
#endif /* STM32F100xB or STM32F100xE */
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00U: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
break;
case 0x04U: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE;
break;
case 0x08U: /* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
#if !defined(STM32F105xC) && !defined(STM32F107xC)
pllmull = ( pllmull >> 18U) + 2U;
if (pllsource == 0x00U)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
}
else
{
#if defined(STM32F100xB) || defined(STM32F100xE)
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
#else
/* HSE selected as PLL clock entry */
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
{/* HSE oscillator clock divided by 2 */
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
}
else
{
SystemCoreClock = HSE_VALUE * pllmull;
}
#endif
}
#else
pllmull = pllmull >> 18U;
if (pllmull != 0x0DU)
{
pllmull += 2U;
}
else
{ /* PLL multiplication factor = PLL input clock * 6.5 */
pllmull = 13U / 2U;
}
if (pllsource == 0x00U)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
}
else
{/* PREDIV1 selected as PLL clock entry */
/* Get PREDIV1 clock source and division factor */
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
if (prediv1source == 0U)
{
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
}
else
{/* PLL2 clock selected as PREDIV1 clock entry */
/* Get PREDIV2 division factor and PLL2 multiplication factor */
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
}
}
#endif /* STM32F105xC */
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK clock frequency ----------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
/**
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
* before jump to __main
* @param None
* @retval None
*/
#ifdef DATA_IN_ExtSRAM
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
* This function configures the external SRAM mounted on STM3210E-EVAL
* board (STM32 High density devices). This SRAM will be used as program
* data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmpreg;
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
required, then adjust the Register Addresses */
/* Enable FSMC clock */
RCC->AHBENR = 0x00000114U;
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
RCC->APB2ENR = 0x000001E0U;
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
(void)(tmpreg);
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
/*---------------- SRAM Address lines configuration -------------------------*/
/*---------------- NOE and NWE configuration --------------------------------*/
/*---------------- NE3 configuration ----------------------------------------*/
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
GPIOD->CRL = 0x44BB44BBU;
GPIOD->CRH = 0xBBBBBBBBU;
GPIOE->CRL = 0xB44444BBU;
GPIOE->CRH = 0xBBBBBBBBU;
GPIOF->CRL = 0x44BBBBBBU;
GPIOF->CRH = 0xBBBB4444U;
GPIOG->CRL = 0x44BBBBBBU;
GPIOG->CRH = 0x444B4B44U;
/*---------------- FSMC Configuration ---------------------------------------*/
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
FSMC_Bank1->BTCR[4U] = 0x00001091U;
FSMC_Bank1->BTCR[5U] = 0x00110212U;
}
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

191
john103C6T6/Core/Src/tim.c Normal file
View File

@@ -0,0 +1,191 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.c
* @brief This file provides code for the configuration
* of the TIM instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;
/* TIM1 init function */
void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
/* USER CODE END TIM1_Init 2 */
}
/* TIM2 init function */
void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7199;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspInit 0 */
/* USER CODE END TIM1_MspInit 0 */
/* TIM1 clock enable */
__HAL_RCC_TIM1_CLK_ENABLE();
/* TIM1 interrupt Init */
HAL_NVIC_SetPriority(TIM1_BRK_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn);
HAL_NVIC_SetPriority(TIM1_UP_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn);
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
/* USER CODE BEGIN TIM1_MspInit 1 */
/* USER CODE END TIM1_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
/* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspInit 1 */
/* USER CODE END TIM2_MspInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspDeInit 0 */
/* USER CODE END TIM1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM1_CLK_DISABLE();
/* TIM1 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM1_BRK_IRQn);
HAL_NVIC_DisableIRQ(TIM1_UP_IRQn);
HAL_NVIC_DisableIRQ(TIM1_TRG_COM_IRQn);
HAL_NVIC_DisableIRQ(TIM1_CC_IRQn);
/* USER CODE BEGIN TIM1_MspDeInit 1 */
/* USER CODE END TIM1_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspDeInit 0 */
/* USER CODE END TIM2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM2_CLK_DISABLE();
/* TIM2 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspDeInit 1 */
/* USER CODE END TIM2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,124 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_AFIO_REMAP_USART1_ENABLE();
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */