Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32L100 + HTS221
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
BooSooV
Здравствуйте, есть проблема, надо подключить 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, но тогда мы не можем считать, а насколько я понимаю мы должны сначала прислать адрес ячейки а потом считать инфу, и все по одному проводу. Объясните пожалуйста что не так, и как заставить работать.
SasaVitebsk
А SDA не наводит на мысль что интерфейс I2C? И как он соотносится с SPI?
BooSooV
Цитата(SasaVitebsk @ Jun 11 2015, 06:06) *
А SDA не наводит на мысль что интерфейс I2C? И как он соотносится с SPI?

SDA/SDI/SDO это одна ножка датчика,
а ножкой CS мы определяем будем общаться по SPI или I2C
сори за не точнсть, так на схеме написано что мне дали
Obam
Цитата(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.
RabidRabbit
Таки читайте внимательней рефренс-мануал на STM32L100, особенно раздел 28.3.4 Configuring the SPI for half-duplex communication sm.gif
И не слушайте Обаму - схему менять не надо sm.gif
BooSooV
Цитата(RabidRabbit @ Jun 11 2015, 06:24) *
Таки читайте внимательней рефренс-мануал на STM32L100, особенно раздел 28.3.4 Configuring the SPI for half-duplex communication sm.gif
И не слушайте Обаму - схему менять не надо sm.gif

спасибо, сейчас гляну
Obam
Если есть half-duplex, то не слушайте, а если нет, то…

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

BooSooV
прочитал 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 нуту полу дуплекса?

Полу дуплекса двунаправленного мне именно двунаправленность на одном проводе нужна
RabidRabbit
SPI_CR1_BIDIMODE - CR1 - это номер регистра, а не номер модуля SPI.

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

Ещё раз повторю: читайте документацию, там всё написано sm.gif
Obam
Цитата(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
BooSooV
уважаемые электроники, я так и не понял что мне надо сделать чтобы все заработало, надо:
установить бит BIDIOE = 1
отправить байт адреса откуда я хочу считать
установить бит BIDIOE = 0
считать байт от датчика
у меня правильный ход мыслей? или я опять запутался?
Obam
Цитата(BooSooV @ Jun 11 2015, 12:12) *
уважаемые электроники, я так и не понял что мне надо сделать чтобы все заработало, надо:
установить бит BIDIOE = 1
отправить байт адреса откуда я хочу считать
установить бит BIDIOE = 0
считать байт от датчика
у меня правильный ход мыслей? или я опять запутался?


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

спасибо, буду пробовать, потом отпишусь о успехах
BooSooV
Здравствуйте, я опять с вопросами, написал код который худо бедно передает по одному проводу данные, от мастера слейву и обратно, правда передает только один раз а не в цикле, где то накосячил.
Теперь я применил этот код к моему датчику температуры 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
Obam
Цитата(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 прием

Ох, ё-моё, а ведь переведён…
BooSooV
Цитата(Obam @ Jun 24 2015, 06:33) *
Здравствуйте sm.gif



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

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

Осцилограф есть =) без него бы я вообще ничего не смог, на нем сигнал отправляемым мастером выглядит хорошо,вроде, такт тоже в норме
Копи пастом грешу конечно, но без него и того бы не было, а на прием переводится командой

SPI2->CR1 &= ~ SPI_CR1_BIDIOE; //BIDIOE прием
Obam
Цитата(BooSooV @ Jun 24 2015, 10:42) *
Осцилограф есть =) без него бы я вообще ничего не смог, на нем сигнал отправляемым мастером выглядит хорошо,вроде, такт тоже в норме
Копи пастом грешу конечно, но без него и того бы не было, а на прием переводится командой

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


Обратно от датчика что?
BooSooV
Цитата(Obam @ Jun 24 2015, 06:44) *
Обратно от датчика что?

ничего, насколько я могу судить, сигналы идут очень быстро и возможно накладываются, а может он просто молчит
в общем ничего интересного от датчика нет
Obam
Цитата(BooSooV @ Jun 24 2015, 10:53) *
ничего, насколько я могу судить, сигналы идут очень быстро и возможно накладываются, а может он просто молчит
в общем ничего интересного от датчика нет


Зациклить обмен с датчиком.
Ждущая развертка, запуск от CS.
На каждый цикл обмена (CS 1-->0 и 1-->0) должно быть 16 синхроимпульсов SCK, на первые 8 - ваши данные (0x4F), на вторые 8 - ответ датчика.

Разворачивайте, смотрите.
BooSooV
Цитата(Obam @ Jun 24 2015, 07:07) *
Зациклить обмен с датчиком.
Ждущая развертка, запуск от CS.
На каждый цикл обмена (CS 1-->0 и 1-->0) должно быть 16 синхроимпульсов SCK, на первые 8 - ваши данные (0x4F), на вторые 8 - ответ датчика.

Разворачивайте, смотрите.

Посмотрел
for(uint32_t i=0; i<0x000000FF; i++);
//Прием данных.
изменил время задержки между приемом и передачей, и когда (CS 1-->0 и 1-->0) у меня там лежит 16 импульсов такта

но зато только сейчас заметил что в канале данных творится дурь, сейчас в пеинте написуюкакая
Obam
Цитата(BooSooV @ Jun 24 2015, 11:25) *
Посмотрел
for(uint32_t i=0; i<0x000000FF; i++);
//Прием данных.
изменил время задержки между приемом и передачей, и когда (CS 1-->0 и 1-->0) у меня там лежит 16 импульсов такта

но зато только сейчас заметил что в канале данных творится дурь, сейчас в пеинте написуюкакая


Очень хорошо; что с данными?
BooSooV
Цитата(Obam @ Jun 24 2015, 07:26) *
Очень хорошо; что с данными?


картинка с плавным падением сигнала


Для проверки канала подал 10101010, вот что увидел осцилограф в канале данных(ровные кубики)
Obam
"…Мойша The Beatles напел…" sm.gif

Синхроимпульсы как расположены?
0x4F, положим, видно. Плавный спад - разряд входной емкости. Ответ должен быть 0xBC.

10101010 - на фига? Датчик же висит на шине - хрень какая-нибудь загонтся в него…

Ё-моё! 0x4F! Маэстро, вы, не охренели? Запись в регистр для чтения?
BooSooV
Цитата(Obam @ Jun 24 2015, 07:59) *
"…Мойша The Beatles напел…" sm.gif

Синхроимпульсы как расположены?
0x4F, положим, видно. Плавный спад - разряд входной емкости. Ответ должен быть 0xBC.

10101010 - на фига? Датчик же висит на шине - хрень какая-нибудь загонтся в него…

Ё-моё! 0x4F! Маэстро, вы, не охренели? Запись в регистр для чтения?

Вот так расположены синхроимпульсы


но но уважаемый =)) никакой записи и в помин нет, если я не ошибаюсь
даташит http://www.farnell.com/datasheets/1836732.pdf (стр 16) гласит:
SPI read
The SPI read command is performed with 16 clock pulses:
bit 0: READ bit. The value is 1.
bit 1: MS bit. When 0, do not increment the address, when 1, increment the address in
multiple readings.
bit 2-7: address AD(5:0). This is the address field of the indexed register.
bit 8-15: data DO(7:0) (read mode). This is the data that is read from the device (MSB first).
Multiple read command is also available in 3-wires mode.

