Как прочитать реестр?
Ниже приведен скетч, который я использую с 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;
}
@Rico, 👍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
}
Если бы вы использовали массив в качестве буфера чтения, вам не нужно было бы принудительно использовать максимум четыре байта за раз, поскольку беззнаковое целое число может содержать только четыре байта...
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Сколько цифр дает вам число 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