Я пытаюсь прочитать данные из EVAL-ADXL355-PMDZ, подключенного к комплекту обнаружения Lora STM2L072 через протокол SPI для проекта. Сначала я использовал датчик ADXL345 и смог прочитать данные акселерометра c и преобразовать их в g без каких-либо проблем. После переключения датчика на ADXL355 я продолжаю получать все нули при чтении регистров данных вместо этого.
Я изменил свой начальный код для ADXL345 в соответствии с таблицей данных датчика ADXL355 (https://www.analog.com/media/en/technical-documentation/data-sheets/adxl354_355.pdf), чтобы он мог работать с новым датчиком.
Основные изменения касаются настроек шины подключения SPI (ADXL345 использовал CPOL = 1 и CPHA = 1, а ADXL355 использует CPOL = 0 и CPHA = 0), имена регистров, количество байтов для чтения для каждой оси и коэффициент преобразования для преобразования необработанных данных в г. Я сохранил конфигурацию prescaler, которую я имел для ADXL345, где я установил его на 64, что дает мне скорость 500 Кбит / с c.
Также, по сравнению с ADXL345, бит R / W должен установить до младшего бита адреса, и я заметил, что бит многобайтового чтения не может быть установлен, но у меня есть некоторые сомнения по этому поводу, хотя, похоже, мне не нужно устанавливать его из таблицы данных (см. ссылку выше).
Это основной код (он инициализирует периферийные устройства и акселерометр и выполняет простое считывание данных l oop каждые 2 секунды):
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "string.h"
/* Private variables ---------------------------------------------------------*/
RTC_HandleTypeDef hrtc;
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
uint8_t data[9]; /*Buffer to hold SPI data. Axis acceleration is a 20 bit value, and it's stored
in consecutive registers, from the most significative to the least significative data
and in left-justified mode. It is thus needed to read 3 bytes for each axis (i.e. 9 consecutive bytes
for each axis). */
int32_t x,y,z; /*variables that hold the binary acceleration reads. */
float xg, yg, zg; /*variables that hold the data converted in g. */
uint8_t data_tx[2];
uint8_t temp;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
//function to write 1 byte in a register on the accelerometer through SPI
//void SPI_write(uint8_t address, uint8_t value);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void SPI_write (uint8_t address, uint8_t value) //function to write 1 byte in a register on the accelerometer through SPI
{
data_tx[0]= (address<<1) | 0x00; /* set write operation= to enter Write mode you have to set the 8th bit of the first byte sent to 0.*/
data_tx[1] = value; /*byte to write in the register*/
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET); // pull the CS pin (PA12) low (selects the slave)
HAL_SPI_Transmit (&hspi2, data_tx, 2, 100); // write data to register specifying that it consists of 2 bytes (address+value)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); // pull the CS pin high
}
void SPI_read (uint8_t address, int bytes) //function to read multiple bytes from a register on the accelerometer through SPI
{
address = (address<<1) | 0x01; /* set read operation= to enter Read mode you have to set the 8th bit of the first byte sent to 1.*/
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET); // pull the CS pin low
HAL_SPI_Transmit (&hspi2, &address, 1, 100); // send address
HAL_SPI_Receive (&hspi2, data, bytes, 100); // receive the data
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); // pull the CS pin high
}
void adxl_init(void){
//Configuring the Range
SPI_write(0x2C, 0x02); /*b00000001=0x01 in 0x2C register (Interrupt Polarity, Range register)
sets a 4g range. The ADXL also uses 20 bit RES and stores data in the left-justified mode.*/
//Configuring the Power Control or POWER_CTL register:
SPI_write(REG_POWER_CTL, 0x06); /* enters measurement mode and disables temperature reading */
}
void display_Data(double val, char axis){ //displays acceleration data using UART
char msg[20];
sprintf(msg, "%c: %f",axis, val);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
char newline[2] = "\r\n";
HAL_UART_Transmit(&huart2, (uint8_t *) newline, 2, 10);
}
void readSensor(void){
SPI_read(0x08, 9); /*the full accelerometer information is held in 3 bytes for each axis, so you need to read 9 bytes
(also, acceleration data is stored from the most significant bit to the least significant one) */
// copy the 3 bytes received for each axis into a single variable
x=((data[0]<<16) | (data[1]<<8) | data[2]) >>4; /*moving the first received byte at the beginning (left-justified),
then using an OR to concatenate it with the second byte (shifted the same way) and lastly the third byte
Since this are 20-bits values, we then shift the copied value 4 bits to the right*/
y=((data[3]<<16) | (data[4] <<8) | data[5]) >>4;
z=((data[6]<<16) | (data[7] <<8) | data[8]) >>4;
//converting to g
/* From the datasheet we get that for a +-4g sensitivity the scale factor is 7.8 ug/LSB.
* To convert the data we just need to multiple with 7.8 and then divide by 1000000*/
xg=x*0.0000078;
yg=y*0.0000078;
zg=z*0.0000078;
}
int check_adxl(void){
SPI_read(0x01, 1);
temp=(uint8_t)data[0];
return (temp==0x1D);
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
MX_SPI2_Init();
MX_USART2_UART_Init();
//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); //sets CS line high when not reading/writing
/* USER CODE BEGIN 2 */
HAL_Delay(1000);
adxl_init();
char *mex="Accelerometer...";
char line[2] = "\r\n";
HAL_UART_Transmit(&huart2, (uint8_t *) mex, 15, 10);
HAL_UART_Transmit(&huart2, (uint8_t *) line, 2, 10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(2000);
/*Reading and displaying sensor data*/
readSensor();
display_Data(xg, 'X');
display_Data(yg, 'Y');
display_Data(zg, 'Z');
HAL_UART_Transmit(&huart2, (uint8_t *) line, 2, 10);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Это моя конфигурация SPI для ADXL355 (выполненная с использованием STM32CubeMX):
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
Результат, который я получаю, всегда равен нулю. Кроме того, если я пытаюсь прочитать другие регистры, я получаю либо 0, либо 255, поэтому я предполагаю, что проблема в соединении SPI.
Я проверял соединения тысячу раз, и они должны быть правильными (это документация, которую я использовал https://wiki.analog.com/resources/eval/user-guides/eval-adicup360/hardware/adxl355).
Я видел некоторые другие подобные проблемы, подобные этой Чтение данных из ADXL355 с использованием python интерфейса SPI на Raspberry Pi (даже если этот использует малину), и мне было интересно, может ли ADXL355 возможно есть проблемы?
Заранее спасибо за любую помощь по этому вопросу.