Перейти к содержанию
    

STM32 HAL SPI ошибка или глюки IAR,

Ничего хитрого

The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register: If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit). If FRXTH is cleared (default), RXNE goes high and stays high until the RXFIFO level is greater than or equal to 1/2 (16-bit).

и сначала ставим CR2 а потом CR1

 

SPI1->CR2 = 0; // 16 bit

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_SPE; // или как надо

 

В RM есть.

 

В HAL SPI_Init() есть код

 

/* Align by default the rs fifo threshold on the data size */

if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)

{

frxth = SPI_RXFIFO_THRESHOLD_HF;

}

else

{

frxth = SPI_RXFIFO_THRESHOLD_QF;

}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обмен идет с CC2500

 

Про осцилограф.

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

 

Проверял в самом начале проекта. Осцллограммы идеальные - и STM32 и СС2500 выдают правильные картинки.

 

"при добавлении третьего чтения портятся data1,data2,data3"

 

uint8_t localRxBuf[4];

uint8_t data1,data2,data3;

 

Исходя из объявления, эта память находится в одном сегменте, одного типа (uint8_t) , и вполне вероятно "слитно".

Похоже что ф-ия HAL пишет в массив данные, которые не того типа, или не того кол-ва, или и то и другое.

Запись начиная с localRxBuf[0] зашкаливает за localRxBuf[3] и возможно, затирает data123

 

Расположил вот так:

 

uint8_t localRxBuf1[16];
uint8_t localRxBuf2[16];
uint8_t localRxBuf3[16];
uint8_t localRxBuf4[16];
uint8_t data1,data2,data3;
uint16_t dataX1,dataX2,dataX3;
.......
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf1[0], 1, 10000);
   data1=localRxBuf1[0];
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf2[0], 1, 10000);
   data2=localRxBuf2[0];
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf3[0], 1, 10000);
   data3=localRxBuf3[0];

 

все равно прием неправильный...

 

 

Ничего хитрого

The RXNE flag is set depending on the FRXTH bit value in the SPIx_CR2 register: If FRXTH is set, RXNE goes high and stays high until the RXFIFO level is greater or equal to 1/4 (8-bit). If FRXTH is cleared (default), RXNE goes high and stays high until the RXFIFO level is greater than or equal to 1/2 (16-bit).

и сначала ставим CR2 а потом CR1

 

SPI1->CR2 = 0; // 16 bit

SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_SPE; // или как надо

 

В RM есть.

 

В HAL SPI_Init() есть код

 

/* Align by default the rs fifo threshold on the data size */

if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)

{

frxth = SPI_RXFIFO_THRESHOLD_HF;

}

else

{

frxth = SPI_RXFIFO_THRESHOLD_QF;

}

 

Я об этом как раз и упоминал.

В HAL_SPI_Init() ниже в CR2 ставится/снимается бит FRXTH.

hspi->Instance->CR2 = (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode | hspi->Init.NSSPMode | hspi->Init.DataSize ) | frxth;

 

Для 8-битного режима FRXTH должен быть сброшен, собственно переменная принимает значение0: frxth = SPI_RXFIFO_THRESHOLD_HF;

Но непонятно условие для этого: if(hspi->Init.DataSize > SPI_DATASIZE_8BIT) ????

Не получается ли, что это никогда не выполняется и всегда ставится режим SPI_RXFIFO_THRESHOLD_QF(16 бит)?

 

Изменено пользователем Pasa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проверил с stm32f030 и CC2500 - всё работает как часы.

Проверьте инициализацию spi

SPI_DIRECTION_2LINES

SPI_CRCCALCULATION_ENABLE

SPI_DATASIZE_8BIT

и пройдите по шагам

