Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
224 lines (155 sloc) 14.6 KB
#ifndef ADS1256_H
#define ADS1256_H
//-------------------------------------
// Настройка режимов микросхемы АЦП (высокоуровневое API модуля, синхронные операции)
//-------------------------------------
// Управление потоком выполнения
void ADS1256_API_Reset(void); //Программный Сброс: Reset Registers to Default Values
void ADS1256_API_Synchronize(void); //Послать команду SYNC: Synchronize the A/D Conversion (приостановить конвертацию... но быть готовым сразу же продолжить, по команде WAKEUP)
void ADS1256_API_Standby(void); //Послать команду STANDBY: Standby Mode / One-Shot Mode (усыпить АЦП, поместить в режим пониженного энергопотребления... при этом, конвертация конечно приостанавливается, но для ее возобновления требуется больше времени, чем после команды SYNC)
void ADS1256_API_WakeUp(void); //Послать команду WAKEUP: Complete Synchronization or Exit Standby Mode ([разбудить АЦП, если был в спящем режиме]... и сразу после этого, произвести конвертацию)
// Вернуть заводской Идентификатор Микросхемы (значение битов "ID3, ID2, ID1, ID0" из регистра STATUS)
uint8_t ADS1256_API_GetDeviceID(void);
// Установить Порядок БИТОВ в ответе "данных семплирования" (бит ORDER в регистре STATUS)
uint8_t ADS1256_API_GetBitOrderMode(void);
void ADS1256_API_SetBitOrderMode(uint8_t bit);
// Режим "автоматически запускать процедуру перекалибровки, после каждой перенастройки режима АЦП" (бит ACAL в регистре STATUS)
uint8_t ADS1256_API_GetAutoCalibrationMode(void);
void ADS1256_API_SetAutoCalibrationMode(uint8_t bit);
uint8_t ADS1256_API_IfAutoCalibrationOn(void); //Возвращает логический результат: TRUE если автокалибровка включена; FALSE отключена.
// (*) Вкл/выкл Входной Повторитель (увеличивает импеданс до 10..80МОм, но уменьшает динамический диапазон до 0..3V) (бит BUFEN в регистре STATUS)
uint8_t ADS1256_API_GetInputBufferMode(void);
void ADS1256_API_SetInputBufferMode(uint8_t bit);
uint8_t ADS1256_API_IfInputBufferOn(void); //Возвращает логический результат: TRUE если буфер включен; FALSE отключен.
// Запросить статус готовности АЦП к чтению данных или принятию команды (бит DRDY регистра STATUS - дублирует аппаратную шину DRDY)
uint8_t ADS1256_API_GetDataReadyBit(void);
uint8_t ADS1256_API_IfDataReady(void); //Возвращает логический результат: TRUE если данные готовы; FALSE данные не готовы, еще обновляются.
void ADS1256_API_WaitDRDY(void); //Вспомогательная функция: ожидание готовности АЦП к чтению данных или принятию команды (сигнал DRDY)
// Настройка мультиплексора входных каналов (Регистр MUX)
void ADS1256_API_SetMultiplexerSingleP(uint8_t PositiveChannelNumber); //Коммутация каналов для "Однопроводного включения", для измерения ПОЛОЖИТЕЛЬНОГО напряжения
void ADS1256_API_SetMultiplexerSingleN(uint8_t NegativeChannelNumber); //Коммутация каналов для "Однопроводного включения", для измерения ОТРИЦАТЕЛЬНОГО напряжения
void ADS1256_API_SetMultiplexerDifferential(uint8_t PositiveChannelNumber, uint8_t NegativeChannelNumber); //Коммутация каналов для "Дифференциального включения", для измерения РАЗНИЦЫ напряжений
// Настройка "Транслятора тактовой Частоты на Выход" (для тактирования внешней периферии) (биты CLKx регистра ADCON)
uint8_t ADS1256_API_GetClockOutMode(void);
void ADS1256_API_SetClockOutMode(uint8_t bits);
uint8_t ADS1256_API_IfClockOutOn(void); //Возвращает логический результат: TRUE если транслятор тактовой частоты активен (DIO0=CLKOUT); FALSE отключен (DIO0 обычный GPIO).
// Настройка "Источников тока, используемых для определения наличия Датчика, подключенного ко входу АЦП" (биты SDCSx регистра ADCON)
uint8_t ADS1256_API_GetSensorDetectionCurrentSources(void);
void ADS1256_API_SetSensorDetectionCurrentSources(uint8_t bits);
uint8_t ADS1256_API_IfSensorDetectionCurrentSourcesOn(void); //Возвращает логический результат: TRUE если эмиссия тока включена; FALSE детектор отключен (нормальный режим).
// (*) Настройка "Усилителя с Программируемым коэффициентом" для входного сигнала (биты PGAx регистра ADCON)
uint8_t ADS1256_API_GetProgrammableGainAmplifierMode(void);
void ADS1256_API_SetProgrammableGainAmplifierMode(uint8_t bits);
// (*) Настройка частоты семплирования АЦП (количество замеров в секунду) (Регистр DRATE)
uint8_t ADS1256_Convert_SPS2DRATE(uint16_t SPS); // Вспомогательная функция: возвращает наиболее близкий поддерживаемый Режим по требуемой Частоте семплирования (конвертирует SPS -> DRATE)
uint16_t ADS1256_Convert_DRATE2SPS(uint8_t DRATE); // Вспомогательная функция: разшифровывает Частоту семплирования из внутренней кодировки значение Регистра (конвертирует DRATE -> SPS )
void ADS1256_API_SetDataRateMode(uint8_t DRATE); // Базовая функция: 1) Перенастроить DRATE; 2) Запустить автокалибровку; 3) Форсировать конвертацию.
void ADS1256_API_SetDataRateModeSPS(uint16_t SPS); // Интерфейсная функция: Установить новую частоту семплирования в SPS = [2.5 .. 30000]
uint16_t ADS1256_API_GetDataRateModeSPS(void); // Интерфейсная функция: Возвращает текущую частоту семплирования (в единицах SPS)
// Настройка регистров калибровочных коэффициентов OFCx и FSCx
uint32_t ADS1256_API_GetOffsetCalibrationCoefficient(void); // Считывает значение регистров OFC (Offset Calibration Coefficient)
void ADS1256_API_SetOffsetCalibrationCoefficient(uint32_t value); // Записывает значение в регистры OFC (Offset Calibration Coefficient)
uint32_t ADS1256_API_GetFullscaleCallibrationCoefficient(void); // Считывает значение регистров FSC (Fullscale Callibration Coefficient)
void ADS1256_API_SetFullscaleCallibrationCoefficient(uint32_t value); // Записывает значение в регистры FSC (Fullscale Callibration Coefficient)
void ADS1256_API_DoSelfCalibration(void); // (*) Запустить автокалибровку
// (*) Note: после изменения режимов BUFEN, PGA, DRATE - настоятельно рекомендуется запускать "Self Calibration" (ADS1256_API_DoSelfCalibration)...
// (**) Note: все вышеперечисленные API-методы Getter-типа возвращают спецкод ошибки ADS1256_STATUS_DATAC_ERROR, вместо реальных данных, в случае когда связь с АЦП заблокирована режимом "потоковой конвертации", см. ниже...
// В то же время, API-методы Setter-типа ничего не делают с АЦП - просто втихую возвращают управление. При активном режиме "потоковой конвертации" никакие API-методы этого раздела вызывать нельзя! Как сказано ниже.
#define ADS1256_STATUS_DATAC_ERROR 0xFF
//-------------------------------------
// Служебные методы
//-------------------------------------
// Инициализация модуля (функция должна быть вызвана единожды, при старте программы)
void ADS1256_Init(void);
// DEBUG: Тестирование АЦП
void ADS1256_Test(void);
//-------------------------------------
// Единичные измерения: Синхронное чтение Данных конвертации АЦП
//-------------------------------------
// Произвести одиночное преобразование немедленно (синхронно и долго: до 2/SPS сек)
int32_t ADS1256_API_ConvertDataOnce(void);
// Вернуть результат последней конвертации, не производя нового замера (относительно быстро)
int32_t ADS1256_API_ReadLastData(void);
//-------------------------------------
// Потоковая конвертация: Асинхронное и неблокирующее чтение Данных конвертации АЦП, с помощью Обработчиков Прерываний
//-------------------------------------
// Требования и Ограничения:
//
// 1) Для использования режима "асинхронного потокового чтения результатов конвертации" -
// ОБЯЗАТЕЛЬНО НЕОБХОДИМА в аппаратной конфигурации устройства отдельная асинхронная ШИНА DRDY.
// (Здесь, чтение бита STATUS.DRDY по шине SPI - невозможно, т.к. очень медленно, и притом SPI будет занят!)
//
// 2) Datasheet (page 29) строго предупреждает: "Avoid using the continuous read mode (RDATAC) when DIN and DOUT are connected together."
// Нельзя использовать режим "потоковой конвертации" в полудуплексном режиме SPI, т.е. в режиме "1-WIRE SPI" (BIDIMODE=1)!
// (В аппаратной конфигурации с мультиплексированной шиной данных, когда на прием и передачу - одна аппаратная линия, нельзя!)
// Полудуплексный режим используется, например, при эмуляции SPI интерфейса аппаратным UART модулем...
// Также, можно и в STM32CubeMX сконфигурировать порт SPI в полудуплексном режиме (это поддерживается HAL-драйверами).
// Но для работы с АЦП ADS1256, в режиме RDATAC - интерфейс SPI должен быть полноценным (6 проводов):
// с отдельными шинами DIN и DOUT, плюс SPI-синхроимпульсы по шине SCLK;
// также, необходим упомянутый выше сигнал DRDY по отдельной шине;
// еще очень желателен (хотя и не необходим, но сильно увеличивает надежность) сигнал ChipSelect (CS), стробирующий начало пакета;
// и конечно, шина "Земли" (общий провод).
// SPI интерфейс должен позволять внешнему АЦП передавать и принимать данные ОДНОВРЕМЕННО - чтобы АЦП был способен принимать команду "SDATAC", одновременно с передачей 3-байтного "результата конвертации".
//
// 3) (**) Во время активного режима "RDATAC: Read Data Continuous" - нельзя посылать АЦП никакие "синхронные" API-команды из предыдущего раздела! Никакие!
// Даже "безобидную" вычитку содержимого регистров АЦП делать нельзя - т.к. Шина SPI занята.
// И шина SPI должна быть постоянно готова для пересылки очередного результат конвертации - что обслуживается соответствующими Обработчиками прерываний, асинхронно...
// Даже метод ADS1256_API_Reset() запускать нельзя! Не смотря на то, что режим RDATAC прерывается командами SDATAC и RESET... Но в этом Драйвере своя реализация, которая исключает конфликты доступа.
// Итак, пока активен режим RDATAC - вызывайте только API-команды текущего раздела (в частности, используйте только метод ADS1256_API_StopDataContinuousMode[Synchronous] для остановки АЦП, после чего с ним можно будет вновь взаимодействовать).
//
// 4) Если вам не требуется режим "асинхронного потокового чтения результатов конвертации"?
// и если вы будете общаться с АЦП только синхронно (методами из предыдущих разделов)?
// То просто игнорируйте все функции в этом разделе - ничего подключать и конфигурировать не нужно, здесь все по умолчанию отключено.
// Важно: модуль математической постобработки результатов конвертации "adc_stat.h" - является отдельной логикой и с данным драйвером АЦП никак не связан!
// Поэтому "инициализацию скользящего окна" и "сброс статистики по выборке" - следует производить из прикладного кода, на ваше усмотрение.
// Рекомендую методику:
// сбросить/инициализировать "окно и статистику" ADC_AVG_ResetArray()
// запустить потоковую конвертацию ADS1256_API_RunDATAC()
// собрать необходимое количество данных (выждать по Времени или до События, например до нажатия Кнопки и т.п.)
// во время обработки потока можно также получать усредненное значение и в реальном режиме времени ADC_AVG_GetMovingAverage()
// остановить потоковую конвертацию ADS1256_API_StopDATAC()
// и далее, уже неторопливо, обрабатывать собранные данные: ADC_AVG_GetHistoricalMax(), ADC_AVG_GetHistoricalMin(), ADC_AVG_CalcArrayStatistics()...
//-------------------------------------
// Тип callback-функции для запоминания/учёта очередного результата конвертации АЦП (используется в асинхронном режиме)
// Важно: данная функция должна быть неблокирующей и очень лёгкой, поскольку запускается из обработчика прерывания!
typedef void (*TDataRegistrator)(const int32_t);
// Получить указатель на текущий Регистратор (полезно для отладочных целей или полиморфных реализаций - подвязать Wrapper...)
TDataRegistrator ADS1256_API_GetDataRegistrator(void);
// Подключить callback-функцию для запоминания/учёта очередного результата конвертации АЦП (Регистратор вызывается из "обработчика прерывания SPI" по завершении выборки очередного результата конвертации)
void ADS1256_API_SetDataRegistrator(TDataRegistrator pFunc);
// Вычитанный, по Шине SPI асинхронно, результат конвертации нужно быстро куда-то засунуть, сохранить и обработать, причем без тяжелой математики, и тем более без блокирующих ожиданий.
// Рекомендуется, в качестве "регистратора данных" подключить функцию ADC_AVG_IncludeSample() из сателитного модуля "adc_stat.h"...
//-------------------------------------
// Активировать режим "RDATAC: Read Data Continuous" (**)
// (Внимание: после запуска этого метода никакие другие API-функции данного драйвера АЦП вызывать нельзя! Сперва, нужно вызвать метод ADS1256_API_StopDataContinuousMode[Synchronous], для остановки потоковой конвертации...)
void ADS1256_API_RunDataContinuousMode(void);
// Послать сигнал остановки режима "SDATAC: Stop Read Data Continuous" АСИНХРОННО (**)
// (Внимание: управление вернется сразу же - еще до фактической остановки режима SDATAC!)
void ADS1256_API_StopDataContinuousMode(void);
// Остановить режим "SDATAC: Stop Read Data Continuous" СИНХРОННО (**)
// (Примечание: После выполнения этой функции, АЦП вновь станет доступным к управлению!)
void ADS1256_API_StopDataContinuousModeSynchronous(void);
// Возвращает логический результат: TRUE если режим "потоковой конвертации" сейчас включен; FALSE режим отключен (АЦП свободно для конфигурации)
uint8_t ADS1256_API_IfDataContinuousMode(void);
//-------------------------------------
// TODO: Включить Прерывание EXTI для порта GPIO, обслуживающего физическую шину DRDY:
// (Preemtion Priority = 10, ниже чем SPI)
// Настроить EXTI на срабатывание "по спаду" сигнала! (т.к. активный сигнал шины /DRDY = Low)
// TODO: Поместить вызов в callback-функцию HAL-драйвера EXTI: HAL_GPIO_EXTI_Callback() - уже реализовано в модуле "ads1256_InterruptHandlersConnector.c"
// (Функция запускает SPI для вычитки очередного результата конвертации)
void ADS1256_INTERRUPT_OnDRDY(uint16_t GPIO_Pin);
// TODO: Включить Прерывание для SPI интерфейса, к которому подключен внешний АЦП:
// (Preemtion Priority = 5, выше чем EXTI)
// Настроить SPI в режиме = "Full-Duplex Master" (полноценное 3-проводное соединение: DIN и DOUT разнесены по разным шинам, плюс синхронизация SCLK)
// Frame Format = Motorola
// Data size = 8 Bits
// First bit = MSB First
// Prescaler (for Baud Rate) = выбираете сами (см. рекомендации в разделе "Настройка Частоты и Таймингов" файла "ads1256.c")
// Clock Polarity (CPOL) = Low
// Clock Phase (CPHA) = 2 Edge
// CRC Calculation = Disabled
// NSS Signal Type = Software (управление сигналом ChipSelect программное)
// TODO: Поместить вызов в callback-функцию HAL-драйвера SPI: HAL_SPI_TxRxCpltCallback() - уже реализовано в модуле "ads1256_InterruptHandlersConnector.c"
// (Функция передает "результат конвертации" в "регистратор данных")
void ADS1256_INTERRUPT_OnSPI(SPI_HandleTypeDef *hspi);
#endif // ADS1256_H