Главная » Bascom-8051, Basic, Железо » Программирование аналоговых преобразователей Bascom-8051

0

К  аналоговым  преобразователям,  программирование  которых  будут  рассмотрено   ниже,   относятся аналого-цифровые (АЦП), цифро-аналоговые преобразователи (ЦАП). К АЦП  также можно отнести все схемы преобразования аналогового сигнала в частоту или длительность с устройством измерения частоты или периода. К устройствам ЦАП также относятся всевозможные регуляторы уровня, цифровые синтезаторы частоты, генераторы широтно-импульсной  модуляции  и  даже  просто  управляемые генераторы частоты. Принципиальное различие АЦП и ЦАП с точки зрения программиста, независимо от того с каким аналоговым сигналом работает устройство, заключается в направлении передачи и порядке преобразования данных. При работе с АЦП данные считываются и после многократного преобразования приобретают вид, понятный наблюдателю  или субъекту, принимающему решение.   Очевидные   данные   ЦАП,   напротив,   должны   многократно   преобразовываться   перед   загрузкой преобразователь.  Задачи  и  проблемы   программирования  ЦАП  и  АЦП  можно  сформулировать  следующим образом:

а) организация работы программы преобразования;

б) обеспечение интерфейса ЦАП или АЦП с процессором;

в) выбор формы представления цифрового значения измеряемого или устанавливаемого параметра;

г) преобразование из кода АЦП в формат пригодный для вычисления и преобразование устанавливаемого значения в код загрузки ЦАП

д) оптимальная цифровая калибровки преобразователей;

е) накопление, усреднение и вывод данных АЦП;

ж) ввод и подготовка данных ЦАП;

з) ускорение принятия решений на основании данных АЦП.

Рассмотрим эти задачи подробнее в том же порядке. Начнем с организации работы программы – с выбора двигателя. Для приведения в действия любой программы, работающей с аналоговыми устройствами, всегда нужен какой-то двигатель. В роли двигателя может выступать:

а) внешнее событие, например, приход команды с клавиатуры или из внешнего интерфейса на установку нового  значения  воспроизводимого  параметра  (или  запрос  измеренных  данных).   Обычно,  таким  образом, работают системы с ЦАП;

б) команда от таймера, задающего периодичность операций установки, смены или измерения параметров системы. Системы с периодически воспроизводимым циклом  преобразования характерны для измерительных устройств, например, таких как цифровой вольтметр, и применяются наиболее часто;

в) команда измерительного устройства о готовности данных. Самый характерный пример таких систем – устройства,  в  основе  которых  лежит  медленный  АЦП  (интегрирующего  типа).   Привязка  всех  системы  к медленному АЦП является лучшим решением, позволяющим исключить нежелательные переходные процессы и разрывы  потока  данных.  Основной   недостаток   подобных  систем  возможность  остановки  программы  при перегрузке или отказе измерительного устройства (впрочем, легко устранимый);

г) команда другой программы, являющейся ведущей или передающей запрос на действие по цепочке. С точки зрения измерительной программы, такая команда является внешней, однако относительно системы в целом могут быть и другие механизмы приведения ее в действие, в том числе, и упомянутые выше.

При планировании взаимодействия других частей программы с измерительной  необходимо учитывать время исполнения каждой из них. Например, недопустимо, если обработка и вывод (всегда обращайте внимание на  время  вывода!)  измеренных  данных,  выполняемых  в  измерительной  цикле,  превышает  время  готовности данных АЦП. Также недопустимо, если частота измерения АЦП меньше частоты считывания данных из него. Все это приводит к потере  данных и появлению неявной погрешности измерения. Аналогично, нужно учитывать реальное время установления воспроизводимого параметра, задаваемого с помощью ЦАП. Причем учитывать не время установления выходного сигнала ЦАП, а время установления всей  аналоговой  схемы (если такая есть). Периодичность загрузки ЦАП должна быть намного больше электрической постоянной времени аналоговой части схемы. Также, время обработки устанавливаемых данных и загрузки кода в ЦАП не должно превышать период повторения операций загрузки.

Рассмотрим   с   проблему   интерфейса.   Почти   всегда   АЦП   или   ЦАП,   с    которыми   работает микроконтроллер,  являются  однокристальными  устройствами.   Номенклатура  этих  устройств,  чрезвычайно широка   и   всегда,   за   исключением   особых    случаев,   может   быть   выбрана   модель,   удовлетворяющая метрологическим требованиям,  скорости, конфигурации входа (выхода) и напряжению питания. Выбранный по указанным  критериям, преобразователь чаще оказывается с последовательным портом. В результате  возникают сложности достижения высокого быстродействия при считывании (записи) данных. Это обусловлено отсутствием большинства у процессоров семейства 8051 высокоскоростного аппаратного последовательного порта, а с другой стороны использование АЦП и ЦАП с параллельным портом также не всегда возможно из-за дефицита свободных линий портов. Таким образом, задача интерфейса сводится к программному формированию сигналов управления на  выводах преобразователя и перемещению данных из регистров процессора в устройство или  наоборот. В общем  случае,  создание  программы  считывания  (из  АЦП)  и  тем  более  записи  данных  (в  ЦАП)  с  помощью операторов  Bascom  не  представляет  большой  сложности.  Для   этого  предусмотрены  операторы  SHIFTIN,

