|
|
  |
STM32 HAL SPI ошибка или глюки IAR,, ошибка чтения SPI с помощью HAL от CubeMX |
|
|
|
Jul 28 2016, 19:48
|
Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665

|
Обмен идет с CC2500 Цитата(k155la3 @ Jul 28 2016, 09:39)  Про осцилограф. Проверьте соответствие настроек полярности-фазы SPI и их соответствие девайсу с которым работаете. Проверял в самом начале проекта. Осцллограммы идеальные - и STM32 и СС2500 выдают правильные картинки. Цитата(k155la3 @ Jul 28 2016, 16:15)  "при добавлении третьего чтения портятся 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]; все равно прием неправильный... Цитата(x893 @ Jul 28 2016, 19:44)  Ничего хитрого 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 - Jul 28 2016, 23:45
|
|
|
|
|
Jul 28 2016, 20:08
|
Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665

|
Цитата(x893 @ Jul 28 2016, 17:47)  Функция 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; Цитата(x893 @ Jul 28 2016, 23:19)  Проверил с 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 - Jul 28 2016, 20:28
|
|
|
|
|
Jul 29 2016, 03:11
|
Частый гость
 
Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355

|
Цитата(x893 @ Jul 28 2016, 21:14)  Ничего хитрого Хитрость для меня была в том, что CR2->FRXTH пришлось инициализировать при каждой записи-чтении. Цитата(x893 @ Jul 28 2016, 21:14)  сначала ставим CR2 а потом CR1 Может быть винт от хитрости как раз в этом. Надо будет проверить.
|
|
|
|
|
Jul 29 2016, 06:12
|
Частый гость
 
Группа: Участник
Сообщений: 146
Регистрация: 19-07-16
Пользователь №: 92 603

|
Ну вот и моя хитрость. Чтение делаю 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 - Jul 29 2016, 07:39
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!!
|
|
|
|
|
Jul 29 2016, 06:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Pasa @ Jul 28 2016, 23:08)  Никакого гадания нет. Уже давно все посмотрел. Потому и поднял тему, что не понятно каким образом аппартано в регистр DR залетает мусор и на выходе HAL-функции получаем полный бред, портящий буфер приема. . . . . 0. Как выделена память под буфер и данные - проверьте "время жизни". Ведь при передаче в ф-ю вы используете адрес, а оптимизатору-компилятору это ПОФИГ  1. Ваш код работает в составе проекта или "отсажен" в минимальный вид для отладки. (в смысле нет ли "сторонних" факторов влияния) 2. Я бы разобрался почему портится приемный буфер. Заполните буфер паттерном. Поставть на отладчике breakpoint типа "изменение памяти". Или вообще пошагово оттрасируйте состояние этй области. Этот путь вылавливания демона проще всего - ведь есть "устойчивый сбой", и это хорошо  Проверьте, ведь возможно работу ф-ии SPI сбивает вообще что-то другое, к ней не относящиеся. 3. Ну и классика - размеры стека итп. ps к п.0: Чтоб компилятор не своевольничал, я нужные переменные итд объявляю в глоб. области, в виде Код __root char flag_Alarm; #pragma required=flag_Alarm (IAR)
Сообщение отредактировал k155la3 - Jul 29 2016, 06:53
|
|
|
|
|
Jul 29 2016, 07:30
|
Частый гость
 
Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355

|
Цитата(serglg @ Jul 29 2016, 11:12)  Ну вот и моя хитрость Это не хитрость. Это глупость. Вы не попытались разобраться, почему не работает первый вариант и чего в нем не хватает. А не хватает только второго чтения из вашей MRFC, так как данные отдаются следующим после адреса байтом.
|
|
|
|
|
Jul 29 2016, 08:36
|
Частый гость
 
Группа: Участник
Сообщений: 146
Регистрация: 19-07-16
Пользователь №: 92 603