блин вижу свой косяк
Obam
Цитата(BooSooV @ Jun 24 2015, 12:05) *
но но уважаемый =)) никакой записи и в помин нет, если я не ошибаюсь

Да ну?
Нажмите для просмотра прикрепленного файла

0x4F как на картиночке будет расположено?
Тут старая сказка "про белого бычка": бит 0 в байте данных и бит 0 при его передаче. sm.gif
BooSooV
надо писать 8F == 10001111
1 = читаю
0 = без сдвига
001111 = откуда читаю
Спасибо за указание на ошибку, я один нолик пропустил
Obam
Кроме того, если нет записи, по-вашему, 11110010b (0x4F наоборот) по какому адресу читался ID датчика?

Цитата(BooSooV @ Jun 24 2015, 12:15) *
надо писать 8F == 10001111


Что датчик отвечает? Осцилл. старый? Почему сигналограммы в paint?
BooSooV
Цитата(Obam @ Jun 24 2015, 08:20) *
Кроме того, если нет записи, по-вашему, 11110010b (0x4F наоборот) по какому адресу читался ID датчика?



Что датчик отвечает? Осцилл. старый? Почему сигналограммы в paint?

не долгой была моя радость, датчик отвечает FF
Осцилограмма в пеинте потому что способа проще я не нашел, у меня простой осцилограф, старого типа, никакого вывода на комп нету, и вот что он нам показал:
Obam
И из DR читается 0xFF?
Повторяемость результата есть?