SHIFTOUT,    SPIIN,    SPIOUT.    Затруднения    появляются,    когда    устройство,    с    которым     необходимо взаимодействовать, имеет число разрядов не кратное восьми (не целое число байт) и не допускает подачу лишних импульсов  на  входе  синхронизации.     Практически  таких   микросхем  очень  мало.  Чаще  микросхемы,  не допускающие подачу лишних импульсов, ориентированы на байтовый обмен, и поэтому проблем с ними вообще не возникает.  Справедливости ради, нужно сказать, что проблема числа импульсов синхронизации возникает только  для  микросхем,  имеющих  двухпроводный  интерфейс,  или  при  попытках  использования  имеющиеся трехпроводные (и более) интерфейсы как двухпроводный. Использование ассемблера для написания подпрограмм ввода-вывода оправдано только в одном  случае, когда эти подпрограммы вызывается в прерывании, и к ним предъявляются особые требования по скорости и количеству используемых регистров. В остальных случаях это делать  не  рекомендуется,  т.к.  библиотеки  Bascom  дают  оптимальный  код  и  быстродействие  (50  –  70  %  от возможного).   Ниже   приведен   пример    программы,   работающей   с   типичным    устройством,   имеющим последовательный интерфейс. В тексте программы имеются все  варианты  организации интерфейса с помощью операторов последовательного вывода SHIFTOUT и SPIOUT.

‘————————————————————– ‘  Программа тестирование цифрового потенциометра AD8400 -2,-3

‘————————————————————– Dim Badr As Byte                ‘байтовый адрес

Dim Value As Byte               ‘значение записываемого кода

Dim Wtmp As Byte                ‘временные данные Pdin Alias P1.0                 ‘подключение ЦАП Pcs Alias P1.2

Pclk Alias P1.3

‘———————

Config Spi = Soft , Din = P1.0 , Dout = P1.1 , Cs = P1.2 , Clk = P1.3 ‘———————

‘TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART Config Timer2 = Timer , Gate = Internal , Mode = 2

$baud = 9600                    ‘скорость 9.6 кБ

$crystal = 12000000             ‘при кварце 12 МГц

‘——————— Set Pcs : Reset Pclk

‘Цикл

Mc:

Input "Enter number of DAC" , Badr       ‘запрос адреса ЦАП Input "Enter code for DAC" , Value       ‘запрос данных ЦАП Value = Value And &B00000011             ‘маска

Print "DAC=" ; Badr ; " " ; "Code=" ; Value       ‘покажем

‘———————

‘ _   временная диаграмма работы интерфейса    _

‘  |                                          |  CS ‘              

   X    X    X    X    X    X    X    X    X 

Data

‘      _    _

_    _    _

_    _    _

    | |  | |  | |  | |  | |  | |  | |  | |     ‘———————

Clk

‘    Gosub Ser_out               ‘использовать подпрограмму вывода Wtmp = Makeint(value , Badr) ‘сложим как: младший + старший ‘второй вариант

Spiout Wtmp , 2              ‘послать два байта: адрес и данные

Goto Mc

‘———————

‘подпрограмма последовательного вывода

Ser_out:

Acc = Badr                    ‘адрес в аккумулятор

Pcs = 0

Pdin = Acc.1 : Set Pclk : Reset Pclk  ‘выдвинем старший бит адреса Pdin = Acc.0 : Set Pclk : Reset Pclk  ‘выдвинем младший бит адреса ‘ Shiftout Pdin , Pclk , Badr , 1     ‘выдвинем 8-битный адрес

Shiftout Pdin , Pclk , Value , 1      ‘затем данные (старший – первым) Pcs = 1

Return

‘——————————————

Следующая программа демонстрирует организацию ввода и обработки данных  12-разрядного АЦП с последовательным интерфейсом. Для считывания данных АЦП  используется оператор SHIFTIN. Особенность программы заключается в том, что тактирование  работы программы осуществляется с помощью таймера, а для вывода вычисляется среднее значение шестнадцати отсчетов.

‘————————————————————– ‘   Программа тестирования АЦП типа AD7893-3 (Шкала +-2.5 В)

‘————————————————————–

$large                          ‘модель программы более 2 кбайт

Dim B_dat As Bit                ‘бит "Есть новые данные" Dim Mes As Byte                 ‘счетчик измерений

‘———————

Dim Temp As Integer             ‘временные данные

Dim R_bd As Integer             ’16-разр. двоичные данные

‘———————

Dim R_fld As Single             ‘регистр данных АЦП

‘———————

