top of page

Модули АЦП

ADS1100

unit ads1100T;
{$O-}
{$xdata}
{$idata}
//================================================
//БЛОК РАБОТЫ С АЦП ADS1100
interface
var
          PSA1100:real;        //ХРАНИТЕЛЬ КОДА PSA АЦП
          b1100:integer;       //СЧИТАННОЕ ЗНАЧЕНИЕ
          pb1100:integer;
          FORMAT1100:byte;     //ХРАНИТЕЛЬ ФОРМАТА ДАННЫХ: 12,14,15 ИЛИ 16
          PGA1100:byte;        //ХРАНИТЕЛЬ УСИЛЕНИЯ АЦП: 1,2,4,8
          ref1100:word;        //опорное напряжение ацп
          ADR1100:byte;        //адрес ацп в серии (0-7)
          reg1100:byte;        //буфер регистра для записи в ацп параметров его работы
          sc1100:boolean;      //флаг одиночного преобразования Single Conversion
          b1100r:real;
          OffsetError:integer; //аддитивная ошибка (ошибка смещения)
          NonLinear:real;
          Code1100:integer;
         
          //sda:boolean absolute $0a0;
          //scl:boolean absolute $0a1;
procedure getadsc;
procedure getadr1100;
procedure Wr1100;
procedure Rd1100;
procedure In1100;
procedure In1100M;
procedure In1100MR;
implementation
uses declare,ports,i2c;
const adr1100g=%10010000;
//===============================================
procedure getadsc;
          //ПОДПРОГРАММА ВЫЧИСЛЕНИЯ ПОПРАВОЧНОГO КОЭФФИЦИЕНТА
          //ДЛЯ АЦП ADS1100 ПРИ ЗАДАННОМ ФОРМАТЕ И ЗАДАННОМ
          //КОЭФФИЦИЕНТЕ УСИЛЕНИЯ, КОТОРЫЕ ЗАДАЮТСЯ В КОН-
          //СТАНТАХ FORMAT1100 И PGA1100 СООТВЕТСТВЕННО.
          //В РЕЗУЛЬТАТЕ СОДЕРЖИМОЕ ПЕРЕМЕННОЙ PSA1100
          //ЯВЛЯЕТСЯ ДЕЛИТЕЛЕМ В ФОРМУЛЕ РАСЧЕТА НАПРЯЖЕНИЯ,
          //ЧИСЛИТЕЛЕМ КОТОРОЙ ЯВЛЯЕТСЯ СЧИТАННЫЙ АЦП КОД.
          //КРОМЕ ТОГО, ПЕРЕМЕННАЯ REG1100 СОДЕРЖИТ КОНФИГУРАЦИОННЫЙ
          //КОД, ЗАПИСЫВАЕМЫЙ В БАЙТ КОНФИГУРАЦИИ АЦП.
begin         
reg1100:=$80;
if (format1100=13) or (format1100<12) then format1100:=12;
if format1100>16 then format1100:=16;

case format1100 of      //установка DR0 и DR1 в конфигурационном регистре
  16: begin valr:=32768;reg1100:=reg1100 or %00001100;end;//16, 32, 64, 128
  15: begin valr:=16384;reg1100:=reg1100 or %00001000;end;//8, 16, 32, 64
  14: begin valr:=8192;reg1100:=reg1100 or %00000100;end;//4, 8, 16, 32
  12: begin valr:=2048;reg1100:=reg1100 or %00000000;end;//1, 2, 4, 8
end;
valr:=valr*pga1100;
psa1100:={round}(valr/ref1100);     //вычисление пересчетного коэффициента,
                                     //на значение которого будет делиться код,
                                     //если нужно определить значение входного
                                     //напряжения в мВ.

if sc1100 then reg1100:=reg1100 or %00010000;    //установка режима работы АЦП -
                                                  //единичное или непрерывное преобразование.
//b:=pga1100;
b:=0;
case pga1100 of
  1: b:=0;
  2: b:=1;
  4: b:=2;
  8: b:=3;