HAL_StatusTypeDef HAL_SPI_Receive(...

никаких чудес нет.

SPI_CS программный у меня.

 

Там все понятно. Если байтов принимается > 1, то включается 16 бит режим - SPI пофигу, а процессору меньше работы.

Последний байт (если есть) принимается в 8-бит режиме. Но можно использовать от 4-х бит до 9-бит (байтовый обмен) или от 9 до 16 (2 байта на обмен)

 

Но проще посмотреть дебаггером, что конкретно происходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция SPI Receive в HAL занимает строк 20 из них 10 фуфло всякое. Пройдите по шагам и посмотрите что там делается. За пять минут (вместо дня гадания) уже всё определили бы и получали свои байты.

 

Никакого гадания нет. Уже давно все посмотрел. Потому и поднял тему, что не понятно каким образом аппартано в регистр DR залетает мусор и на выходе HAL-функции получаем полный бред, портящий буфер приема.

 

на всякий случай SPI проинициализирован вот так:

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

 

 

Проверил с stm32f030 и CC2500 - всё работает как часы.

Проверьте инициализацию spi

SPI_DIRECTION_2LINES

SPI_CRCCALCULATION_ENABLE

SPI_DATASIZE_8BIT

и пройдите по шагам

HAL_StatusTypeDef HAL_SPI_Receive(...

никаких чудес нет.

SPI_CS программный у меня.

 

Там все понятно. Если байтов принимается > 1, то включается 16 бит режим - SPI пофигу, а процессору меньше работы.

Последний байт (если есть) принимается в 8-бит режиме. Но можно использовать от 4-х бит до 9-бит (байтовый обмен) или от 9 до 16 (2 байта на обмен)

 

Но проще посмотреть дебаггером, что конкретно происходит.

 

читаю от CC2500 три регистра:

    
cmd_byte = ( (regAddr & 0x3f) | TI_CCxxx0_READ_BURST );  // regAddr - начальный адрес регистра

   CS_LO(); // /CS = 0

   HAL_SPI_Transmit(&hspi1, &cmd_byte, 1, 10000);

   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf1[0], 1, 10000);
   data1 = localRxBuf1[0];
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf2[0], 1, 10000);
   data2 = localRxBuf2[0];
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf3[0], 1, 10000);
   data3 = localRxBuf3[0];

   CS_HI(); // /CS = 1

 

на выходе в data1,data3,data3 путаница

А на осциллографе совершенно правильная картинка.....и на MISO и на MOSI

 

Попробуйте пж-ста мою конструкцию....заработает ли у вас? .......не могу понять что у меня происходит

 

 

в CC2500 для теста пишу так:

uint8_t localRxBuf1[16];
uint8_t localRxBuf2[16];
uint8_t localRxBuf3[16];
uint8_t localRxBuf4[16];
uint8_t data1,data2,data3;
uint16_t dataX1,dataX2,dataX3;

CC2500_Init();
CC2500_WriteRegSingle(0x09,     0x55); 
CC2500_WriteRegSingle(0x0A,     0x33); 
CC2500_WriteRegSingle(0x0B,     0x07); 

while(1)
{

   HAL_Delay(1000);

   cmd_byte = ( 0x09  | TI_CCxxx0_READ_BURST );  // regAddr - начальный адрес регистра

   CS_LO(); // /CS = 0

   HAL_SPI_Transmit(&hspi1, &cmd_byte, 1, 10000);


   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf1[0], 1, 10000);
   data1 = localRxBuf1[0];
   dataX1=(uint16_t)hspi1.Instance->DR;

   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf2[0], 1, 10000);
   data2 = localRxBuf2[0];
   dataX2=(uint16_t)hspi1.Instance->DR;

   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf3[0], 1, 10000);
   data3 = localRxBuf3[0];
   dataX3=(uint16_t)hspi1.Instance->DR;

   CS_HI(); // /CS = 1

 

}

 

[/code]

 

Значения dataX1 dataX2 dataX3 по циклам:

0x000F - 0x3355 - 0x0007

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

0x0733 - 0x0007 - 0x5500

.......

 

p.s.

с работы сторожа выгоняют...появлюсь через 30 минут ( в 0:10)

Изменено пользователем Pasa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ничего хитрого

Хитрость для меня была в том, что CR2->FRXTH пришлось инициализировать при каждой

записи-чтении.

 

сначала ставим CR2 а потом CR1

Может быть винт от хитрости как раз в этом. Надо будет проверить.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вот и моя хитрость. Чтение делаю 3 (три) раза подряд. К примеру мне надо установить бит в каком либо регистре.

Раньше (в типовом пример из интернета) было так:

    void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask) 
        {
    TM_MFRC522_WriteRegister(reg, TM_MFRC522_ReadRegister(reg) | mask);
        }

Глючит.

