Как прочитать реестр?

Ниже приведен скетч, который я использую с 32-битным АЦП TI ADS1262. Я пытался добиться максимального разрешения, установив усиление регистра MODE2 на 101, что составляет 32 В/В. Настройка PGA по умолчанию — 000 или 1 В/В. Строка, в которой я установил усиление: «PC_ADS1262.ads1262_Reg_Write(MODE2, 5<<4 | 2);» Я думаю, что он, вероятно, настроен на 32 В/В, но мне хотелось прочитать регистр, чтобы убедиться, где оно на самом деле установлено. Я не знаю, как сделать чтение реестра, есть предложения? На странице 85 таблицы данных ADS1262 показана команда чтения регистра RREG, но я просто не знаю, как ее использовать. Кстати, при подключении АЦП к напряжению 10 мВ лучшие результаты, которые я получаю, составляют 0,00997589244 вольт или 0,00997589149 вольт. Он прыгает между этими двумя показаниями напряжения. Таким образом, приращение составляет 0,00000000095 вольт. Это довольно хорошая точность, но она не 32-битная. Техническое описание ADS1262

 example.ino
 this example gives differential voltage across the AN0 And AN1 in volts
 Hooking-up with the Arduino
 ----------------------
|ads1262 pin label| Pin Function         |Arduino Connection|
|-----------------|:--------------------:|-----------------:|
| DRDY            | Data ready Output pin|  D6              |             
| MISO            | Slave Out            |  D12             |
| MOSI            | Slave In             |  D11             |
| SCLK            | Serial Clock         |  D13             |
| CS              | Chip Select          |  D7              |
| START           | Start Conversion     |  D5              | 
| PWDN            | Power Down/Reset     |  D4              |
| DVDD            | Digital VDD          |  +5V             |
| DGND            | Digital Gnd          |  Gnd             |
| AN0-AN9         | Analog Input         |  Analog Input    |
| AINCOM          | Analog input common  |                  |
| AVDD            | Analog VDD           |  -               |
| AGND            | Analog Gnd           |  -               |
-----------------------------------------------------------------
*/
#include <SPI.h>
#include <SoftwareSerial.h>
#include <math.h>
#include <ads1262.h>

#define PGA 32
#define VREF 2.50                 // Internal reference of 2.048V
#define VFSR VREF/PGA             
#define FSR (((long int)1<<23)-1)  

ads1262 PC_ADS1262;                     // class

float volt_V=0;
float volt_mV=0;
volatile int i;
volatile char SPI_RX_Buff[10];
volatile long ads1262_rx_Data[10];
volatile static int SPI_RX_Buff_Count = 0;
volatile char *SPI_RX_Buff_Ptr;
volatile int Responsebyte = false;
volatile signed long sads1262Count = 0;
volatile signed long uads1262Count=0;
double resolution;



void setup() 
{
  // initalize the  data ready and chip select pins:
  pinMode(ADS1262_DRDY_PIN, INPUT);                  //data ready input line
  pinMode(ADS1262_CS_PIN, OUTPUT);                   //chip enable output line
  pinMode(ADS1262_START_PIN, OUTPUT);               // start 
  pinMode(ADS1262_PWDN_PIN, OUTPUT);                // Power down output   

  Serial.begin(9600);
  //initalize ADS1292 slave
  PC_ADS1262.ads1262_Init();                      // initialise ads1262
  Serial.println("ads1262 Initialised successfully....");

 }