end;
//dec(b);
reg1100:=reg1100 or b;  //установка PGA0 и PGA1 в конфигурационном регистре
end;
{
         7       6       5       4       3       2       1       0
       st/drdy   0       0      SC      dr1     dr0    pga1     pga0
      
В режиме единичного преобразования установка бита  st/drdy запускает процесс
преобразования. Затем производится непрерывный опрос указанного бита программой
польхователя. Как только он становится равным 0, преобразование завершено,
и данные размещены в выходном регистре. Теперь их можно считать.

В режиме непрерывного преобразования бит  st/drdy управляется АЦП. Когда он сброшен,
данные готовы к чтению. После считывания выходного регистра АЦП устанавливает  st/drdy
в 1 и держит его на этом уровне до тех пор, пока не произведет следующее преобразование,
после чего опять установит  st/drdy в 0.
}

{Более ранняя заметка.
Если АЦП находится в режиме единичного преобразования,
установка ST/DRDY в 1 запускает процесс преобразования.
После окончания данного процесса АЦП устанавливает ST/DRDY
в 0, что означает возможность считывания данных.
В режиме непрерывного преобразования установка ST/DRDY
пользователем в 1 игнорируется АЦП.
По-видимому, ST/DRDY автоматически устанавливается в
1 после чтения данных или чтения регистра состояния.}

//===============================================
//Процедура исходного определения адреса ацп.
//Производится последовательное обращение к АЦП
//с индивидуальным номером от 0 до 7. Как только
//АЦП ответит, происходит выход из подпрограммы
//с назначенным adr1100. Если в указанном диапазоне
//адресов ответ от АЦП не получен, возникает
//ошибка с кодом 17 - "Адрес АЦП не определен".
procedure getadr1100;
begin
//getadsc;
i2cinit;
for adr1100:=0 to 8 do
  begin
   asm
    mov a,adr1100
    clr c
    rlc a
    orl a,#adr1100g
    lcall i2cadr
    lcall i2cstop
   end;
   if not I2CError then break;
  end;
if adr1100=8 then err:=17 else err:=0;
end;
//===============================================
//процедура записи конфигурационного регистра в ацп
procedure Wr1100;
begin
i2cstart;
asm                //формирование старт-байта для записи
  mov a,adr1100
  clr c
  rlc a
  orl a,#adr1100g
  clr acc.0
end;
i2cwb;
i2cans;
acc:=reg1100;
i2cwb;
i2cans;
i2cstop;
end;
//===============================================
//процедура чтения данных из ацп
procedure Rd1100;
begin
i2cstart;
asm                //формирование старт-байта для чтения
  mov a,adr1100
  clr c
  rlc a
  orl a,#adr1100g
  setb acc.0
end;
i2cwb;
i2cans;
i2crb;
b1100:=acc;
b1100:=b1100 shl 8;
i2cansm;
i2crb;
b1100:=b1100+acc;
i2cansm;
i2crb;
i2cansm;
i2cstop;
cy:=acc.7;
//if not Polarline1100 then b1100:=-b1100;
end;
//===============================================
//процедура чтения данных из ацп с контролем готовности
procedure Rd1100s;
begin
//repeat
while 1<>0 do
  begin
   rd1100;
   if not cy then exit;       //ждем готовности данных
  end;
//until not cy;
end;
//===============================================
//процедура полного цикла работы ацп с выдачей кода
procedure In1100;
begin
wr1100;                      //запись конфигурационного регистра,
                              //в режиме одиночного преобразования - запуск.
rd1100s;                     //проверка готовности данных и их считывание
b1100:=b1100+OffsetError;
end;
//===============================================
//процедура полного цикла работы ацп с выдачей
//результата в милливольтах
procedure In1100M;
begin
wr1100;                      //запись конфигурационного регистра,
                              //в режиме одиночного преобразования - запуск.
rd1100s;                     //проверка готовности данных и их считывание
b1100:=b1100+OffsetError;
b1100:=round(b1100*NonLinear);
code1100:=b1100;
b1100:=round(b1100/psa1100); //пересчет в милливольты
end;
//===============================================
//процедура полного цикла работы ацп с выдачей
//результата в милливольтах (вещественное значение)
procedure In1100MR;
begin
wr1100;                      //запись конфигурационного регистра,
                              //в режиме одиночного преобразования - запуск.
rd1100s;                     //проверка готовности данных и их считывание
b1100:=b1100+OffsetError;
code1100:=b1100;
if b1100<0 then b1100:=0;
b1100r:=((b1100*NonLinear)/psa1100);     //пересчет в милливольты
end;
//===============================================
end.

ADS8325

unit ads8325;
{$Idata}
{$O-}
{$xdata}
interface

procedure in8325;


var
   data8325:word;
  