А вот так работает уверенно:

    void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask) 
        {
        int BUFR;
        BUFR=TM_MFRC522_ReadRegister(reg);
        BUFR=TM_MFRC522_ReadRegister(reg);
        BUFR=TM_MFRC522_ReadRegister(reg);
        BUFR=BUFR | mask;
        
    TM_MFRC522_WriteRegister(reg, BUFR);
            
        }

А можно и по другому, саму функцию TM_MFRC522_ReadRegister вызываем только раз,

    void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask) 
        {
        int BUFR;
        BUFR=TM_MFRC522_ReadRegister(reg);
        BUFR=BUFR | mask;
        
    TM_MFRC522_WriteRegister(reg, BUFR);
            
        }

а вот в ней:

uint8_t TM_MFRC522_ReadRegister(uint8_t addr) 
    {
    uint8_t val;
    uint8_t j;
    j=addr;
    
    ZAPRC522[0] = (addr << 1) & 0x7E;
    ZAPRC522[0] = ZAPRC522[0] | 0x80;

    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, ZAPRC522, OTVRC522, 2, 20);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_SET);
    BUFRC522[j]=OTVRC522[0];
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, ZAPRC522, OTVRC522, 2, 20);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_SET);
    BUFRC522[j]=OTVRC522[0];
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, ZAPRC522, OTVRC522, 2, 20);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_SET);
    BUFRC522[j]=OTVRC522[0];
    val = OTVRC522[0];
    return val;
        
    }

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Никакого гадания нет. Уже давно все посмотрел. Потому и поднял тему, что не понятно каким образом аппартано в регистр DR залетает мусор и на выходе HAL-функции получаем полный бред, портящий буфер приема.

. . . .

 

0. Как выделена память под буфер и данные - проверьте "время жизни". Ведь при передаче в ф-ю вы используете адрес,

а оптимизатору-компилятору это ПОФИГ :)

1. Ваш код работает в составе проекта или "отсажен" в минимальный вид для отладки.

(в смысле нет ли "сторонних" факторов влияния)

2. Я бы разобрался почему портится приемный буфер.

Заполните буфер паттерном.

Поставть на отладчике breakpoint типа "изменение памяти". Или вообще пошагово оттрасируйте состояние этй области.

Этот путь вылавливания демона проще всего - ведь есть "устойчивый сбой", и это хорошо :)

Проверьте, ведь возможно работу ф-ии SPI сбивает вообще что-то другое, к ней не относящиеся.

3. Ну и классика - размеры стека итп.

 

ps к п.0:

Чтоб компилятор не своевольничал, я нужные переменные итд

объявляю в глоб. области, в виде

__root char flag_Alarm;
#pragma required=flag_Alarm

(IAR)

 

Изменено пользователем k155la3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вот и моя хитрость

 

Это не хитрость. Это глупость. Вы не попытались разобраться, почему не работает

первый вариант и чего в нем не хватает. А не хватает только второго чтения из

вашей MRFC, так как данные отдаются следующим после адреса байтом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это не хитрость. Это глупость. Вы не попытались разобраться, почему не работает

первый вариант и чего в нем не хватает. А не хватает только второго чтения из

вашей MRFC, так как данные отдаются следующим после адреса байтом.

 

Какого второго чтения?

Функция HAL_SPI_TransmitReceive(&hspi1, ZAPRC522, OTVRC522, 2, 20) в первом байте передает адрес вторым байтом принимает.

Чувствую, что в HAL-драйверах какая-то засада при работе с 8-битным приемом.

Или? Вы намекаете что в функции HAL_SPI_TransmitReceive надо ставить не 2 байта а 4?

Изменено пользователем serglg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сегодняшний момент вызывает вопрос код в HAL_SPI_Init()

 

  if(hspi->Init.DataSize > SPI_DATASIZE_8BIT)
  {
    frxth = SPI_RXFIFO_THRESHOLD_HF;
  }
  else
  {
    frxth = SPI_RXFIFO_THRESHOLD_QF;
    //frxth = SPI_RXFIFO_THRESHOLD_HF;   //  может надо здесь так?
  }

 

При установке 8-битного режима при инициализации SPI всегда делается frxth = SPI_RXFIFO_THRESHOLD_QF;

Хотя ручное прописывание frxth = SPI_RXFIFO_THRESHOLD_HF; не помогло...

 

 

 

