реклама на сайте
подробности

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> STM32L100 + HTS221
BooSooV
сообщение Jun 11 2015, 05:52
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



Здравствуйте, есть проблема, надо подключить HTS221(датчик температуры и влажности) к STM32L100.
Схема соеденения:
HTS221 SCL --------- PB13(SCK2) STM32L100
................RDY---------PC6(RDY2)
................SDA---------PB15(MOSI2)
................CS------------PB12(CS2)
Схема соединения изменению не подлежит.
Инициализация SPI 2:
CODE
#define GPIO_Pin_NSS2 GPIO_Pin_12 // NSS (CS)
#define GPIO_Pin_SCK2 GPIO_Pin_13 // SCK
#define GPIO_Pin_MISO2 GPIO_Pin_14 // MISO
#define GPIO_Pin_MOSI2 GPIO_Pin_15 // MOSI
#define GPIOSPI2 GPIOB

#define GPIO_PinSourceSCK2 GPIO_PinSource13
#define GPIO_PinSourceMISO2 GPIO_PinSource14
#define GPIO_PinSourceMOSI2 GPIO_PinSource15

// -- Инициализация GPIO для SPI2 ----------------------------------------------
void init_GPIO_for_SPI2()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure2;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // Запуск необходимых GPIO

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCK2 | GPIO_Pin_MISO2 | GPIO_Pin_MOSI2;
GPIO_Init(GPIOSPI2, &GPIO_InitStructure);

// нога NSS(CS2). она управляется программно, ПОЭТОМУ
// она конфигурируется как выход
GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure2.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure2.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure2.GPIO_Pin = GPIO_Pin_NSS2;
GPIO_Init(GPIOSPI2, &GPIO_InitStructure2);

// Настраиваем ноги SPI2 для работы в режиме альтернативной функции
GPIO_PinAFConfig(GPIOSPI2, GPIO_PinSourceSCK2, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOSPI2, GPIO_PinSourceMISO2, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOSPI2, GPIO_PinSourceMOSI2, GPIO_AF_SPI2);

GPIO_SetBits(GPIOSPI2, GPIO_Pin_NSS2);
}


// -- Инициализация SPI2 -------------------------------------------------------
void Init_SPI2()
{
SPI_InitTypeDef SPI_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

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

init_GPIO_for_SPI2();

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

SPI_Init(SPI2,&SPI_InitStructure);

SPI_Cmd(SPI2,ENABLE);

GPIO_SetBits(GPIOSPI2, GPIO_Pin_NSS2);
}

Чтение регистра датчика:
Код
  uint8_t cmd = 0x4F;

   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET) {}
   GPIO_ResetBits(GPIOSPI2, GPIO_Pin_NSS2);

   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) {}
   SPI_I2S_SendData(SPI2, cmd);  

   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) {}
   uint8_t data = SPI_I2S_ReceiveData(SPI2);
  
   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) {}
   SPI_I2S_SendData(SPI2, 0x00);

   while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) {}
   data = SPI_I2S_ReceiveData(SPI2);

   GPIO_SetBits(GPIOSPI2, GPIO_Pin_NSS2);

по идее должен выдать свое имя
Такая схема у меня работала на другом SPI но там было MOSI И MISO разными проводами, а тут все в одном, что делать не знаю пробовал поставить в инициализации SPI_Direction_1Line_Tx, но тогда мы не можем считать, а насколько я понимаю мы должны сначала прислать адрес ячейки а потом считать инфу, и все по одному проводу. Объясните пожалуйста что не так, и как заставить работать.

Сообщение отредактировал IgorKossak - Jun 11 2015, 05:59
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 11 2015, 06:06
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



А SDA не наводит на мысль что интерфейс I2C? И как он соотносится с SPI?
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 11 2015, 06:12
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



Цитата(SasaVitebsk @ Jun 11 2015, 06:06) *
А SDA не наводит на мысль что интерфейс I2C? И как он соотносится с SPI?