void loop() 
{
  volatile int i,data;


 if((digitalRead(ADS1262_DRDY_PIN)) == LOW)               // monitor Data             ready(DRDY pin)
  {  
    SPI_RX_Buff_Ptr = PC_ADS1262.ads1262_Read_Data();      // read 6 bytes  conversion register
    Responsebyte = true ; 
  }

  if(Responsebyte == true)
  {
    for(i = 0; i <5; i++)
    {
      SPI_RX_Buff[SPI_RX_Buff_Count++] = *(SPI_RX_Buff_Ptr + i);              
    }
    Responsebyte = false;
  }

  if(SPI_RX_Buff_Count >= 5)
  {     


    ads1262_rx_Data[0]= (unsigned char)SPI_RX_Buff[1];  // read 4 bytes adc count
    ads1262_rx_Data[1]= (unsigned char)SPI_RX_Buff[2];
    ads1262_rx_Data[2]= (unsigned char)SPI_RX_Buff[3];
    ads1262_rx_Data[3]= (unsigned char)SPI_RX_Buff[4];


     uads1262Count = (signed long) (((unsigned long)ads1262_rx_Data[0]<<24)|   ((unsigned long)ads1262_rx_Data[1]<<16)|(ads1262_rx_Data[2]<<8)|ads1262_rx_Data[3]);//get the raw 32-bit adc count out by shifting
     sads1262Count = (signed long) (uads1262Count);      // get signed value
     PC_ADS1262.ads1262_Reg_Write(MODE2, 5<<4 | 2);  //Here is where I set the gain
     resolution = (double)((double)VREF/pow(2,31));       //resolution= Vref/(2^n-1) , Vref=2.5, n=no of bits
    // Serial.print(resolution,15);
     volt_V      = (resolution)*(float)sads1262Count;     // voltage = resolution * adc count
     volt_mV   =   volt_V*1000;                           // voltage in mV
     Serial.print("Readout voltage");
     Serial.print(" : ");
     Serial.print(volt_V,9);
     Serial.print(" V ,");

   }

  SPI_RX_Buff_Count = 0;

}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

, 👍1

Обсуждение

Сколько цифр дает вам число float/double? https://en.wikipedia.org/wiki/Single-precision_floating-point_format, @Mikael Patel

Не уверен, что это то, что вам нужно, Микаэль, но я сделал «Serial.print(resolve,35);» и получил 0.00000003890134334564208984375000000, @Rico

В AVR gcc float и double имеют 32-битную точность (одинарная точность). Это дает точность от 6 до 9 значащих десятичных цифр (как указано в вики). Вы теряете 8 бит информации при преобразовании 32-битного целого числа в 32-битное число с плавающей запятой., @Mikael Patel

Я думаю, что ответ на ваш первоначальный вопрос - 10 цифр. Например, 9,997589244мВ. Но последние две цифры не совсем точны, и их следует округлить до 9,9975892, что даст 8 цифр. Вероятно, это находится в области 24-битной точности. Вы согласны?, @Rico

Да, 32-8 это 24 :)., @Mikael Patel


1 ответ


1

Вот важные части кода, который я использую для ЧТЕНИЯ или ЗАПИСИ регистров в чипе ADS1263... Надеюсь, это поможет вам преодолеть это препятствие...

// 2-байтовые команды ADS1263.
// Обратите внимание, что 3 старших бита — это команда, остальные биты — это адрес начального регистра.
// Обратитесь к таблице 37 на странице 85 документа SBAS661B.PDF для получения подробной информации о схеме команд АЦП.
// Чтение регистров XXXn nnnn, начиная с адреса XXXr rrrr. Первый байт 001р рррр и второй байт 000н нннн.
// Запись регистров XXXn nnnn, начиная с адреса XXXr rrrr. Первый байт 010r rrrr и второй байт 000n nnnn.
const byte WREG = 0x40; // 0b01000000 Команда ADS1263 Запись 40h + рег-адрес.
const byte RREG = 0x20; // 0b00100000 ADS1263 Чтение команды 20h + адрес регистрации.
const byte MASK = 0x03; // 0b00000011 маскирует старшие разряды и ограничивает размер блока от 0 до 3 байтов.

unsigned int ads1263_Read_Reg(byte thisRegister, byte bytesToRead)
{
byte inByte = 0;
unsigned int result = 0;
byte readStatus = 0;
byte readCRC = 0;

... REDACTED 
// ADS1263 ожидает адрес регистра в младших 5 битах байта. Поэтому сдвиг битов не требуется:
// Теперь объединим адрес и команду в один байтовый бит, замаскированный, чтобы добавить команду чтения регистра.

byte dataToSend = thisRegister | RREG;
byte lengthToRead = byte bytesToRead & MASK; // Принудительно использовать максимум 3 байта.

... REDACTED

SPI.transfer(dataToSend);
result = SPI.transfer(0x00);
lengthToRead--;
if (lengthToRad > 0)
    {
    result = result << 8;
    inByte = SPI.transfer(0x00);
    result = result | inByte;
    lengthToRead--;
    }

... REDACTED

Serial.print("Register Data: ");
Serial.println(result, BIN);

... REDACTED
}

Если бы вы использовали массив в качестве буфера чтения, вам не нужно было бы принудительно использовать максимум четыре байта за раз, поскольку беззнаковое целое число может содержать только четыре байта...

,