mirror of
https://github.com/eddyem/STM8_samples.git
synced 2026-03-20 16:51:04 +03:00
readme
This commit is contained in:
90
voltmeters/README
Normal file
90
voltmeters/README
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
конфигурационный регистр АЦП: |!RDY|C1|C0|!O/C|S1|S0|G1|G0|
|
||||
!RDY == 0 когда преобразование окончено (МК может послать NAK и считать данные); при записи в непрерывном режиме не учитывается
|
||||
C1,C0 не задействованы
|
||||
!O/C - режим преобразования (по умолчанию 1): 1-непрерывное, 0-одноразовое
|
||||
S1,S0 - разрешение (по умолчанию 0): 00 - 12, 01 - 14, 10 - 16, 11 - 18 бит
|
||||
G1,G0 - усиление (по умолчанию 0): 00 - 1, 01 - 2, 10 - 4, 11 - 8
|
||||
|
||||
Поддерживаемые скорости: 100кбит/с, 1400кбит/с и 3.4Мбит/с
|
||||
|
||||
Протокол: стартовый бит, данные (MSB first), стоповый бит
|
||||
данные считываются при SCL==1, если SCL==1, а SDA меняется, это START(1->0) или STOP(0->1)
|
||||
ноги: SCL - push/pull; SDA - open drain
|
||||
в режиме чтения прервать передачу можно командами NAK/STOP
|
||||
После стартового бита первый байт - адрес (4 бита - код устройства - 1101, 3 бита - адрес устройства/000 по даташиту/, 1 бит - R/!W)
|
||||
в режиме записи (R/!W = 0) пишем конфигрегистр
|
||||
в режиме чтения устройство посылает конфигрегистр и данные (1 байт == 8 бит данных + ACK бит, после адреса ACK инициируется
|
||||
устройством, после данных - микроконтроллером)
|
||||
в 18-битном режиме отсылаются 3 байта данных, следом 1 байт конфиг; первые 7 бит первого байта данных - MSB (знак операции, т.е. ноль),
|
||||
LSB третьего байта - LSB данных
|
||||
|
||||
GENERAL CALL
|
||||
Если первым байтом передать нули, то второй байт читают все устройства линии. Второй байт:
|
||||
== 0x06 - сброс АЦП на настройки по умолчанию
|
||||
== 0x08 - одноразовое преобразование
|
||||
|
||||
сигналы:
|
||||
NOT BUSY (умолчательное состояние) - SDA=1, SCL=1
|
||||
START DATA TRANSFER - SCL = 1, SDA = 1->0
|
||||
STOP DATA TRANSFER - SCL = 1, SDA = 0->1
|
||||
DATA VALID - данные не должны изменяться при SCL=1
|
||||
|
||||
Каждая передача данных начинается со START и кончается STOP
|
||||
|
||||
ACK: девятый такт SCL используется как ACK. Для прерывания чтения достаточно установить SDA=1 на этот бит
|
||||
Этот бит можно проверять: если АЦП сдох, то будет 1 вместо 0
|
||||
!!! на этот бит нужно отпустить ногу
|
||||
|
||||
|
||||
После включения нужно инициализировать АЦП: 1 байт - start(0);1;1;0;1;0;0;0;0;ACK(1)
|
||||
2 байт - 0;0;0;1;1;1;0;0;ACK(1)
|
||||
не забываем проверять ACK: если он !=0, то АЦП сдох
|
||||
|
||||
далее - непрерывно читаем: 1 байт - start(0);1;1;0;1;0;0;0;1;ACK(1)
|
||||
2-5 байты: 8 бит; ACK(0)
|
||||
6 и последующие (пока тикает SCL и не установлен ACK/STOP): конфиг
|
||||
|
||||
чтение: читаем до тех пор, пока в конфиг-регистре RDY==1; затем прерываем (ACK=1,STOP) и инициализируем следующую порцию считывания
|
||||
(можно читать 8 раз и усреднять)
|
||||
прервать операцию чтения можно в любой момент, отправив бит STOP
|
||||
|
||||
|
||||
|
||||
|
||||
ВОЛЬТМЕТР:
|
||||
|
||||
Вычисление.
|
||||
В 18-битном режиме реально АЦП дает 17 бит (т.к. у нас однополярное напряжение без сдвига). Таким образом,
|
||||
LSB=2.048V/2^{17}
|
||||
коэффициент резисторного делителя kr (17.5 в идеальных условиях)
|
||||
-> U = ADU*2.048*kr/2^{17}, где ADU - показания внешнего АЦП (по умолчанию коэффициент усиления = 1)
|
||||
Следовательно, для вычисления напряжения в милливольтах (используем 32-битную целочисленную арифметику, т.к.
|
||||
float не справится, а double и 64-битные целые sdcc не умеет) используем формулу
|
||||
---> U = (ADU*K)>>17
|
||||
K - коэффициент преобразования, по умолчанию K = 2048*17.5=35840, но при калибровке мы его можем поменять
|
||||
Из-за того, что коэффициент K занимает 15-16 бит, может возникнуть ситуация переполнения, т.е.
|
||||
нам нужно еще и хранить ADUmax - предельное значение, выдаваемое АЦП, которое еще можно обработать
|
||||
это значение вычисляется так:
|
||||
---> ADUmax = 0xffffffff/K (по умолчанию 119837)
|
||||
"Умолчательное" ограничение дает нам предел измерений: 32.758В (естественно, в реальных условиях этот предел
|
||||
варьируется как минимум на 5% из-за погрешности резисторов делителя)
|
||||
|
||||
Коэффициент K при калибровке вычисляется так:
|
||||
---> K = Uref<<17/ADU = Const / ADU
|
||||
Uref - опорное напряжение в милливольтах (жестко зафиксировано при компиляции)
|
||||
Следовательно, Const можно вычислить на этапе компиляции, скажем, для Uref=12000мВ мы имеем
|
||||
Const = 12000<<17 = 1572864000; для улучшения калибровки можно считать значение ADU 16 раз и усреднить
|
||||
|
||||
Служебный разъем имеет подключение к ноге 3 (PD6/UART1_RX), следовательно, используется для калибровки.
|
||||
Вариантов калибровки 2 (причем, можно реализовать их одновременно):
|
||||
1) при получении на PD6 логической 1 производится считывание результата, вычисление и запоминание констант
|
||||
2) при получении данных по UART1 вольтметр воспринимает их в качестве множителя, вычисляет предельное значение и сохраняет константы
|
||||
Во втором варианте можно пробежаться по всему диапазону (0..30В) и линейной аппроксимацией вычислить оптимальный коэффициент.
|
||||
|
||||
Режим отображени вычисленных данных прост:
|
||||
- динамическая индикация на 5 позиций (т.е. нужно либо поочередно читать/показывать, либо делать это псевдоодновременно,
|
||||
но ждать окончания преобразования, непрерывно читая, не стоит)
|
||||
- после вычисления U в милливольтах нам надо отобразить это значение:
|
||||
-- если U < 10000, т.е. используется 4 знакоместа, мы рисуем 4-значное число (дополняя спереди нулями), а десятичную точку ставим в четвертой позиции (digit2)
|
||||
-- иначе рисуем на пяти знакоместах, просто выводя целое; десятичную точку ставим в пятой позиции (digit1)
|
||||
Reference in New Issue
Block a user