SDA/SDI/SDO это одна ножка датчика,
а ножкой CS мы определяем будем общаться по SPI или I2C
сори за не точнсть, так на схеме написано что мне дали
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 11 2015, 06:23
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(BooSooV @ Jun 11 2015, 09:52) *
Здравствуйте, есть проблема, надо подключить HTS221(датчик температуры и влажности) к STM32L100.
Схема соеденения:
HTS221 SCL --------- PB13(SCK2) STM32L100
................RDY---------PC6(RDY2)
................SDA---------PB15(MOSI2)
................CS------------PB12(CS2)
Схема соединения изменению не подлежит.


SPI у датчика "не SPI". Схема соединения подлежит не изменению, а доработке: вывод MOSI2 соединить с MISO2.
Тогда после отправки первого байта, программно придется переключать MOSI2 в режим GP_I и принимать байт ответа по MISO2.


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jun 11 2015, 06:24
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



Таки читайте внимательней рефренс-мануал на STM32L100, особенно раздел 28.3.4 Configuring the SPI for half-duplex communication sm.gif
И не слушайте Обаму - схему менять не надо sm.gif
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 11 2015, 06:27
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



Цитата(RabidRabbit @ Jun 11 2015, 06:24) *
Таки читайте внимательней рефренс-мануал на STM32L100, особенно раздел 28.3.4 Configuring the SPI for half-duplex communication sm.gif
И не слушайте Обаму - схему менять не надо sm.gif

спасибо, сейчас гляну
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 11 2015, 06:45
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Если есть half-duplex, то не слушайте, а если нет, то…

Кстати, ST всех вводят в заблуждение: этот интерфейс назывался 2Wire.



--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 11 2015, 07:14
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



прочитал 28.3.4 Configuring the SPI for half-duplex communication
поискал в системных файлах халф дуплекс но нашел только такие конфигурации:
файл stm32l1xx_spi.h
CODE
/** @defgroup SPI_data_direction
* @{
*/

#define SPI_Direction_2Lines_FullDuplex ((uint16_t)0x0000)
#define SPI_Direction_2Lines_RxOnly ((uint16_t)0x0400)
#define SPI_Direction_1Line_Rx ((uint16_t)0x8000)
#define SPI_Direction_1Line_Tx ((uint16_t)0xC000)
#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_Direction_2Lines_FullDuplex) || \
((MODE) == SPI_Direction_2Lines_RxOnly) || \
((MODE) == SPI_Direction_1Line_Rx) || \
((MODE) == SPI_Direction_1Line_Tx))
/**

у меня не полу дуплекса или я что то не понял?

нашел ещё один сомнительный момент в коде
CODE
/******************* Bit definition for SPI_CR1 register ********************/
#define SPI_CR1_CPHA ((uint16_t)0x0001) /*!< Clock Phase */
#define SPI_CR1_CPOL ((uint16_t)0x0002) /*!< Clock Polarity */
#define SPI_CR1_MSTR ((uint16_t)0x0004) /*!< Master Selection */

#define SPI_CR1_BR ((uint16_t)0x0038) /*!< BR[2:0] bits (Baud Rate Control) */
#define SPI_CR1_BR_0 ((uint16_t)0x0008) /*!< Bit 0 */
#define SPI_CR1_BR_1 ((uint16_t)0x0010) /*!< Bit 1 */
#define SPI_CR1_BR_2 ((uint16_t)0x0020) /*!< Bit 2 */

#define SPI_CR1_SPE ((uint16_t)0x0040) /*!< SPI Enable */
#define SPI_CR1_LSBFIRST ((uint16_t)0x0080) /*!< Frame Format */
#define SPI_CR1_SSI ((uint16_t)0x0100) /*!< Internal slave select */
#define SPI_CR1_SSM ((uint16_t)0x0200) /*!< Software slave management */
#define SPI_CR1_RXONLY ((uint16_t)0x0400) /*!< Receive only */
#define SPI_CR1_DFF ((uint16_t)0x0800) /*!< Data Frame Format */
#define SPI_CR1_CRCNEXT ((uint16_t)0x1000) /*!< Transmit CRC next */
#define SPI_CR1_CRCEN ((uint16_t)0x2000) /*!< Hardware CRC calculation enable */
#define SPI_CR1_BIDIOE ((uint16_t)0x4000) /*!< Output enable in bidirectional mode */
#define SPI_CR1_BIDIMODE ((uint16_t)0x8000) /*!< Bidirectional data mode enable */