B_acnv Alias P1.0               ‘подключение АЦП

B_aclk Alias P1.1

B_adat Alias P1.2

‘————————————————————– ‘TIMER0 в режиме 16-бит. счетчика

Config Timer0 = Timer , Gate = Internal , Mode = 1 : Start Timer0 ‘———————

‘TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART Config Timer2 = Timer , Gate = Internal , Mode = 2

$baud = 9600                    ‘скорость 9.6 кБ

$crystal = 12000000             ‘при кварце 12 МГц

‘———————

‘назначение режимов прерываний

On Timer0 Timer_0_int Nosave    ‘вектор прерывания

Enable Interrupts               ‘вообще разрешить прерывания Enable Timer0                   ‘разрешить прерывания таймера 0 ‘——————————————

Set B_acnv : Reset B_aclk

Mes = 16                   ‘количество усредняемых отсчетов

‘—————————————— Mc:

Do

If B_dat = 1 Then           ‘появился бит?

Reset B_dat               ‘сбросить этот бит

R_bd = R_bd + Temp Decr Mes

If Mes = 0 Then

R_fld = R_bd : R_bd = 0 ‘преобразуем в плавающий формат и очистим сумму

R_fld = R_fld * 0.0000763   ‘преобразуем показания в вольты

Print R_fld : Mes = 16  ‘вывести показания и восст. счетчик

End If End If Loop

‘—————————————— ‘обработка прерывания таймера 0

Timer_0_int:

Th0 = &HD8 : Tl0 = &HFD ‘Ffffh-10000 = D8fdh – период прерыв. 10 мс

Set B_dat Return

‘—————————————— ‘запустить преобразование и считать данные Convert:

Reset B_acnv : Reset B_acnv : Set B_acnv       ‘сформировать импульс

‘до считывания нужно выдержать 6 мкс реально получается больше

‘———————

‘ _   временная диаграмма работы интерфейса    

‘  |                                        |   CS

                                            _

   X    X    X    X    X    X    X    X    X_ Data ‘           

  |  |_|  |_|  |_|  |_|  |_|  |_|  |_|  |     ‘———————

Clk

Shiftin B_adat , B_aclk , Temp , 1       ‘подходит режим 1

Return

‘———————————————-

При   программировании   аналоговых   преобразователей    всегда   приходится    выбирать    размерность воспроизводимых  или измеренных  данных.  Лучше и понятней, когда  данные  представлены в  общепринятых единицах, и при этом все числовые значения, принимаемые  измеряемым (или воспроизводимым) параметром в процессе работы, соответствуют используемому устройству отображения. Имеется в виду, что, например, нельзя строить    измерительную   систему,   в   которой   на   3.5-разрядный   индикатор    должно   выводится    число 10000 Гц или 20000 кОм. Понятно, форма представления чисел в программе должна быть такой, чтобы указанные числа выводились как 10.00 кГц и 020.0 МОм. Удобней всего, когда числа в программе представлены в формате с плавающей точкой. Это позволяет работать с широким диапазоном значений без потери точности и производить любые вычисления. Микросхемы ЦАП и  АЦП принимают и выдают значения, представленные в виде целого двоичного кода числа младших разрядов. Bascom предоставляет прекрасные возможности преобразования числа в формате с плавающей точкой в код загрузки ЦАП (в целое  двоичное число) и, соответственно, выходного кода АЦП в число в формате с плавающей точкой, что показано в предыдущих примерах и последующей программе. При преобразовании двухполярного числа   нужно позаботится, чтобы  источником (или приемником) двоичных данных была знаковая переменная типа Integer или Long, и чтобы старший (знаковый) бит был заполнен, как это сделано в следующей демонстрационной  программе (тестирования AD7711A) с помощью оператора ROTATE. Если преобразуется  однополярное двоичное число, то его расположение в регистре двоичных  данных  имеет только то значение, что должно соответствовать разрядам ЦАП или АЦП.

Второй   составляющей   преобразования   кода   является   операция   умножения   на    масштабирующий коэффициент.  В  случае  загрузки  ЦАП  с  помощью  масштабирующего  коэффициента  происходит  переход  от принятой  размерности  к  числу  устанавливаемых  младших  разрядов  (смотри  пример  в  программе  монитора синтезатора частоты). Чтобы привести к требуемой размерности данные АЦП, выраженные в единицах младшего разряда, также  применяется соответствующий масштабный коэффициент.

