roboforum.ru

Технический форум по робототехнике.

Stm32L100 + Hts221

Stm32L100 + Hts221

BooSooV » 13 июл 2015, 11:35

Есть проблема, надо подружить STM32 и HTS221 по SPI Half Duplex.
Соединение:

HTS221 SCL --------- PB13(SCK2) STM32L100
................RDY---------PC6(RDY2)
................SDA---------PB15(MOSI2)
................CS------------PB12(CS2)

Использую код инициализации:

Код: Выделить всёРазвернуть

SPI_InitTypeDef SPI_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

SPI_Cmd(SPI2, DISABLE);
SPI_I2S_DeInit(SPI2);



// Настройки SPI2
SPI_InitStructure.SPI_Direction=SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode=SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL=SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA=SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial=7;

SPI_Init(SPI2,&SPI_InitStructure);

SPI_Cmd(SPI2,ENABLE);



Обмен данными:
Код: Выделить всёРазвернуть
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);
SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Tx);
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
SPI2->DR = 0xBC;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) {}
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);

SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Rx);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) {}
uint8_t temp2 = SPI2->DR;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);
SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Tx);
GPIO_SetBits(GPIOB, GPIO_Pin_12);


Датчик молчит.
а вот что на осциллографе:


Прошу вашей помощи в решении проблемы, даташитов начитался, как и всего остального, не помогает
Вложения
2.jpg
1.jpg

Re: Stm32L100 + Hts221

elmot » 13 июл 2015, 23:14

Первый же вопрос, даже не глядя на осциллограммы - где настройка и тактирование GPIO?

Re: Stm32L100 + Hts221

BooSooV » 14 июл 2015, 12:27

здесь))
Код: Выделить всёРазвернуть
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B
  //Линии SPI2
  //PB15(MOSI), PB14(MISO), PB13(SCK), PB12(NSS) - AF, Push-Pull, AF5(SPI1)
  GPIOB->MODER |= GPIO_MODER_MODER15_1 | GPIO_MODER_MODER14_1 | GPIO_MODER_MODER13_1 | GPIO_MODER_MODER12_1; //Alternate function
  GPIOB->OTYPER &= ~(GPIO_OTYPER_OT_15 | GPIO_OTYPER_OT_14 | GPIO_OTYPER_OT_13 | GPIO_OTYPER_OT_11); //Push-Pull
  GPIOB->AFR[1] |= (5<<28 | 5<<24 | 5<<20 | 5<<16); //PB15, PB14, P13, PB12 = AF5

Re: Stm32L100 + Hts221

elmot » 14 июл 2015, 20:30

Странные осциллограммы какие-то... Попробуй его по i2c завести. Резисторы только не забудь.

Re: Stm32L100 + Hts221

dccharacter » 14 июл 2015, 22:09

Я по осцилограммам вижу две проблемы (похоже, не связанные между собой)
1. У тебя чип селект отпускает рано. Почему-то не дожидается завершения приема.
2. Пока чип селект низкий, у тебя линия данных задавлена вниз передатчиком. То ли он не переконфигурируется на прием, то ли неправильно сконфигурирована нога (должна быть сконфигурирована как open drain и подтянута к питанию резистором)

Добавлено спустя 1 минуту 18 секунд:
А что вот это за микросегундные задержки, для чего?
for(uint32_t i=0; i<0x0000003F; i++);

Добавлено спустя 30 секунд:
http://www.ba0sh1.com/howto-use-stm32-s ... plex-mode/

Добавлено спустя 18 секунд:
Ну точно, у тебя пуш-пулл...

Re: Stm32L100 + Hts221

BooSooV » 15 июл 2015, 11:38

i2c не получится, так как платы уже разведены, и приходится работать с тем что есть
open drain пробовал раньше, не помогло
for(uint32_t i=0; i<0x0000003F; i++); без этих задержек он не правильно обменивался в тестовом режиме
кстати про тестовый режим,делал обмен по такому же интерфейсу(по одному проводу данных) на одной плате, и получилось, все работает вот код:
Код: Выделить всёРазвернуть
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET) {}
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
 
  SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Tx);
  SPI_BiDirectionalLineConfig(SPI1,SPI_Direction_Rx);
 
  GPIO_ResetBits(GPIOB, GPIO_Pin_4);
     
  SPI2->DR = 0x07;
   
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) {}
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) {}
 
  uint8_t temp1 = SPI1->DR;

  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET) {}
 
////////////////////////////////////////////////////////////////////////////
 
  SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Rx);
  SPI_BiDirectionalLineConfig(SPI1,SPI_Direction_Tx);

  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET) {}

  for(uint32_t i=0; i<0x0000003F; i++);
 
  SPI1->DR = 0x04;
 
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) {}
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) {}
 
  uint8_t temp2 = SPI2->DR;
 
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
  while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET) {}
 
  SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Tx);
  SPI_BiDirectionalLineConfig(SPI1,SPI_Direction_Rx);
 
  GPIO_SetBits(GPIOB, GPIO_Pin_4);


Добавлено спустя 5 минут 29 секунд:
а вот осцилограммы, передаем сначала 7 потом 4

Добавлено спустя 3 минуты 32 секунды:
И вот вопрос, почему тут вся передача проходит норм а с датчиком нет?
Вложения
ADS00004.jpg
ADS00003.jpg

Re: Stm32L100 + Hts221

dccharacter » 16 июл 2015, 21:08

А попробуй все-таки переключить ногу в open drain и попробуй когда в режим приема переключаешься отправить байт пустой в сторону датчика.


Код: Выделить всёРазвернуть
SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Rx);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);
SPI2->DR = 0xBC;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) {}
uint8_t temp2 = SPI2->DR;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
for(uint32_t i=0; i<0x0000003F; i++);


Rambler\'s Top100 Mail.ru counter