Обновлены шапки и по мелочи
This commit is contained in:
246
Core/App/adc.c
246
Core/App/adc.c
@@ -12,7 +12,7 @@
|
||||
* - Установку callback-функций для событий:
|
||||
* - завершение секвенсора
|
||||
* - половина буфера
|
||||
* - полный буфер
|
||||
* - полный буфера
|
||||
* - ошибка
|
||||
* + Управление цифровыми компараторами (DC0-DC3):
|
||||
* - Инициализацию и конфигурацию компараторов
|
||||
@@ -39,56 +39,102 @@
|
||||
##### Как использовать этот драйвер #####
|
||||
==============================================================================
|
||||
|
||||
1. Общие функции ADC:
|
||||
-------------------------- Общие функции АЦП --------------------------------
|
||||
|
||||
a) Инициализация:
|
||||
(+) adc_init_first() — обязательный вызов перед использованием ADC
|
||||
1. Инициализация АЦП:
|
||||
(+) adc_init_first() - обязательный вызов перед использованием АЦП
|
||||
(+) Настраивает тактирование, GPIO и ожидает готовности аналогового модуля
|
||||
|
||||
2. Калибровка каналов:
|
||||
(+) ADC_Channel_Calibr(&hadc, channel, OFFSET, GAIN) - калибровка смещения и усиления
|
||||
(+) Формула калибровки: Dc = Dr * (4096+GAIN)/4096 + OFFSET
|
||||
|
||||
3. Чтение значений каналов:
|
||||
(+) ADC_Channel_GetValue(&hadc, channel) - получение текущего значения канала
|
||||
(+) Данные обновляются автоматически при работе секвенсоров
|
||||
|
||||
4. Инициализация GPIO:
|
||||
(+) adc_gpio_init(hadc.ChannelEnable) - настраивает пины выбранных каналов
|
||||
(+) Вызывается автоматически в adc_init_first()
|
||||
|
||||
------------------------ Секвенсоры (SEQ0, SEQ1) ----------------------------
|
||||
|
||||
b) Работа с каналами:
|
||||
(+) ADC_Get_ChannelValue(&hadc, channel) — получение текущего значения канала
|
||||
1. Настройка в periph_config.h:
|
||||
(+) Определите adc_seq0_config, adc_seq1_config
|
||||
(+) Настройте ADC_ClockSource и ADC_ClockMHz для тактирования АЦП
|
||||
(+) Определите adc_ch_config для включения нужных каналов
|
||||
|
||||
2. Инициализация секвенсоров:
|
||||
(+) adc_seq_init(&hadc, ADC_SEQ_Num_0, &adc_seq0_config) - инициализация SEQ0
|
||||
(+) Аналогично для SEQ1 при необходимости
|
||||
|
||||
3. Работа с секвенсорами:
|
||||
(+) ADC_SEQ_Start(&hadc, ADC_SEQ_Num_0, buffer, buffer_size) - запуск с буфером
|
||||
(+) ADC_SEQ_Stop(&hadc, ADC_SEQ_Num_0) - остановка секвенсора
|
||||
(+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, тип, func) - установка обработчика
|
||||
(+) ADC_SEQ_SoftwareStart() - программный запуск преобразования
|
||||
|
||||
4. Обработка прерываний секвенсоров:
|
||||
(+) ADC_SEQ0_IRQHandler - вызвать adc_seq_irq_handler(&hadc, ADC_SEQ_Num_0)
|
||||
(+) ADC_SEQ1_IRQHandler - вызвать adc_seq_irq_handler(&hadc, ADC_SEQ_Num_1)
|
||||
|
||||
------------------------ Цифровые компараторы (DC) --------------------------
|
||||
|
||||
|
||||
==============================================================================
|
||||
##### Особенности работы #####
|
||||
==============================================================================
|
||||
|
||||
-------------------------- Общие особенности --------------------------------
|
||||
|
||||
2. Секвенсоры (SEQ):
|
||||
|
||||
a) Настройка периферии (periph_config.h):
|
||||
(+) Определить структуры ADC_SEQ_ExtInit_TypeDef для нужных секвенсоров:
|
||||
adc_seq0_config, adc_seq1_config
|
||||
(+) Настроить последовательность каналов, режимы работы
|
||||
(+) Настроить прерывания (IT) и ITCount
|
||||
(+) Определить callback-функции (можно NULL)
|
||||
|
||||
b) Инициализация:
|
||||
(+) adc_init_first() — первичная настройка тактирования, сброс ADC, инициализация хендла hadc
|
||||
(+) adc_seq_init(&hadc, ADC_SEQ_Num_0, &adc_seq0_config) — инициализация конкретного секвенсора
|
||||
|
||||
c) Callback-функции (опционально):
|
||||
(+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_SeqCplt, Callback) — завершение секвенсора
|
||||
(+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_BuffHalf, Callback) — половина буфера
|
||||
(+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_BuffFull, Callback) — полный буфер
|
||||
(+) ADC_SEQ_Set_Callback(&hadc, ADC_SEQ_Num_0, ADC_Callback_Error, Callback) — ошибки
|
||||
|
||||
d) Запуск и остановка:
|
||||
(+) ADC_SEQ_Start(&hadc, ADC_SEQ_Num_0, data_buffer, buffer_size) — запуск с буфером
|
||||
(+) ADC_SEQ_Stop(&hadc, ADC_SEQ_Num_0) — остановка секвенсора
|
||||
|
||||
e) Работа с данными:
|
||||
(+) ADC_Get_ChannelValue(&hadc, channel) — чтение текущего значения канала из хендла
|
||||
(+) ADC_SEQ_SoftwareStart() — программный запуск преобразования
|
||||
|
||||
f) Обработка прерываний:
|
||||
(+) adc_seq_irq_handler(&hadc, ADC_SEQ_Num_0) — обработчик прерываний секвенсора
|
||||
- В обработчике автоматически читаются данные из FIFO, обновляются каналы и буфер
|
||||
- В обработчиках автоматически вызываются соответствующие callback-функции
|
||||
и сбрасываются флаги
|
||||
|
||||
g) Особенности работы:
|
||||
(+) Данные автоматически читаются из FIFO в прерывании
|
||||
(+) Поддерживается кольцевой буфер (BufferCircular)
|
||||
(+) Автоматический вызов callback при заполнении половины/всего буфера
|
||||
|
||||
3. Цифровые компараторы (DC):
|
||||
|
||||
- Частота ADC:
|
||||
- Задается через ADC_ClockMHz в periph_config.h
|
||||
- Автоматически настраивается делитель от источника тактирования
|
||||
|
||||
- Аналоговый модуль (AM):
|
||||
- Требует времени для старта после включения (до 1 мс)
|
||||
- adc_init_first() ожидает готовности AM с таймаутом 1 секунда
|
||||
- При неудаче вызывает Error_Handler()
|
||||
|
||||
- Калибровка:
|
||||
- OFFSET: смещение в диапазоне [-255, 255] квантов АЦП
|
||||
- GAIN: коэффициент усиления в диапазоне [-255, 255] квантов АЦП (4096+GAIN)
|
||||
- Калибровка применяется аппаратно для каждого канала отдельно
|
||||
|
||||
------------------------ Секвенсоры (SEQ0, SEQ1) ----------------------------
|
||||
|
||||
- Буферизация данных:
|
||||
- Данные в буфере хранятся в формате [канал][время]
|
||||
- При buffer_size=100 для 2 каналов буфер будет 200 элементов
|
||||
- Буфер может быть кольцевым (BufferCircular=ENABLE)
|
||||
|
||||
- Прерывания секвенсоров:
|
||||
- Генерируются после заданного количества рестартов (ITCount)
|
||||
- ITCount=0 означает прерывание после каждого прохода секвенсора
|
||||
- Данные автоматически читаются из FIFO в прерывании
|
||||
|
||||
- Работа с усреднением:
|
||||
- Аппаратное усреднение измерения:
|
||||
- 2, 4, 8, 16, 32 или 64 выборок (SEQ_Init.ReqAverage)
|
||||
- Включается через SEQ_Init.ReqAverageEn
|
||||
- Усредненные значения помещаются в FIFO как единый результат
|
||||
- Аппаратное усреднение рестартов
|
||||
- 2, 4, 8, 16, 32, 64, 128, 256 выборок (SER_Init.RestartCount + 1)
|
||||
- Включается через SEQ_Init.RestartAverageEn
|
||||
- Усредненные значения помещаются в FIFO как единый результат
|
||||
|
||||
- Таймер рестартов:
|
||||
- Период в тиках ADC_ClockMHz/2 (драйвер автоматически делит на 2)
|
||||
- Используется для периодического запуска секвенсора
|
||||
- При RestartTimer=0 рестарт происходит немедленно
|
||||
|
||||
- Чтение FIFO:
|
||||
- FIFO буфер на 32 элемента автоматически читается в прерывании
|
||||
- Данные распределяются по каналам согласно последовательности в Req[0..3]
|
||||
- При переполнении FIFO (>32 элементов до прерывания) возможна потеря данных
|
||||
|
||||
------------------------ Цифровые компараторы (DC) --------------------------
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
*/
|
||||
@@ -122,6 +168,10 @@ void adc_init_first(void)
|
||||
// Включаем аналоговый модуль
|
||||
ADC_AM_Cmd(ENABLE);
|
||||
|
||||
// Настройка пинов для ADC
|
||||
hadc.ChannelEnable = &adc_ch_config;
|
||||
adc_gpio_init(hadc.ChannelEnable);
|
||||
|
||||
hadc.Instance = ADC;
|
||||
#endif
|
||||
|
||||
@@ -140,15 +190,6 @@ void adc_init_first(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (USE_ADC_DC0==1)
|
||||
#endif
|
||||
#if (USE_ADC_DC1==1)
|
||||
#endif
|
||||
#if (USE_ADC_DC2==1)
|
||||
#endif
|
||||
#if (USE_ADC_DC3==1)
|
||||
#endif
|
||||
|
||||
#if (USE_ADC_SEQ0==1) || (USE_ADC_SEQ1==1) || (USE_ADC_DC0==1) || (USE_ADC_DC1==1) || (USE_ADC_DC2==1) || (USE_ADC_DC3==1)
|
||||
uint32_t starttick = millis();
|
||||
while (!ADC_AM_ReadyStatus()) {
|
||||
@@ -158,6 +199,41 @@ void adc_init_first(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Записать калибровочные значения канала
|
||||
* @param hadc указатель на хендл АЦП
|
||||
* @param channel номер канала
|
||||
* @param OFFSET Коэффициент корректировки смещения нуля АЦП в квантах [-255:255]
|
||||
* @param GAIN Коэффициент корректировки усиления зн АЦП в квантах [-255:255]
|
||||
* @retval значение ADC (0 если данные невалидны)
|
||||
* @details Результат преобразования передается на схему коррекции, которая нивелирует
|
||||
* ошибку усиления и смещения нуля и работа которой описывается формулой
|
||||
* Dc = Dr * (4096+GAIN)/4096 + OFFSET
|
||||
*/
|
||||
OperationStatus ADC_Channel_Calibr(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel, int OFFSET, int GAIN)
|
||||
{
|
||||
if (!hadc || (int)channel >= ADC_CH_Total)
|
||||
return ERROR;
|
||||
|
||||
ADC_CH_SetOffsetTrim(channel, OFFSET);
|
||||
ADC_CH_SetGainTrim(channel, GAIN);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получение текущего значения канала
|
||||
* @param hadc указатель на хендл АЦП
|
||||
* @param channel номер канала
|
||||
* @retval значение ADC (0 если данные невалидны)
|
||||
*/
|
||||
uint16_t ADC_Channel_GetValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel)
|
||||
{
|
||||
if (!hadc || (int)channel >= ADC_CH_Total)
|
||||
return 0;
|
||||
|
||||
return hadc->ChannelData[channel];
|
||||
}
|
||||
|
||||
//-- ADC Sequencers API functions ----------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -302,20 +378,6 @@ OperationStatus ADC_SEQ_Stop(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Nu
|
||||
return OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Получение текущего значения канала
|
||||
* @param hadc указатель на хендл АЦП
|
||||
* @param channel номер канала
|
||||
* @retval значение ADC (0 если данные невалидны)
|
||||
*/
|
||||
uint16_t ADC_Get_ChannelValue(ADC_HandleTypeDef *hadc, ADC_CH_Num_TypeDef channel)
|
||||
{
|
||||
if (!hadc || (int)channel >= ADC_CH_Total)
|
||||
return 0;
|
||||
|
||||
return hadc->ChannelData[channel];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Программный запуск преобразования
|
||||
*/
|
||||
@@ -323,7 +385,7 @@ void ADC_SEQ_SoftwareStart(void)
|
||||
{
|
||||
ADC_SEQ_SwStartCmd();
|
||||
}
|
||||
int itcnt;
|
||||
|
||||
/**
|
||||
* @brief Обработчик прерываний секвенсора
|
||||
* @param hadc указатель на хендл АЦП
|
||||
@@ -335,7 +397,7 @@ void adc_seq_irq_handler(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ_Num)
|
||||
if (!hadc || !hadc->Instance || !hadc->SEQ[SEQ_Num].Config)
|
||||
return;
|
||||
// GPIO_SetBits(GPIOA, GPIO_Pin_7);
|
||||
itcnt++;
|
||||
|
||||
ADC_SEQ_HandleTypeDef *hseq = &hadc->SEQ[SEQ_Num];
|
||||
ADC_SEQ_ExtInit_TypeDef *conf = hseq->Config;
|
||||
|
||||
@@ -482,3 +544,45 @@ static void __adc_seq_fifo_read(ADC_HandleTypeDef *hadc, ADC_SEQ_Num_TypeDef SEQ
|
||||
|
||||
|
||||
//-- ADC Digital Comparators API functions -------------------------------------
|
||||
|
||||
|
||||
|
||||
//-- ADC GPIO functions --------------------------------------------------------
|
||||
/**
|
||||
* @brief Инициализация GPIO для ADC
|
||||
*/
|
||||
void adc_gpio_init(ADC_ChannelEnableTypeDef *ChEn)
|
||||
{
|
||||
#if (USE_ADC_SEQ0==1) || (USE_ADC_SEQ1==1) || (USE_ADC_DC0==1) || (USE_ADC_DC1==1) || (USE_ADC_DC2==1) || (USE_ADC_DC3==1)
|
||||
// Получаем структуру
|
||||
GPIO_Init_TypeDef *ch0_config = gpio_get_init(ADC_Ch0_GPIO_Port, ADC_Ch0_Pin);
|
||||
GPIO_Init_TypeDef *ch1_config = gpio_get_init(ADC_Ch1_GPIO_Port, ADC_Ch1_Pin);
|
||||
GPIO_Init_TypeDef *ch2_config = gpio_get_init(ADC_Ch2_GPIO_Port, ADC_Ch2_Pin);
|
||||
GPIO_Init_TypeDef *ch3_config = gpio_get_init(ADC_Ch3_GPIO_Port, ADC_Ch3_Pin);
|
||||
|
||||
if(ChEn->Ch0)
|
||||
{
|
||||
GPIO_StructInit(ch0_config);
|
||||
ch0_config->Pin = ADC_Ch0_Pin;
|
||||
GPIO_Init(ADC_Ch0_GPIO_Port, ch0_config);
|
||||
}
|
||||
if(ChEn->Ch1)
|
||||
{
|
||||
GPIO_StructInit(ch1_config);
|
||||
ch1_config->Pin = ADC_Ch1_Pin;
|
||||
GPIO_Init(ADC_Ch1_GPIO_Port, ch1_config);
|
||||
}
|
||||
if(ChEn->Ch2)
|
||||
{
|
||||
GPIO_StructInit(ch2_config);
|
||||
ch2_config->Pin = ADC_Ch2_Pin;
|
||||
GPIO_Init(ADC_Ch2_GPIO_Port, ch2_config);
|
||||
}
|
||||
if(ChEn->Ch3)
|
||||
{
|
||||
GPIO_StructInit(ch3_config);
|
||||
ch3_config->Pin = ADC_Ch3_Pin;
|
||||
GPIO_Init(ADC_Ch3_GPIO_Port, ch3_config);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user