implementation
uses declare,ports,common;
//*************************************************
//ПОДПРОГРАММА ПРИЕМА ДАННЫХ ОТ АЦП ADS8325
//ПРИНЯТЫЕ ДАННЫЕ РАСПОЛАГАЮТСЯ В R6:R7 и в data8325
//=================================================
{
Для расчета результатов измерений в мВ, если используется
на входе INA159, применяется формула:
Vmv=(Code-32768)/3.2
INA159 укладывает диапазон входных напряжений
+/-10В в диапазон выходных напряжений 48-4048 мВ
при напряжении опоры 4096 мВ, которая одновременно
}
//----------------------------
          //ПОДПРОГРАММА ФОРМИРОВАНИЯ ТАКТИРУЮЩЕГО ИМПУЛЬСА
procedure CLK;assembler;      //3  0.15
asm
          setb LINEACLK        //2  0.1
          clr LINEACLK       //2  0.1
end;                          //3  0.15
//=================================================
          //LINEACLK=P3.0
          //LINEDATA=P3.1
          //LINECONV=P3.2
          //USING 2
procedure IN8325;             //3  0.15
label INDATA0;
begin
asm
          clr LINEACLK
          MOV r6,#0           //2  0.1 MKS
          MOV r7,#0           //2  0.1
          CLR LINECONV        //2  0.1
         
          LCALL CLK           //4  0.5
          LCALL CLK           //4  0.5
          LCALL CLK           //4  0.5
          LCALL CLK           //4  0.5
          LCALL CLK           //4  0.5
          LCALL CLK           //4  0.5
         
          //LCALL CLK           //4  0.5
          MOV R2,#16          //2  0.1
INDATA0:  setb LINEACLK        //2  0.1  \
          MOV C,LINEDATA      //2  0.1  |
          MOV A,r7            //1  0.05 |
          RLC A               //1  0.05 |
          MOV r7,A            //1  0.05  \   Цикл 1,2 мкс * 16=19,2 мкс
          MOV A,r6            //1  0.05  /
          RLC A               //1  0.05 |
          MOV r6,A            //2  0.1  |
          clr LINEACLK       //2  0.1  |
          DJNZ R2,INDATA0     //3  0.15 /
          SETB LINECONV       //2  0.1

          mov data8325,r7     //2  0.1
          mov data8325+1,r6   //2  0.1
end;                         //3  0.15
end;
//При частоте генератора микроконтроллера 20 Мгц
//длительность цикла работы с АЦП составляет 19,2 мкс,
//входная и выходная часть подпрограммы занимают 4,55 мкс,
//то есть вся подпрограмма имеет длительность ~ 23,6 мкс.
//Частота на LINEACLK составляет 1,25 Мгц, на
//LINECONV - примерно 40 кГц.
//================================================

end.

ADS7834

unit ads7834;
{$Idata}
{$O-}
{$xdata}
interface

procedure in7834;
procedure shift;
procedure Read7835;
procedure Volt7835;
procedure Code7835;
procedure MVolt7835;

var
   data7834:integer;
  
implementation
uses declare,ports,common;
var cb:byte;
//*************************************************
//ПОДПРОГРАММА ПРИЕМА ДАННЫХ ОТ АЦП ADS7834
//ПРИНЯТЫЕ ДАННЫЕ РАСПОЛАГАЮТСЯ В R6:R7 и в data7834
//=================================================
//----------------------------
          //ПОДПРОГРАММА ФОРМИРОВАНИЯ ТАКТИРУЮЩЕГО ИМПУЛЬСА
procedure CLK;assembler;
asm
          SETB LINEACLK
          CLR LINEACLK
end;
//=================================================
          //LINEACLK=P3.0
          //LINEDATA=P3.1
          //LINECONV=P3.2
          //USING 2
procedure IN7834;
label INDATA0;
begin
asm
          MOV r6,#0
          MOV r7,#0
          CLR LINEACLK
          CLR LINECONV
          LCALL CLK
          LCALL CLK
          MOV R2,#12
INDATA0:  SETB LINEACLK
          MOV C,LINEDATA
          MOV A,r7
          RLC A
          MOV r7,A
          MOV A,r6
          RLC A
          MOV r6,A
          CLR LINEACLK
          NOP
          DJNZ R2,INDATA0
          SETB LINECONV
end;
          data7834:=ar6;
          data7834:=data7834 shl 8;
          data7834:=data7834+ar7;