Ниже представлен еще пример программы, работающей с АЦП. В ней осуществляется  тестирование 24- разрядного АЦП, связанного с процессором через последовательный  интерфейс.  АЦП перед началом работы инициализируется и проводится его самокалибровка (калибровка нуля и калибровка шкалы). В данной программе АЦП является источником сигнала  синхронизации для всей программы. Установив при инициализации АЦП время измерения  (интегрирования, т.к. АЦП интегрирующего типа) равное 20 мс и подав сигнал готовности данных АЦП на вход прерывания, мы будем каждые 20 мс получать новый отсчет. Вследствие того, что вывод и визуальное  восприятие  данных  с  такой  скоростью  невозможно,  применено  усреднение  данных  шестнадцати отсчетов. Теперь, каждые 320 мс (3 раза в секунду) мы будем  получать результат. В программе считывания данных  АЦП  применено  много  ассемблерных  вставок  для  повышения  скорости работы  и лучшего  контроля ресурсов, используемых в  прерывании. В программе предусмотрена калибровка АЦП, информация о которой будет представлена ниже.

‘————————————————————– ‘      Программа тестирования 24-разр. АЦП AD7711A (+-2.5 В)

‘————————————————————–

$large                          ‘модель программы более 2 кбайт

Dim B_dat As Bit                ‘бит "Есть новые данные" Dim Mes As Byte                 ‘счетчик измерений

Dim R_ch As Byte                ‘введеный символ

‘———————

Dim Temp As Long                ‘временные данные

Dim R_bd As Long                ’32-разр. двоичные данные

‘———————

Dim R_fld As Single             ‘регистр данных АЦП

Dim R_zero As Single            ‘константа смещения нуля

Dim R_scal As Single            ‘константа калибровки масштаба

‘————————————————————–

‘TIMER0 в режиме 16-бит. счетчика

Config Timer0 = Timer , Gate = Internal , Mode = 1 : Start Timer0 ‘———————

‘TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART Config Timer2 = Timer , Gate = Internal , Mode = 2

$baud = 9600                    ‘скорость 9.6 кБ

$crystal = 12000000             ‘при кварце 12 МГц

‘———————

On Int0 Int0_int Nosave         ‘вектор INT0

Enable Interrupts               ‘вообще разрешить прерывания

‘——————————————

Gosub Str_adc          ‘самокалибровка и установка режима АЦП

Mes = 16               ‘количество усредняемых отсчетов

R_zero = 0             ‘нет смещение нуля R_scal = 1             ‘масштаб идеальный Print " – MONITOR FOR ADC AD7711A – " Print " Calb zero – Z  @ Uinp = 0 V " Print " Calb scale – S @ Uinp = + 2 V"

Enable Int0                 ‘разрешить внешнее прерывания 0 ‘——————————————

Mc: Do

If B_dat = 1 Then           ‘появился бит?

Reset B_dat                ‘сбросить этот бит

Rotate R_bd , Left , 4     ‘показания еще нужно умножить на 16

‘таким образом, сумма 16-ти отсчетов полностью расположиться в 32-битн. регистре

R_fld = R_bd : R_bd = 0    ‘преобразуем в плавающий формат и очистим сумму

R_fld = R_fld * 0.00000000116415322       ‘преобразуем показания в вольты

R_ch = Inkey

If R_ch <> 0 Then          ‘если нажата кнопка – проверить

Gosub Makeclb            ‘при необходимости калибровать

End If

Gosub Calbr                ‘учесть калибровку

Print R_fld                ‘вывести показания

End If Loop

‘——————————————

‘обработка прерывания таймера 0

Int0_int:

$asm

Push Psw Push Acc

$end Asm

Psw.3 = 1 : Psw.4 = 1  ‘выберем третий банк – он не используется Bascom Gosub Rd_adc

$asm

djnz {Mes} , Int0_1    ;обработка счетчика измерений

Setb {B_dat}           ;если Mes=0, есть новые данные АЦП

mov {Mes} , #16        ;восстановить счетчик

Int0_1:

Pop Acc Pop Psw

$end Asm Return

‘———————————————- ‘    УТИЛИТЫ СИГМА-ДЕЛЬТА АЦП ТИПА AD7711A

‘———————————————- ‘регистры AD7711

‘ формат регистра управления

‘           ——— MD2 0 норм. 0 самокалиб. ‘           ¦——– MD1 0 изм.  0 в выбранн. ‘           ¦¦——- MD0 0       1 канале

‘           ¦¦¦—— G2 0   0    0    0    1    1    1    1

‘           ¦¦¦¦—– G1 0=1 0=2  1=4  1=8  0=16 0=32 1=64 1=128

‘           ¦¦¦¦¦—- G0 0   1    0    1    0    1    0    1

‘           ¦¦¦¦¦¦— CH 0-AIN1, 1-AIN2

‘           ¦¦¦¦¦¦¦– PD 0-работа, 1-останов

‘           ¦¦¦¦¦¦¦¦——— WL Выход: 0-16 бит, 1-24 бита

‘           ¦¦¦¦¦¦¦¦¦——– IO Вых. ток RTD 0-выкл, 1-вкл

‘           ¦¦¦¦¦¦¦¦¦¦——- BO Вых. ток BO  0-выкл, 1-вкл

‘           ¦¦¦¦¦¦¦¦¦¦¦—— B/U Вход: 0-двухполярный, 1-однополярн.