Функция HAL_SPI_Receive() собственно сводится к вызову HAL_SPI_TransmitReceive().

 

В ней тоже вызывает вопрос вот это:

 

  if((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount > 1))
  {
    /* set fiforxthreshold according the reception data length: 16bit */
    CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
  }
  else
  {
    /* set fiforxthreshold according the reception data length: 8bit */
    SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
    //CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);   // может надо так?
  }

 

Хотя в stm32f0xx_hal_spi.h прописано вот это:

 

/** @defgroup SPI_FIFO_reception_threshold SPI FIFO Reception Threshold
  * @{
  * This parameter can be one of the following values:
  *     SPI_RXFIFO_THRESHOLD or SPI_RXFIFO_THRESHOLD_QF :
  *          RXNE event is generated if the FIFO
  *          level is greater or equal to 1/2(16-bits).
  *     SPI_RXFIFO_THRESHOLD_HF: RXNE event is generated if the FIFO
  *          level is greater or equal to 1/4(8 bits). */
#define SPI_RXFIFO_THRESHOLD            SPI_CR2_FRXTH
#define SPI_RXFIFO_THRESHOLD_QF         SPI_CR2_FRXTH
#define SPI_RXFIFO_THRESHOLD_HF         ((uint32_t)0x00000000)

 

 

В результате на сегодняшнее утро предварительно помогла перед вызовом HAL_SPI_Receive() пачковая вычитка DR регистра:

   dataX1=(uint16_t)hspi1.Instance->DR;
   dataX1=(uint16_t)hspi1.Instance->DR;
   dataX1=(uint16_t)hspi1.Instance->DR;
   dataX1=(uint16_t)hspi1.Instance->DR;
   HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf1[0], 1, 10000);

 

Но надо все проверить .... думаю к вечеру это дело прояснится

 

 

0. Как выделена память под буфер и данные - проверьте "время жизни". Ведь при передаче в ф-ю вы используете адрес,

а оптимизатору-компилятору это ПОФИГ :)

1. Ваш код работает в составе проекта или "отсажен" в минимальный вид для отладки.

(в смысле нет ли "сторонних" факторов влияния)

2. Я бы разобрался почему портится приемный буфер.

Заполните буфер паттерном.

Поставть на отладчике breakpoint типа "изменение памяти". Или вообще пошагово оттрасируйте состояние этй области.

Этот путь вылавливания демона проще всего - ведь есть "устойчивый сбой", и это хорошо :)

Проверьте, ведь возможно работу ф-ии SPI сбивает вообще что-то другое, к ней не относящиеся.

3. Ну и классика - размеры стека итп.

 

ps к п.0:

Чтоб компилятор не своевольничал, я нужные переменные итд

объявляю в глоб. области, в виде

__root char flag_Alarm;
#pragma required=flag_Alarm

(IAR)

 

0. Буфер объявлен как глобальные переменные. Оптимизация компилера полностью отключена.

1. Собственно это начальный проект, но весь код отрублен и из main() вызывается единственный этот тестовый процесс чтения по SPI. Ничего лишнего нет. Все прерывания запрещены, кроме системного тика для HAL_Delay();

2. Собственно портится не сам буфер, а портится регистр DR.....ну и соответственно портится буфер

3. Стек не смотрел....но вроде ничего не делается для переполнения.

 

__root char flag_Alarm - эта штука для меня новинка, так как STM32 занимаюсь только около месяца....почитаю, разберусь и попробую применить...

 

 

Чувствую, что в HAL-драйверах какая-то засада при работе с 8-битным приемом.

У меня вот тоже ОЧЕНЬ-ОЧЕНЬ похожие чувства.....сильно похоже на засаду....еще в коде полностью не разобрался, но есть большое желание это все прошерстить

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(1)

HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);

data1 = localRxBuf[0];

HAL_SPI_Receive(&hspi1, (uint8_t*)&localRxBuf[0], 1, 10000);

data2 = localRxBuf[0];

(2)

. . . .

 

Позволю себе.

Если после точки (1) Вы не упоминаете, и не используете явно массив localRxBuf, т.е.

(2)
localRxBuf[2] =  localRxBuf[3] +  localRxBuf[4];  // обман компилятора
MyCalc( localRxBuf[2] );
.....