Цитата(BooSooV @ Jun 24 2015, 12:25) *
не долгой была моя радость, датчик отвечает FF


Не нравится мне плавный спад: синхроимпульсы в это время есть?
Кстати, фронты синхроимпульсов правильно выбраны?
BooSooV
Цитата(Obam @ Jun 24 2015, 08:32) *
И из DR читается 0xFF?
Повторяемость результата есть?

что за DR?
я ведь должен прислать датчику такое чтобы считать? 10111100 (BC) ?
повторяемость 100% с этим все стабильно))


Синхроимпульсы есть? а как проверить правильно ли выбраны их фронты?
Obam
Цитата(BooSooV @ Jun 24 2015, 12:40) *
что за DR?

DataRegister wink.gif
"bufPr1 = SPI2->DR;//Считываем данные из приемного б…"

Цитата
я ведь должен прислать датчику такое чтобы считать? 10111100 (BC) ?

0xBC должен ответить датчик.

Цитата
Синхроимпульсы есть? а как проверить правильно ли выбраны их фронты?


Данные SPI-блоком в контроллере могут двигаться по переднему или по заднему фронту синхроимпульсов.
Вот ответ датчика с правильным ID и будет признаком правильной настройки интерфейса.

Наличие синхроимпульсов во время плавного спада данных не годится.
BooSooV
Пойдем по списку))
смотрел на прямую DR, пишу в него BC (10111100)
1 - чтение
0 - без здвига
111100 - 6 разрядный адрес 0F задом наперед

можно как нибудь решить проблему плавного спада?

Я домой, дальнейшие пытки датчика продолжатся завтра с 9:00 =)
Obam
Стоять!!!!! Назад!!!!!

В DR 0xBC писать не надо. Это датчик во втором байте должен вернуть (т.е. процессор вычитать).
Вот примерно так:
Нажмите для просмотра прикрепленного файла
По поводу плавного спада: надо разобраться с исходным уровнем и активным фронтом SCK.
BooSooV
AD5 AD4.....AD0 они ведь идут задом наперед, не надо ли и адрес в бинарном коде писать задом наперед?
Так ведь чтобы что то передать это что то надо записать в DR, оттуда и считать что пришло, разве нет?
Obam
Шутки шутками, но доку (DS на датчик и контроллер и RefMan на контроллер) - курить до просветления.

Данные в датчик должны "вдуваться" старшим (MSB) битом вперёд: R\~Wбит это старший, AD5..AD0 - записаны от старшего к младшему => 10001111b. Зачем это преворачивать?

"Так ведь чтобы что то передать это что то надо записать в DR, оттуда и считать что пришло, разве нет?"
Так вы и писали в DR 0x8F при BIDIOE==1, а как этот байт был отправлен, то BIDIOE 1-->0 переключит SPI на приём и автоматически вычитает (R\~W==1 не забыли?) из датчика
данные по только что переданному адресу, их вы увидите тоже в DR.

И ещё: если не будет выполнено "This line is driven at the falling edge of SCL and should be captured at the rising edge of SCL." то не правильно будут тактироваться данные.
CPOL, CPHA соответствуют требуемому?
BooSooV
увидел только что одну проблему, мой код почему то на отправку генерит 16 импульсов, и ничего не генерит на прием, я думал что это 8 на передачу и 8 на прием, а оказалось что на прием воще ничего нет, сейчас пробую другой пример под себя переделать, об успехах отпишусь
Obam
CODE

SPI2->CR1 |= SPI_CR1_BIDIOE; //BIDIOE передача
SPI2->DR = 0x8F; //Пишем в буфер передатчика 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 передача

Ну откуда??? 8 синхроимпульсов от "SPI2->DR = 0x8F" и 8 синхроимпульсов от "SPI2->CR1 &= ~ SPI_CR1_BIDIOE"
BooSooV
Ну откуда??? 8 синхроимпульсов от "SPI2->DR = 0x8F" и 8 синхроимпульсов от "SPI2->CR1 &= ~ SPI_CR1_BIDIOE"[/quote]
если бы я знал)) я закоментил все, оставил только отправку, а как было 16 импульсов так и осталось
Obam
Цитата(BooSooV @ Jun 25 2015, 12:05) *
если бы я знал)) я закоментил все, оставил только отправку, а как было 16 импульсов так и осталось