end;
//================================================
procedure Shift;
begin
if cy then cb:=1 else cb:=0;
data7834:=data7834 shl 1;
data7834:=data7834 and $fffe;
data7834:=data7834 or cb;
end;
//================================================
procedure Read7835;
begin
if faver then
  begin
   aver:=0;
    for iw:=1 to 1000 do
     begin
      loadacc;
      if (not linemode) or (not linesave) then exit;
      in7834;
      asm
       mov a,data7834+1
       mov c,acc.3
      end;
      if cy then data7834:=data7834 or %1111000000000000;
      aver:=aver+data7834;
     end;
     data7834:=round(aver/1000);
  end
   else
    begin
     in7834;
      asm
       mov a,data7834+1
       mov c,acc.3
      end;    
     if cy then data7834:=data7834 or %1111000000000000;
    end;
end;
//================================================
procedure Code7835;
begin
      asm
       mov a,data7834+1
       mov c,acc.3
      end;    
if cy then data7834:=data7834 or %1111000000000000;
data7834:=round(data7834*1.221);
data7834:=round(data7834*KDADS7835);
end;
//================================================
procedure Volt7835;
begin
read7835;
data7834:=round(data7834*1.221);
valr:=data7834*KDADS7835/1000;
end;
//================================================
procedure MVolt7835;
begin
read7835;
data7834:=round(data7834*1.221);
data7834:=round(data7834*KDADS7835);
end;
//================================================
end.

ADS7835

unit ads7835;
//{$Idata}
{$O-}
//{$xdata}
interface

procedure in7834;
procedure in7835;

var
   buf7834:integer;
  
implementation
uses declare,ports;


//================================================
//ПОДПРОГРАММА ПРИЕМА ДАННЫХ ОТ АЦП ADS7834
//ПРИНЯТЫЕ ДАННЫЕ РАСПОЛАГАЮТСЯ В buf7834
//================================================
//ПОДПРОГРАММА ФОРМИРОВАНИЯ ТАКТИРУЮЩЕГО ИМПУЛЬСА
procedure CLK;
begin
lineaclk:=true;
acc:=acc;
lineaclk:=false;
end;
//----------------------------     
procedure IN7834;
begin
buf7834:=0;
lineaclk:=false;
lineconv:=false;
CLK;
CLK;
for i:=1 to 12 do
  begin
   asm
    setb lineaclk
    mov c,linedata
    mov a,buf7834
    rlc a
    mov buf7834,a
    mov a,buf7834+1
    rlc a
    mov buf7834+1,a
    clr lineaclk
   end;     
  end;
  lineconv:=true;      
end;
//===============================================
//подпрограмма приема данных от ADS7835
procedure in7835;
begin
in7834;
if (buf7834 and $0800)<>0 then
  begin
   buf7834:=not(buf7834)+1;
   buf7834:=buf7834 and $0fff;
   buf7834:=-buf7834;
  end;
end;   
//-----------------------------------------------
end.

ADS7888

unit ads7888;
{$O-}
{$xdata}
{$idata}
interface
//ПОДПРОГРАММА ЧТЕНИЯ ADS7888
var    ref7888:word idata;
          buf7888:word;
         
          //cs7888:boolean absolute $a0;
          //clk7888:boolean absolute $a1;
          //sdo7888:boolean absolute $a2;
procedure in7888;
procedure in7888mv;         
         
implementation 
uses declare,ports;       
//------------------------------------------------
procedure clock7888;assembler;
asm
          CLR CLK7888
          NOP
          SETB CLK7888
end;
//------------------------------------------------
procedure in7888;assembler;
label IN78880,IN78881,IN78882;
asm
          clr a
          mov buf7888,a
          mov buf7888+1,a
          CLR CS7888
          MOV R2,#4
IN78880:  LCALL CLOCK7888
          DJNZ R2,IN78880
          CLR A
          MOV R2,#8
IN78881:  MOV C,SDO7888
          RLC A
          LCALL CLOCK7888
          DJNZ R2,IN78881
          MOV R2,#4
IN78882:  LCALL CLOCK7888
          DJNZ R2,IN78882
          SETB CS7888
          mov buf7888,a
end;
//------------------------------------------------
procedure in7888mv;
begin
          IN7888;
          vall:=buf7888;
          buf7888:=trunc((vall * ref7888) / 256);
end;
//------------------------------------------------
end.

bottom of page