‘           ¦¦¦¦¦¦¦¦¦¦¦¦————- FS11=0¬

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦———— FS10  ¦          при кварце 5 МГц:

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦———– FS9   ¦         50 Гц  FS=135 (0С3h)

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦———- FS8   ¦             (fкв/512)

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦——— FS7   ¦- FS = ———————-

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦——– FS6   ¦       частота первого полюса

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦——- FS5   ¦

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦—— FS4   ¦- FS – код первого полюса

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦—– FS3   ¦          от 19 до 2000

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦—- FS2   ¦

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦— FS1   ¦

‘           ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦– FS0 —

‘C_M2B  equ 00000000b                 ‘старший байт  рабочего режима:

‘C_M1B  equ         10000000b         ‘средний байт  50 Гц, G=1, +-2.5 В

‘C_M0B  equ                 11000011b ‘младший байт  CH1, 24 бита, ток выкл

‘———

‘C_С2B  equ 00100000b                 ‘старший байт  самокалибровки:

‘C_С1B  equ         10000000b         ‘средний байт  50 Гц, G=1, +-2.5 В

‘C_С0B  equ                 11000011b ‘младший байт  CH1, 24 бита, ток выкл

‘———————————————-

‘определение констант

Dim C_m2b As Const &B00000000

Dim C_m1b As Const &B10000000

Dim C_m0b As Const &B11000011

Dim C_c2b As Const &B00100000

Dim C_c1b As Const &B10000000

Dim C_c0b As Const &B11000011

‘———————————————-

‘НАЗНАЧЕНИЕ ПОРТОВ, ПОДКЛЮЧЕННЫХ К АЦП

B_aa0 Alias P1.0                ‘ПОРТ ВЫБОРА РЕГИСТРА АЦП: 0-сост. 1-данных

B_atfs Alias P3.5               ‘ПОРТ РАЗРЕШЕНИЯ ЗАПИСИ АЦП

B_arfs Alias P1.3               ‘ПОРТ РАЗРЕШЕНИЯ СЧИТЫВАНИЯ АЦП

B_aclk Alias P1.1               ‘ПОРТ ТАКТОВОГО СИГНАЛА ДЛЯ ДАННЫХ АЦП

B_adat Alias P1.2               ‘ДАННЫЕ АЦП

B_ardy Alias P1.4               ‘ГОТОВНОСТЬ ДАННЫХ АЦП

‘———————————————- ‘ЗАПИСЬ 8 БИТ В АЦП ИЗ АККУМУЛЯТОРА

Wrb_adc:

$asm

Wrb_adc1:

$end Asm

Mov   R0 , #8

Rlc   A               ;данные в SDATA Mov   {B_adat} , C

Setb  {B_aclk}        ;защелкнуть – SCLK в "1"

Clr   {B_aclk}        ;SCLK в "0" Djnz  R0 , Wrb_adc1

Return

‘———————————————- ‘ЧТЕНИЕ 8 БИТ ИЗ АЦП В АККУМУЛЯТОР

Rdb_adc:

$asm

Rdb_adc1:

Mov   R0 , #8

Setb {b_aclk}         ;защелкнуть – SCLK в "1" Mov   c , {B_adat}

Clr   {B_aclk}        ;SCLK в "0" Rlc   A               ;данные в Acc

$end Asm

Djnz  R0 , Rdb_adc1

Return

‘———————————————- ‘ Начальная подготовка АЦП к работе:

‘ самокалибровка – установка режима

‘——— Str_adc:

Reset B_aclk : Reset B_aa0 : Reset B_atfs  ‘SCLK=0, A0=0, разрешим запись

Acc = C_c2b : Gosub Wrb_adc ‘назначить самокалибровку АЦП

Acc = C_c1b : Gosub Wrb_adc Acc = C_c0b : Gosub Wrb_adc

Set B_atfs : Wait 2         ‘запретим запись и ждать 2 сек

Reset B_atfs                ‘разрешить запись

Acc = C_m2b : Gosub Wrb_adc ‘назначить нормальный режим АЦП

Acc = C_m1b : Gosub Wrb_adc Acc = C_m0b : Gosub Wrb_adc

Set B_atfs : Set B_adat    ‘запретим запись подготовиться к приему данных

Return

‘———————————————- ‘Программа считывания данных из АЦП ‘Производится первичная обработка данных – они ‘складываются с регистром суммы с учетом знака Rd_adc:

B_adat = 1 : B_aclk = 0    ‘подготовить порты

B_aa0 = 1 : B_arfs = 0     ‘разрешить чтение АЦП

‘———

Mov  R1 , #{Temp + 3} Mov  @R1 , #0

Dec R1

Gosub Rdb_adc

Mov @r1 , A       ;запомним старший байт

Dec R1

Gosub Rdb_adc

Mov @r1 , A       ;запомним средний байт

Dec R1

Gosub Rdb_adc

Mov @r1 , A       ;запомним младший байт

‘———

