Top.Mail.Ru
Уведомления
Очистить все

[Решено] Как при помощи CMSIS получить адрес WHO_AM_I с акселерометра LIS3DSH, который находится на STM32F407 Discovery?

 stm
(@stm)
Level 4

С HAL это делается так:

uint8_t address=0x8F; //Register address+read
uint8_t result;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); //Chip Select
HAL_SPI_Transmit(&hspi1,&address,1,1000);
HAL_SPI_Receive(&hspi1,&result,1,1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); //Chip Select

А с CMSIS кажется надо 2 раза посылать данные и 2 раза получать.

sk

Пробовал так, не получается:

uint8_t address=0x8F; //Register address+read
uint8_t result;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET); //Chip Select
SPI1->DR = address;
while((SPI1->SR & SPI_SR_BSY) != RESET);
result=SPI1->DR;
while((SPI1->SR & SPI_SR_BSY) != RESET);
SPI1->DR = 0;
while((SPI1->SR & SPI_SR_BSY) != RESET);
result=SPI1->DR;
while((SPI1->SR & SPI_SR_BSY) != RESET);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET); //Chip Select

Использовать флаг SPI_SR_TXE не получается, бит SPI_SR_TXE постоянно в нуле.


Цитата
Создатель темы Размещено : 20.10.2023 06:20
 stm
(@stm)
Level 4

Флаг SPI_SR_TXE принимает значение ноль после этой строчки

SPI1->DR = address;

И после этого флаг SPI_SR_TXE в единицу не становится.


ОтветитьЦитата
Создатель темы Размещено : 20.10.2023 06:48
Aveal MT
(@aveal)
Top level Admin

В целом механизм такой:

uint16_t SPI_TransmitReceive(uint16_t data)
{
  while(!(SPI1->SR & SPI_SR_TXE));
  SPI1->DR = data;
  while(!(SPI1->SR & SPI_SR_RXNE));
  return SPI1->DR;
}

У Эдуарда в посте есть описание обменных процедур через регистры - ссылка.


ОтветитьЦитата
Размещено : 20.10.2023 09:46
 stm
(@stm)
Level 4

SPI1->DR это 8 битный регистр. У меня так SPI1 настроен.
uint16_t data это 16 битная переменная.
Здесь идёт сохранение 16 битной переменной в 8 битный регистр. В моём случае.

SPI1->DR = data;

Наверное с 16 битным SPI1->DR легче, но у меня 8 битный.

Поэтому мне как то надо 2 раза по 8 бит передать и получить 8 битный адрес WHO_AM_I.

SPI1->DR = data;  //Здесь передаю адрес регистра WHO_AM_I
receive=SPI1->DR ;  //Получаю ненужные данные.
SPI1->DR = 0;  //Здесь посылаю пустые 8 бит
receive=SPI1->DR ;  //Здесь надо получить значение регистра WHO_AM_I
tim

ОтветитьЦитата
Создатель темы Размещено : 21.10.2023 01:42
 stm
(@stm)
Level 4

CR1->SPE не был включен.


ОтветитьЦитата
Создатель темы Размещено : 21.10.2023 03:16
 stm
(@stm)
Level 4
while(!(SPI1->SR & SPI_SR_RXNE));

Пока SR & SPI_SR_RXNE пустой, надо ждать.
Не наоборот надо?
Пока SR & SPI_SR_RXNE полный, надо ждать, когда освободится, то заполнять его.
0: Rx buffer empty
1: Rx buffer not empty

У TXE бита наоборот
0: Tx buffer not empty
1: Tx buffer empty


ОтветитьЦитата
Создатель темы Размещено : 21.10.2023 03:25
 stm
(@stm)
Level 4
Рабочий код. SPI_CR1_SPE у меня не был активирован.
 
SPI1->CR1  |= SPI_CR1_SPE; 
uint8_t address=0x8F; //Register address+read
uint8_t result;
HAL_GPIO_Wr