и тожесамое по data123, то даже при полностью отключенной оптимизации считайте, что массива в (1) уже нет.

Точнее, это компилятор так считает :) И память которая там была, уже занята под другие данные (или не занята). Или там стек или ....

На то, что глобальное - не расчитыайте. Разве что есть на эти данные ссылка по extern из других модулей.

И это не оптимизация :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позволю себе.

Если после точки (1) Вы не упоминаете, и не используете явно массив localRxBuf, т.е.

(2)
localRxBuf[2] =  localRxBuf[3] +  localRxBuf[4];  // обман компилятора
MyCalc( localRxBuf[2] );
.....

и тожесамое по data123, то даже при полностью отключенной оптимизации считайте, что массива в (1) уже нет.

Точнее, это компилятор так считает :) И память которая там была, уже занята под другие данные (или не занята). Или там стек или ....

На то, что глобальное - не расчитыайте. Разве что есть на эти данные ссылка по extern из других модулей.

И это не оптимизация :)

 

вы считаете что глобальный массив localRxBuf[] несмотря на то что он используетя в HAL_Recive() и далее

data1=localRxBuf[0] самопроизвольно исчезает????????????????????????????????????????????????????????????????????????????????????????????????????

:w00t: :excl: :w00t: :excl: :w00t: :excl: :w00t: :excl::w00t: :excl::w00t:

Изменено пользователем Pasa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вы считаете что глобальный массив localRxBuf[] несмотря на то что он используетя в HAL_Recive() и далее

data1=localRxBuf[0] самопроизвольно исчезает????????????????????????????????????????????????????????????????????????????????????????????????????

:w00t: :excl: :w00t: :excl: :w00t: :excl: :w00t: :excl::w00t: :excl::w00t:

Если вы после приведенного фрагмента кода не используете явно data1,2,3.

- data1 после (2) не упоминается - так зачем он нужен ?

- элемент массива записывается в неупоминаемый data1 - так зачем он (массив) нужен ?

А то что вы в ф-ию передали &Var, и что этот адрес принадлежит именно Var - компилятор "не знает".

-------

В общем мои "смутные сомненья" Вы поняли. Это IMHO.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Позволю себе.

Если после точки (1) Вы не упоминаете, и не используете явно массив localRxBuf, т.е.

(2)
localRxBuf[2] =  localRxBuf[3] +  localRxBuf[4];  // обман компилятора
MyCalc( localRxBuf[2] );
.....

и тожесамое по data123, то даже при полностью отключенной оптимизации считайте, что массива в (1) уже нет.

Точнее, это компилятор так считает :) И память которая там была, уже занята под другие данные (или не занята). Или там стек или ....

На то, что глобальное - не расчитыайте. Разве что есть на эти данные ссылка по extern из других модулей.

И это не оптимизация :)

Так. Ещё раз, медленно и по буквам.

 

Упрощаю до предела. Пишем

void DoIt (char * p)
{
   for (int i = 0; i < 5; i++)
       p[i] = i;
}

....
char data[10];
DoIt (data);
// data больше не используем

 

Вы утверждаете, что DoIt() будет записывать не в data[], а портить стек?

Как интересно...

(да, я в курсе, что особо умный компилятор не будет делать НИЧЕГО - выкинет и массив, и функцию заполнения. Но изначальный этот HAL_SPI_Receive() выкинуть так просто нельзя - у него внутри volatile много).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы намекаете?

Нет, не намекаю, я привел рабочий код. Нормальное чтение из SPI у меня получилось только

после инициализации бита FRXTH при каждой передаче. Т.е. если длина передаваемых

данных больше 1 сбрасываем бит и передаем в 16-разрядном режиме, если длина передаваемых

данных равна 1 - устанавливаем бит FRXTH и передаем в 8 разрядном режиме. При этом

SPI настроен на SPI_DataSize_8b.

 

Все другие варианты, также как у вас, давали непредсказуемый результат, т.е. то правильно,

то нет.

 

Надо бы еще попробовать инициализировать сначала CR2, затем CR1, как здесь отмечали,

может даст результат, хотя такого упоминания я нигде не нашел. И в SPL и в HAL(какой ужас,

специально сейчас вот посмотрел) сначала инициализируется CR1, затем CR2.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...