B_arfs = 1                 ‘запретить чтение АЦП

‘суммирование показаний

$asm

Rd_adc1:

$end Asm Return

Mov R0 , #{R_bd}  ;сумма данные

Mov R1 , #{Temp}  ;считанные данные

Mov R2 , #4       ;четыре байта

Clr C

Mov A , @R1       ;цикл суммирования

Addc A , @R0

Mov @R0 , A Inc R0

Inc R1

Djnz R2 , Rd_adc1

‘———

‘калибровка показаний

Calbr:

R_fld = R_fld – R_zero   ‘скорректировать смещение

R_fld = R_fld * R_scal   ‘поправить масштаб

Return

‘———

‘провести калибровку

Makeclb:

If R_ch = &H5B Then      ‘если введен Z – калибровать нуль

R_zero = R_fld        ‘показания – константа смещения

End If

If R_ch = &H53 Then      ‘если введен S – калибровать масштаб

R_fld = R_fld – R_zero’учтем поправку нуля и с ней

R_scal = 2 / R_fld    ‘вычислим константу масштаба

End If R_ch = 0

Return

‘——————————-

Следующий пример – программа тестирования цифрового синтезатора. В ней значение в формате с плавающей точкой и выраженной в килогерцах, преобразуется в значение количества единиц младшего разряда ЦАП, затем целое двоичное число и загружается в регистры синтезатора. Как и в предыдущих примерах, микросхема синтезатора подключена к процессору через последовательный интерфейс. Количество загружаемых бит – 40.

‘————————————————————– ‘    Монитор тестирования синтеза AD9850 в режиме с

‘    последовательной загрузкой данных. Кварц = 60 МГц

‘————————————————————– Dim N_dat As Bit                ‘бит "Есть новые данные"

N_inp Alias Scon.0              ‘бит "Есть ввод" (RI) ‘———————

Dim Temp As Byte                ‘временные данные

‘———————

Dim R_bd As Long                ’32-разр. двоичный код загрузки

‘———————

Dim R_frq As Single             ‘регистр значения частоты

Dim R_fld As Single             ‘регистр кода загрузки

‘——————— ‘подключение синтезатора

B_data Alias P1.5 : B_clk Alias P1.3 : B_fqud Alias P1.4 : B_res Alias P1.7 ‘———————

‘ TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART Config Timer2 = Timer , Gate = Internal , Mode = 2

$baud = 9600               ‘скорость 9.6 кБ

$crystal = 12000000        ‘при кварце 12 МГц

‘———————

‘подготовить линии управления к работе

Reset B_data : Reset B_clk : Reset B_fqud : Reset B_res ‘———————

‘главный цикл

Mc: Do

If N_dat = 1 Then       ‘есть новые данные?

N_dat = 0            ‘на самом деле это бит RI

Gosub Sload_9850     ‘загрузка новых данных

End If

If N_inp = 1 Then       ‘что-то принято?

N_inp = 0            ‘очистим без анализа

Input "Enter value of frequency [kHz] f= " , R_frq ‘ввод частоты

Print R_frq          ‘печатать введенное значение

‘чтобы получить код загрузки умножим на число: R_fld = R_frq * 71582.788 ‘ 2^32 / Fclk = 4294967296 / 60000 kHz R_bd = R_fld         ‘преобр. в целое 32-разр. число

Printhex "Hex " ; R_bd    ‘печать в hex формате

Set N_dat            ‘есть данные на вывод в синтезатор

End If Loop

‘——————————————

‘подпрограммы загрузки данных в синтезатор

Sload_9850:

Set B_fqud : Reset B_fqud   ‘сбросить интерфейс

Set B_clk : Reset B_clk     ‘защелкнуть код последовательного режима

Set B_fqud : Reset B_fqud   ‘разрешить последовательный режим ‘выдвинуть данные из R_bd в режиме 3 (мл. сначала , _/\_) Shiftout B_data , B_clk , R_bd , 3

‘выдвинуть последний байт с режимом и фазой

Temp = 0 : Shiftout B_data , B_clk , Temp , 3

Set B_fqud : Reset B_fqud   ‘исполнять загруженные данные

Return

‘——————————————