/******************* Bit definition for SPI_CR2 register ********************/
#define SPI_CR2_RXDMAEN ((uint8_t)0x01) /*!< Rx Buffer DMA Enable */
#define SPI_CR2_TXDMAEN ((uint8_t)0x02) /*!< Tx Buffer DMA Enable */
#define SPI_CR2_SSOE ((uint8_t)0x04) /*!< SS Output Enable */
#define SPI_CR2_FRF ((uint8_t)0x08) /*!< Frame format */
#define SPI_CR2_ERRIE ((uint8_t)0x20) /*!< Error Interrupt Enable */
#define SPI_CR2_RXNEIE ((uint8_t)0x40) /*!< RX buffer Not Empty Interrupt Enable */
#define SPI_CR2_TXEIE ((uint8_t)0x80) /*!< Tx buffer Empty Interrupt Enable */



#define SPI_CR1_BIDIMODE ((uint16_t)0x8000) /*!< Bidirectional data mode enable */
в даташите написано 1 clock and 1 bidirectional data wire (BIDIMODE=1)
а на SPI2 нету BIDIMODE, только на SPI1 значит ли это что на SPI2 нуту полу дуплекса?

Полу дуплекса двунаправленного мне именно двунаправленность на одном проводе нужна
Go to the top of the page
 
+Quote Post
RabidRabbit
сообщение Jun 11 2015, 07:24
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 397
Регистрация: 3-12-09
Из: Россия, Москва
Пользователь №: 54 040



SPI_CR1_BIDIMODE - CR1 - это номер регистра, а не номер модуля SPI.

Делее про полудуплекс. Вся соль в частичке "полу" sm.gif То есть низзя одновременно передавать и принимать. Если Вы внимательно рассмотрите протокол SPI для датчика HTS221, то увидите, что мастер в начале обмена всегда передаёт один байт, а далее уже по обстоятельствам - либо передаёт, либо принимает, за направление овечает бит SPI_CR1_BIDIOE.

Ещё раз повторю: читайте документацию, там всё написано sm.gif
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 11 2015, 07:41
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(RabidRabbit @ Jun 11 2015, 11:24) *
SPI_CR1_BIDIMODE - CR1 - это номер регистра, а не номер модуля SPI.

Делее про полудуплекс. Вся соль в частичке "полу" sm.gif То есть низзя одновременно передавать и принимать. Если Вы внимательно рассмотрите протокол SPI для датчика HTS221, то увидите, что мастер в начале обмена всегда передаёт один байт, а далее уже по обстоятельствам - либо передаёт, либо принимает, за направление овечает бит SPI_CR1_BIDIOE.

Ещё раз повторю: читайте документацию, там всё написано sm.gif


"…The transfer direction (Input/Output) is selected by the BIDIOE bit in the
SPI_CR1 register. When this bit is 1, the data line is output otherwise it is input…"
Так что я был не далёк от истины, предлагая переводить MOSI во GP-вход у дуплексного SPI. sm.gif


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 11 2015, 08:12
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



уважаемые электроники, я так и не понял что мне надо сделать чтобы все заработало, надо:
установить бит BIDIOE = 1
отправить байт адреса откуда я хочу считать
установить бит BIDIOE = 0
считать байт от датчика
у меня правильный ход мыслей? или я опять запутался?
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 11 2015, 08:23
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(BooSooV @ Jun 11 2015, 12:12) *
уважаемые электроники, я так и не понял что мне надо сделать чтобы все заработало, надо:
установить бит BIDIOE = 1
отправить байт адреса откуда я хочу считать
установить бит BIDIOE = 0
считать байт от датчика
у меня правильный ход мыслей? или я опять запутался?


Да


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 11 2015, 08:36
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



Цитата(Obam @ Jun 11 2015, 08:23) *
Да

спасибо, буду пробовать, потом отпишусь о успехах
Go to the top of the page
 
+Quote Post
BooSooV
сообщение Jun 24 2015, 05:57
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 35
Регистрация: 10-06-15
Пользователь №: 87 107



Здравствуйте, я опять с вопросами, написал код который худо бедно передает по одному проводу данные, от мастера слейву и обратно, правда передает только один раз а не в цикле, где то накосячил.
Теперь я применил этот код к моему датчику температуры HTS221, но не получил ничего от него, прошу вашей помощи в поиске ошибок