|
Цитата(alag57 @ Jul 29 2016, 13:30)  Это не хитрость. Это глупость. Вы не попытались разобраться, почему не работает первый вариант и чего в нем не хватает. А не хватает только второго чтения из вашей MRFC, так как данные отдаются следующим после адреса байтом. Какого второго чтения? Функция HAL_SPI_TransmitReceive(&hspi1, ZAPRC522, OTVRC522, 2, 20) в первом байте передает адрес вторым байтом принимает. Чувствую, что в HAL-драйверах какая-то засада при работе с 8-битным приемом. Или? Вы намекаете что в функции HAL_SPI_TransmitReceive надо ставить не 2 байта а 4?
Сообщение отредактировал serglg - Jul 29 2016, 08:40
|
|
|
|
|
Jul 29 2016, 09:04
|
Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665

|
На сегодняшний момент вызывает вопрос код в 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); Но надо все проверить .... думаю к вечеру это дело прояснится Цитата(k155la3 @ Jul 29 2016, 10:17)  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 занимаюсь только около месяца....почитаю, разберусь и попробую применить... Цитата(serglg @ Jul 29 2016, 12:06)  Чувствую, что в HAL-драйверах какая-то засада при работе с 8-битным приемом. У меня вот тоже ОЧЕНЬ-ОЧЕНЬ похожие чувства.....сильно похоже на засаду....еще в коде полностью не разобрался, но есть большое желание это все прошерстить
|
|
|
|
|
Jul 29 2016, 10:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Pasa @ Jul 27 2016, 13:20)  (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 из других модулей. И это не оптимизация
|
|
|
|
|
Jul 29 2016, 10:55
|
Частый гость
 
Группа: Свой
Сообщений: 107
Регистрация: 4-03-09
Из: Беларусь, Минск
Пользователь №: 45 665

|
Цитата(k155la3 @ Jul 29 2016, 13:33)  Позволю себе. Если после точки (1) Вы не упоминаете, и не используете явно массив localRxBuf, т.е. Код (2) localRxBuf[2] = localRxBuf[3] + localRxBuf[4]; // обман компилятора MyCalc( localRxBuf[2] ); ..... и тожесамое по data123, то даже при полностью отключенной оптимизации считайте, что массива в (1) уже нет.Точнее, это компилятор так считает  И память которая там была, уже занята под другие данные (или не занята). Или там стек или .... На то, что глобальное - не расчитыайте. Разве что есть на эти данные ссылка по extern из других модулей. И это не оптимизация  вы считаете что глобальный массив localRxBuf[] несмотря на то что он используетя в HAL_Recive() и далее data1=localRxBuf[0] самопроизвольно исчезает????????????????????????????????????????????????????????????????????????????????????????????????????  
Сообщение отредактировал Pasa - Jul 29 2016, 10:58
|
|
|
|
|
Jul 29 2016, 12:12
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Pasa @ Jul 29 2016, 13:55)  Если вы после приведенного фрагмента кода не используете явно data1,2,3. - data1 после (2) не упоминается - так зачем он нужен ? - элемент массива записывается в неупоминаемый data1 - так зачем он (массив) нужен ? А то что вы в ф-ию передали &Var, и что этот адрес принадлежит именно Var - компилятор "не знает". ------- В общем мои "смутные сомненья" Вы поняли. Это IMHO.
|
|
|
|
|
Jul 29 2016, 13:22
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(k155la3 @ Jul 29 2016, 13:03)  Позволю себе. Если после точки (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 много).
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Jul 29 2016, 13:33
|
Частый гость
 
Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355

|
Цитата(serglg @ Jul 29 2016, 13:36)  Вы намекаете? Нет, не намекаю, я привел рабочий код. Нормальное чтение из SPI у меня получилось только после инициализации бита FRXTH при каждой передаче. Т.е. если длина передаваемых данных больше 1 сбрасываем бит и передаем в 16-разрядном режиме, если длина передаваемых данных равна 1 - устанавливаем бит FRXTH и передаем в 8 разрядном режиме. При этом SPI настроен на SPI_DataSize_8b. Все другие варианты, также как у вас, давали непредсказуемый результат, т.е. то правильно, то нет. Надо бы еще попробовать инициализировать сначала CR2, затем CR1, как здесь отмечали, может даст результат, хотя такого упоминания я нигде не нашел. И в SPL и в HAL(какой ужас, специально сейчас вот посмотрел) сначала инициализируется CR1, затем CR2.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|