Почти всегда точность аналоговых преобразователей недостаточна для решения измерительной задачи. В данном случае речь идет измерения или воспроизведения абсолютного значения напряжения, тока или чего-либо еще. Типичная точность аналоговых преобразователей составляет единицы или, в лучшем случае, доли процента – результат  неидеальности  технологии   их   производства.  С  другой  стороны,  стабильность  метрологических характеристик  этих  же  преобразователе  на  два-три  порядка  (десятичных)  превосходит  их  параметрическую точность. Таким образом, выравнивая масштаб преобразования с внешним эталоном, можно достичь повышения их точности до значений стабильности (временной, температурной), нелинейности и  шумов. Такая операция называется калибровкой, в результате которой устанавливается  коэффициент преобразования АЦП или ЦАП. Калибровка может производиться в аналоговом виде, например, подстройкой напряжения опорного источника, но нас будет интересовать только  цифровая калибровка. Ее преимущества очевидны. Во-первых, аналоговая часть схемы не усложняется. Во-вторых, калибровка может проводиться без доступа внутрь калибруемого объекта, и с удаленным объектом тоже. Самое замечательное, что калибровка производится в том  состоянии устройства, в котором он и работает. Имеется возможность снизить и случайные составляющие операции калибровки. В итоге, повышается точность измерительного  преобразователя, причем даже в большей степени, чем при аналоговой калибровке.   Результаты   цифровой   калибровки,   представляющие   собой   цифровые   коэффициенты   обычно размещаются  в  энергонезависимой  памяти,  чтобы  их  можно  было  воспроизвести  при  повторном  включении питания калибруемого устройства. Не останавливаясь на методах организации хранения данных калибровки (это отдельный вопрос), рассмотрим методы калибровки.

Практически все методы цифровой калибровки можно свести всего к двум видам:

а)   калибровки   масштаба   (коррекция   мультипликативной   составляющей    погрешности).    Конечно, калибровка масштаба может состоять из нескольких составляющих, но, все равно, каждый раз, это будет операция умножения на корректирующий масштабный коэффициент, зависимый от каких то параметров;

б) калибровка смещения (коррекция аддитивной составляющей погрешности преобразователя).

Можно еще говорить о калибровке нелинейности преобразователя, но этот метод  применяется очень редко и всегда в дополнение, к уже указанным.

Калибровка  смещения  измерительного  тракта  учитывается  путем  вычитания  из  текущих  показаний,

значения, ранее запомненного при измерении напряжения на закороченном входе (U = 0).  Поправка масштаба производится  умножением  на  коэффициент,  определенный  как  отношения  эталонного  значения  к  текущим

показаниям  при  подаче  на  вход  напряжения,  равного  эталонному  значению.  В  программе  монитора  АЦП

AD7711A,  приведенной  выше,  применена  и  калибровка  смещения  и  масштаба  по  указанной  схеме.  Там  же имеется процедура калибровки, когда с клавиатуры подается команда произвести калибровку нуля или масштаба. В демонстрационной программе все несколько упрощено, но требуемый порядок полностью выполнен (вначале калибровка нуля, затем масштаба).

Калибровка ЦАП  реализуются  также,  но  с  точностью,  наоборот,  вследствие  обратного  направления преобразования  загружаемого  кода.  Вначале  приводится  в  действие  масштабный  коэффициент,  а  затем  из значения загружаемого кода вычитается поправка смещения нуля. Порядок же определения коэффициентов и для ЦАП  и  для  АЦП  одинаков  –  вначале  определяется  поправка  смещения,  а  затем  масштаба.  Это  значительно облегчает   процедуру    определения   поправочных   коэффициентов,   делая   процесс   одноступенчатым   (без итерационных циклов).

Как указывалось выше, скорость измерения АЦП обычно намного превосходит возможности устройств передачи  и  отображения  данных.  Так  происходит  потому,  что  конечным  приемником  информации  является человек, для которого пределом комфортного восприятия считается частота смены данных в пределах до 3 – 5 Гц. Это   обстоятельство   можно   использовать   с   максимальной   пользой,   например,   организовать   усреднение избыточных отсчетов АЦП. В результате, достигается повышение точности и разрешающей способности за счет дополнительного подавления шумов и помех. Особенно актуальна эта мера для многоразрядных АЦП (более 14 – 16 разрядов), младшие разряды которых не всегда могут быть реализованы в одиничном цикле преобразования. Усреднение может производиться простым  суммированием нескольких отсчетов, так и с помощью алгоритмов цифровой фильтрации. Отличие фильтрации от усреднения в том, что при усреднении поток данных визуально прореживается (данные поступают реже), а при фильтрации скорость выдачи данных может  остается прежней, однако, каждый выходной отсчет цифрового фильтра будет нести какую-то  часть предыдущих отсчетов. Для

наблюдателя процесса фильтрации также важен промежуток вхождения в стационарный режим фильтрации после ее включения, т.е. пока необходимый объем обрабатываемых данных еще не накоплен, на выходе программы не должно быть сбойных показаний. Это возможно, если при  включении режима фильтрации сбросить параметр фильтрации, имеющий значение, аналогичное постоянной времени обычного фильтра, а затем плавно увеличивать его (соответственно и степень  фильтрации до заданной). Ниже представлен фрагмент программы, содержащий самую  простую  подпрограмму  цифровой  фильтрации.  В  представленном  примере  предусмотрена  реализация плавного вхождения в процесс фильтрации. Представленная программа аналогична фильтру первого порядка. Для повышения  порядка  фильтра  достаточно  включить  в  процесс  обработки  две-три  (или  более)  аналогичные программы,  работающие  последовательно  и  с  различными  коэффициентами,  которые  и  установят  характер (модель) фильтра.