//Инициализация GPIO
CODE
void gpio_init()
{
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN; //Тактирование портов A, B


//Линии SPI2 (Master)
//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



// настройка ноги управления
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD, ENABLE); // Запуск необходимых GPIO


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_Pin_12);



}


//Инициализация SPI2
CODE
void spi_init()
{
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
SPI2->CR1 |= SPI_CR1_BR; //Baud rate = Fpclk/256
SPI2->CR1 &= ~SPI_CR1_CPOL; //Полярность тактового сигнала
SPI2->CR1 &= ~SPI_CR1_CPHA; //Фаза тактового сигнала
SPI2->CR1 &= ~SPI_CR1_DFF; //8 бит данных
SPI2->CR1 &= ~SPI_CR1_LSBFIRST; //MSB передается первым
SPI2->CR1 |= SPI_CR1_SSM; //Программный режим NSS
SPI2->CR1 |= SPI_CR1_SSI; //Аналогично состоянию, когда на входе NSS высокий уровень
SPI2->CR2 |= SPI_CR2_SSOE; //Вывод NSS - выход управления slave select
SPI2->CR1 |= SPI_CR1_MSTR; //Режим Master

SPI2->CR1 |= SPI_CR1_BIDIMODE; // двунаправленный режим по одной шине данных
SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача

SPI2->CR1 |= SPI_CR1_SPE; //Включаем SPI1



}



//Основной цикл программы

// MASTER SPI2
CODE
int main()
{
gpio_init(); //Вызов функции инициализации портов
spi_init(); //Вызов функции инициализации модулей SPI
//GPIOH->BSRRL |= GPIO_BSRR_BS_12; // передача запрещена
GPIO_SetBits(GPIOB, GPIO_Pin_12);//общение запрещено
while(1)
{
//GPIOB->BSRRH |= GPIO_BSRR_BS_12; // начинаем передачу
GPIO_ResetBits(GPIOB, GPIO_Pin_12);//начинаем общние

//передача данных.

SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача
SPI2->DR = 0x4F; //Пишем в буфер передатчика SPI1.
while(!(SPI2->SR & SPI_SR_TXE));// Ожидаем окончания передачи данных
SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача

for(uint32_t i=0; i<0x000FFFFF; i++);
//Прием данных.

SPI2->CR1 &= ~ SPI_CR1_BIDIOE; //BIDIOE прием
while(!(SPI2->SR & SPI_SR_RXNE));//приняли данные
bufPr1 = SPI2->DR;//Считываем данные из приемного буфера SPI1. При этой операции происходит очистка буфера и сброс флага RXNE
SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача




//GPIOB->BSRRL |= GPIO_BSRR_BS_12; // заканчиваем передачу
GPIO_SetBits(GPIOB, GPIO_Pin_12);//общение запрещено

//Временная задержка между вызовами функции обмена данными
for(uint32_t i=0; i<0x000FFFFF; i++);
}
}


Этим кодом я спрашиваю его имя
http://www.farnell.com/datasheets/1836732.pdf
страница 16
Go to the top of the page
 
+Quote Post
Obam
сообщение Jun 24 2015, 06:33
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Цитата(BooSooV @ Jun 24 2015, 09:57) *
Здравствуйте,

Здравствуйте sm.gif

Цитата
//передача данных.

SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача
SPI2->DR = 0x4F; //Пишем в буфер передатчика SPI1.
while(!(SPI2->SR & SPI_SR_TXE));// Ожидаем окончания передачи данных
SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача


Точно Spi переведён на приём? Copy-paste погубит мир sm.gif

А вообще, для подобных работ осциллограф наипервейшее средство. Есть?

PS:
Цитата
for(uint32_t i=0; i<0x000FFFFF; i++);
//Прием данных.

SPI2->CR1 &= ~ SPI_CR1_BIDIOE; //BIDIOE прием

Ох, ё-моё, а ведь переведён…

Сообщение отредактировал Obam - Jun 24 2015, 06:41


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 11:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01514 секунд с 7
ELECTRONIX ©2004-2016