• 8- or 16-bit transfer frame format selection

BooSooV
Цитата(Obam @ Jun 25 2015, 08:35) *
• 8- or 16-bit transfer frame format selection

но у меня выставлен формат данных 8, и вроде он должен отправлять и принимать по 8 импульсов, но на самом деле как я понял по его работе, он первую половину воспринимает как отправляемое сообщение, а вторую часть как получаемое, короче я воще ничего не понимаю,
запустил код на Дискавери, думал может что разведено не так,а один фиг при некоторых комбинациях вижу плавный спад


Передаю 2A, размер данных 8 бит, прицепил к осцилографу два щупа, и получил вот такое соответствие,
первый такт
второй данные
Такое разве нормально?
Obam
А что не так?
Нажмите для просмотра прикрепленного файла
00101010b==0x2A старшим битом вперёд. Всё нормально.
BooSooV
Меня смущает то, что в даташите на датчик, начало импульсов в шине данных совпадает с падением в шине такта, а у нас с подъёмом, это нормально?
Obam
"но у меня выставлен формат данных 8, и вроде он должен отправлять и принимать по 8 импульсов, но на самом деле как я понял по его работе, он первую половину воспринимает как отправляемое сообщение, а вторую часть как получаемое"

Во-первых, кто он?
Во-вторых, первый байт - адрес в датчике, а второй байт - данные (если запись в датчик) или ответ датчика (если чтение из него).

"SPI2->DR = 0x8F" команда, дающая передачу первого байта;
"SPI2->CR1 &= ~ SPI_CR1_BIDIOE" команда, дающая прием второго байта.
Если бы надо было записать данные в датчик, то использовалась бы вторая команда "SPI2->DR = 0x**".
BooSooV
The first bit (bit 0) starts at the first falling edge of SCL after the falling edge
of CS while the last bit (bit 15, bit 23,...) starts at the last falling edge of SCL just before the
rising edge of CS.
Вот выдержка из даташита, которая говорит тоже самое
Можно как то настроить чтобы он не по возрастанию читал линию данных а по падению
Obam
Цитата(BooSooV @ Jun 26 2015, 11:03) *
Меня смущает то, что в даташите на датчик, начало импульсов в шине данных совпадает с падением в шине такта, а у нас с подъёмом, это нормально?


Данные у вас меняются по заднему фронту SCL, фиксируются по переднему фронту. Всё нормально.
BooSooV
Цитата(Obam @ Jun 26 2015, 07:05) *
"но у меня выставлен формат данных 8, и вроде он должен отправлять и принимать по 8 импульсов, но на Во-первых, кто он?

ОН контроллер)) ко е что прояснилось, но вопросы с чтением по падению или возрастанию в линии тактирования открыты
Obam
Цитата(BooSooV @ Jun 26 2015, 11:11) *
The first bit (bit 0) starts at the first falling edge of SCL after the falling edge
of CS while the last bit (bit 15, bit 23,...) starts at the last falling edge of SCL just before the
rising edge of CS.
Вот выдержка из даташита, которая говорит тоже самое
Можно как то настроить чтобы он не по возрастанию читал линию данных а по падению



Биты CPOL, CPHA в настройках SPI
BooSooV
Цитата(Obam @ Jun 26 2015, 07:13) *
Данные у вас меняются по заднему фронту SCL, фиксируются по переднему фронту. Всё нормально.

Похоже и правда все норм))
от того страннее что ничего не работает))


Цитата(Obam @ Jun 26 2015, 07:17) *
Биты CPOL, CPHA в настройках SPI

этот вопрос снят, вроде и впрямь и так все правильно работает
зато вот какая странность
Это нормально? я думал что мое сообщение должно идти первым а не вторым?
Obam
Ну что?

SPI2->CR1 |= SPI_CR1_CPOL; //исходное состояние SCK==1
SPI2->CR1 |= SPI_CR1_CPHA; //capture 0-->1
не судьба?
BooSooV
сейчас сделаю)) посмотрим что будет
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.