‘———————————————————————— ‘       Программа обработки по формуле фильтра первого порядка

‘                вызывается каждый раз в цикле измерения

‘———————————————————————— Dim B_stan As Bit               ‘бит стабильность

Dim Uav As Single               ‘выходное значение Dim R_an As Single              ‘параметр фильтрации Dim Uc As Single                ‘текущие показания Dim Tmp As Single               ‘временные данные

Dim N_m As Const 0.9            ‘параметр уменьшения

Dim N_f As Const 0.3            ‘окончательное значение R_an

R_an = 1                        ‘исходное значение параметра фильтрации

B_stan = 0                      ‘сбросить при включении фильтрации

‘        Uav = Uav(1-1/N) + Uc/N – КЛАССИЧЕСКАЯ ФОРМУЛА ФИЛЬТРА

‘        Uav = Uav(1-n) + Uc*n   – УПРОЩЕННАЯ ФОРМУЛА

‘ОБЕСПЕЧИВАЕТ СОКРАЩЕНИЕ ВРЕМЕНИ ВЫЧИСЛЕНИЙ (ИСКЛЮЧАЕТСЯ ДЕЛЕНИЕ И ‘ОДНО ДЕЙСТВИЕ) И ПРАКТИЧЕСКИ НЕОТЛИЧИМА ОТ КЛАССИЧЕСКОГО ВАРИАНТА ‘ПРИ НАБЛЮДЕНИИ ПО ИНДИКАТОРУ

‘ЗНАЧЕНИЕ КОНСТАНТЫ ФИЛЬТРАЦИИ, КОТОРОЕ ПРИ ВКЛЮЧЕНИИ РЕЖИМА ФИЛЬТРА

‘РАВНО 1, ЗАТЕМ С КАЖДЫМ ИЗМЕРИТЕЛЬНЫМ ТАКТОМ УМЕНЬШАЕТСЯ

‘В 1.11 РАЗА(1/N_m) ДО МИНИМАЛЬНОГО ЗНАЧЕНИЯ (N_f). ЗНАЧЕНИЯ N_m И N_f

‘ПОДОБИРАЮТСЯ ЭКСПЕРИМЕНТАЛЬНО, ЧТОБЫ ОБЕСПЕЧИТЬ КОМФОРТНОЕ ВРЕМЯ

‘УСТАНОВЛЕНИЯ, И ДОСТАТОЧНОЕ ПОДАВЛЕНИЕ ШУМОВ. Comp_av:

If B_stan = 1 Then      ‘установился стационарный режим?

Goto C_av2           ‘теперь достигли окончательного значения?

End If

R_an = R_an * N_m       ‘изменим значение параметра фильтрации

If R_an < N_f Then      ‘теперь достигли окончательного значения?

Set B_stan            ‘да – поставим бит стабильности

End If

C_av2:

Return

Tmp = 1 – R_an          ‘вычтем константу фильтрации из единицы Uav = Uav * Tmp         ‘возьмем из суммы соответствующую часть Tmp = Uc * R_an         ‘возьмем часть показаний АЦП

Uav = Uav + Tmp         ‘сложим с суммой

При    программировании    средствами    Bascom    часто    приходится    использовать    переменные,    не соответствующие по длине разрядной сетке ЦАП. При этом загружаемый в  ЦАП  код размещается в младших разрядах переменной, в результате чего, возникает опасность  переполнения разрядной сетки. Чтобы исключить такую возможность необходимо перед преобразованием проверять максимальное значение вводимого числа или числа, полученного после вычислений.

Легкость программирования Bascom провоцирует применение неоптимальных схем обработки данных (в первую очередь по критерию производительности). Чтобы успешно бороться  с этим «злом», рекомендуется в максимальной степени применять обработку данных на низком уровне (непосредственно в кодах загрузки ЦАП или с выходным кодом АЦП). Это, конечно,  сложнее для программиста, но дает существенный выигрыш, т.к.

целые  двоичные  числа  быстрее  обрабатываются  и  занимают  меньше  места  в  памяти.  На   низком  уровне рекомендуется выполнять следующие операции:

а) анализировать перегрузку АЦП и осуществлять выбор пределов измерения, если это  требуется. Это дает возможность предельно быстро реагировать на изменения входного сигнала, отдавая на «высший уровень» данные, действительно пригодные для получения конечного результата;

б) корректировать смещения АЦП и ЦАП, соответственно сохраняя поправки смешения в  виде целых

двоичных чисел;

в)   осуществлять   первичное   усреднение   данных   АЦП   и   при   необходимости   преобразовывать   в двухполярный вид;

г) записывать в массив или осуществлять сортировку, например по величине;

д) вычислять в прерываниях.

Источник: М.Л.Кулиш, СПРАВОЧНИК ПО ПРОГРАММИРОВАНИЮ BASCOM-8051, Краснодар 2001

По теме:

  • Комментарии