MasterElectric Опубликовано 7 июня, 2019 Поделиться Опубликовано 7 июня, 2019 (изменено) 8 часов назад, john2103 сказал: В том то и дело! Много статей, где идет передача 8бит и ожиданием флагов или 16 бит и флаги. Я сам по экспериментировал и сделал переключение с 8 га 16 и обратно. Так же примеры с прерыванием и 8бит или прерывание и 16 бит. А потом я попытался сделать переключение с прерыванием, но чет есть проблемы. Видимо,чет я не совсем понимаю в логике работы модуля. Хотя в циклах все ок.(И я думал, что я разобрался) Причем просто функция передачи по прерываниям работает отлично, если без смены битности. Но битность то я меняю когда модуль не работает ? не могу понять..( Боже что за бред... Посмотрите вначале NarodSream у него как раз последние темы про SPI в 103C8. В уроках он все грамотно рассказывает, вначале посмотрите видео, поучитесь. И если ты так будешь писать на CMSIS, то мой тебе совет используй HAL. Изменено 7 июня, 2019 пользователем MasterElectric 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 7 июня, 2019 Автор Поделиться Опубликовано 7 июня, 2019 25 минут назад, MasterElectric сказал: Потому-то нужно читать RM, а не в разных местах... Когда используешь перывния и так идет непрерывная передача, хоть по 8, хоть по 16 (кроме особых случаев) Немного офтоп. Конечно Ваш ответ, просто лучший! Хоть кто то помог! Какие прерывания? dma? по завершению приема? передачи ? что значит непрерывная? Просто включил прерывание и все само волшебным образом передается? Если вы хотели помочь, то информативность Вашего сообщения 0! Если поиздеваться, то зачем, я не говорю что я ас! И я читал RF, но мне тяжело, темболее на английском, вот и смотрел попутный материал, где был 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
MasterElectric Опубликовано 7 июня, 2019 Поделиться Опубликовано 7 июня, 2019 (изменено) @john2103 Ок, тогда вопрос зачем переключать с 8 на 16 какая цель? @john2103Я ж и пишу посмотри NarodSream, последние уроки, там поток данных от мастера непрерывный, так как тебе и нужно реализовать. Говорят он сансей по МК в русском сегменте ютуба уроков уже больше сотни. Изменено 7 июня, 2019 пользователем MasterElectric 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
john2103 Опубликовано 7 июня, 2019 Автор Поделиться Опубликовано 7 июня, 2019 2 минуты назад, MasterElectric сказал: @john2103 Ок, тогда вопрос зачем переключать с 8 на 16 какая цель? в самом начале топика озвучил! Изучаю! Можно так сделать или нет? Судя по всему прочитанному, это можно сделать, по факту не получилось! Стало просто интересно, этого вообще сделать нельзя или я что то не то делаю. Если есть опыт подскажите, буду очень благодарен. На практике я бы нашел рабочее решение, более простое, но тут чисто интерес, можно или нет 9 минут назад, MasterElectric сказал: @john2103 Ок, тогда вопрос зачем переключать с 8 на 16 какая цель? @john2103Я ж и пишу посмотри NarodSream, последние уроки, там поток данных от мастера непрерывный, так как тебе и нужно реализовать. Говорят он сансей по МК в русском сегменте ютуба уроков уже больше сотни. Его уроки, я все давно пересмотрел и не по одному разу, но если ты заметил, он использует hal и ll. А я говорю про cmsis. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 7 июня, 2019 Поделиться Опубликовано 7 июня, 2019 для того чтобы использовать прерывания в SPI нужно чтобы объем данных был существенным, а передавать 4 байта прерываниями нет смысла. А если передаем буфер зачем переключать битность? поток и так непрырывный при использовании прерываний. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 7 июня, 2019 Автор Поделиться Опубликовано 7 июня, 2019 28 минут назад, MasterElectric сказал: И если ты так будешь писать на CMSIS, то мой тебе совет используй HAL. В чем проблема с моим cmsis, что я делаю не так? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 7 июня, 2019 Поделиться Опубликовано 7 июня, 2019 (изменено) @john2103 В этом: SPI1->CR1 |= SPI_CR1_BIDIMODE; // --- BIDIMODE режим работы (1 - одна линия, 0 - две линии связи) SPI1->CR1 |= SPI_CR1_BIDIOE; // --- BIDIOE Этот бит в сочетании с битом BIDImode выбирает направление передачи в двунаправленном режиме // --- 0: Output disabled (receive-only mode) // --- 1: Output enabled (transmit-only mode) SPI1->CR1 &=~SPI_CR1_CRCEN; // --- Аппаратный расчет CRC включить // --- 0: расчет CRC отключен // --- 1: Расчет CRC включен SPI1->CR1 &= ~SPI_CR1_CRCNEXT; // --- Следующая передача данных будет завершаться CRC-кодом. // --- 0: Этап передачи данных // --- 1: Следующая передача завершится передачей RCR SPI1->CR1 &= ~SPI_CR1_DFF; // --- Формат кадра данных // --- 0: Размер кадра передачи 8 бит // --- 1: Размер кадра передачи 16 бит SPI1->CR1 &= ~SPI_CR1_RXONLY; // --- Этот бит совместно с BIDIMODE выбирает направление передачи в 2-х проводном (MISO и MISO) режиме. // --- 0: Full duplex — передача и прием // --- 1: Output disabled — только прием SPI1->CR1 |= SPI_CR1_SSM; // --- Программное управление ведомым устройством. Когда бит SSM установлен, сигнал NSS заменяется значением бита SSI. // --- 0: Программное управление ведомым отключено // --- 1: Программное управление ведомым включено SPI1->CR1 |= SPI_CR1_SSI; // --- Внутренний выбор ведомого. Этот бит работает только когда бит SSM установлен. Значение этого бита принудительно подается на NSS, а значение IO вывода NSS игнорируется. // --- 1: (Master) Заменяет значение на выводе NSS // --- 0; (Slave) SPI1->CR1 &= ~SPI_CR1_LSBFIRST;// --- Формат кадра // --- 0: MSB передается первым // --- 1: LSB передается первым SPI1->CR1 |= SPI_CR1_BR; // --- BR[2:0]: Выбор скорости передачи // 000: fPCLK/2 // 001: fPCLK/4 // 010: fPCLK/8 // 011: fPCLK/16 // 100: fPCLK/32 // 101: fPCLK/64 // 110: fPCLK/128 // 111: fPCLK/256 //#define SPI_CR1_BR_Pos (3U) //#define SPI_CR1_BR_Msk (0x7U << SPI_CR1_BR_Pos) /*!< 0x00000038 */ //#define SPI_CR1_BR SPI_CR1_BR_Msk /*!< BR[2:0] bits (Baud Rate Control) */ //#define SPI_CR1_BR_0 (0x1U << SPI_CR1_BR_Pos) /*!< 0x00000008 */ //#define SPI_CR1_BR_1 (0x2U << SPI_CR1_BR_Pos) /*!< 0x00000010 */ //#define SPI_CR1_BR_2 (0x4U << SPI_CR1_BR_Pos) /*!< 0x00000020 */ SPI1->CR1 |= SPI_CR1_MSTR; // --- Выбор режима работы SPI: Master/Slave // --- 0: Режим Slave (ведомый) // --- 1: Режим Master (ведущий) SPI1->CR1 &= ~SPI_CR1_CPOL; // --- Полярность тактового сигнала // --- 0: CK в 0 при простое // --- 1: CK в 1 при простое SPI1->CR1 &= ~SPI_CR1_CPHA; // --- Фаза тактового сигнала я такое вижу впервые... @MasterElectric Смотри как бы сделал я. Выдели ногу для тестового сигнала и момент когда ты переключаешь битность дерни ногой и посмотри потом что покажет ЛА. Изменено 7 июня, 2019 пользователем MasterElectric 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 7 июня, 2019 Автор Поделиться Опубликовано 7 июня, 2019 Только что, MasterElectric сказал: для того чтобы использовать прерывания в SPI нужно чтобы объем данных был существенным, а передавать 4 байта прерываниями нет смысла. А если передаем буфер зачем переключать битность? поток и так непрырывный при использовании прерываний. А если я сейчас для примера возьму и изменю объем массива на 300 элементов 1000 или еще больше??? Это что изменить? У вас появиться решение? Я понял, на счет битности и согласен, что битф все равно идут подрят, ну предположим, вот задачу поставили именно так, реализовать именно смену битности! Вы можете, что подсказать конкретное по этому поводу? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 7 июня, 2019 Поделиться Опубликовано 7 июня, 2019 @john2103 Если есть время попробуй то что я предложил и покажите что там будет решение я вам дам. Сам занимаюсь SPI только на L0 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 7 июня, 2019 Автор Поделиться Опубликовано 7 июня, 2019 (изменено) 10 минут назад, MasterElectric сказал: я такое вижу впервые... Развернутые коментарии??? Так это я для себя, что бы запомнить какие регистры, какие биты, как называются, для чего служат! 10 минут назад, MasterElectric сказал: @MasterElectric Смотри как бы сделал я. Выдели ногу для тестового сигнала и момент когда ты переключаешь битность дерни ногой и посмотри потом что покажет ЛА. А за этот совет, спасибо, обязательно попробую! Изменено 7 июня, 2019 пользователем john2103 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 8 июня, 2019 Поделиться Опубликовано 8 июня, 2019 @john2103 В RM четко написано нельзя менять бит DFF при работаеющем модуле (SPE = 1). 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 10 июня, 2019 Автор Поделиться Опубликовано 10 июня, 2019 Доброго времени суток, товарищи! Для тех, кому все же интересно! Наконец добрался до компа и провел тесты. Можно сказать выяснил в чем проблема... (но все же это условно). По совету @MasterElectric добавил несколько контрольных пинов и с помощью ЛА отслеживал изменения. Весь перечень того что делал не привожу, нет смысла, самое интересно: #define A0_true GPIOA->BSRR |= GPIO_BSRR_BS0 #define A0_false GPIOA->BSRR |= GPIO_BSRR_BR0 #define A1_true GPIOA->BSRR |= GPIO_BSRR_BS1 #define A1_false GPIOA->BSRR |= GPIO_BSRR_BR1 #define A2_true GPIOA->BSRR |= GPIO_BSRR_BS2 #define A2_false GPIOA->BSRR |= GPIO_BSRR_BR2 #define A3_true GPIOA->BSRR |= GPIO_BSRR_BS3 #define A3_false GPIOA->BSRR |= GPIO_BSRR_BR3 #define A4_true GPIOA->BSRR |= GPIO_BSRR_BS4 #define A4_false GPIOA->BSRR |= GPIO_BSRR_BR4 ......... void SPI1_STM32F1_write_8bit_irq(uint8_t *data, int32_t len_8bit) { A1_true; if(len_8bit<=0) return; A4_true; while(SPI1->SR & SPI_SR_BSY) ; A4_false; A3_true; SPI1->CR1 &= ~SPI_CR1_SPE; A0_true; SPI1->CR1 &= ~SPI_CR1_DFF; A0_false; SPI1->CR1 |= SPI_CR1_SPE; A3_false; flag =0; tx_index_8_bit = 0; tx_len_8_bit = len_8bit; tx_data_8_bit = data; SPI1->CR2 |= SPI_CR2_TXEIE; A1_false; } void SPI1_STM32F1_write_16bit_irq(uint16_t *data, int32_t len_16bit) { A2_true; if(len_16bit<=0) return; A4_true; while(SPI1->SR & SPI_SR_BSY) ; A4_false; A3_true; SPI1->CR1 &= ~SPI_CR1_SPE; A0_true; SPI1->CR1 |= SPI_CR1_DFF; A0_false; SPI1->CR1 |= SPI_CR1_SPE; A3_false; flag =1; tx_index_16_bit = 0; tx_len_16_bit = len_16bit; tx_data_16_bit = data; SPI1->CR2 |= SPI_CR2_TXEIE; A2_false; } A1_true / A1_false - Начало / конец Передачи 8 бит A2_true / A2_false - Начало / конец Передача 16 бит A4_true / A4_false - Ожидание флага BSY A3_true / A3_false - Откл SPE =0, Вкл SPE = 1 A0_true / A0_false - Включение (или отключение ) бита DFF При том коде, что записан выше, интересны флаги A4_false, A0_false и A3_false, относительно последнего CLOCKа! Видно что BSY срабатывает, когда реально еще идет "крайний CLOCK", происходит смена бита DFF(еще время уходит на переключение флага A3_true) и заканчивается раньше чем крайний КЛОК, но при этом включение SPE = 1 происходит после него. (А1 - А2 А самое главное более 0,25 мкс после "крайнего клока") и код работает как надо, никаких лишних передач! Если убрать флаги переключения DFF, но при этом оставить включение и отключение SPI (SPE = 0, SPE = 1), то получим: .... A3_true; SPI1->CR1 &= ~SPI_CR1_SPE; // A0_true; SPI1->CR1 &= ~SPI_CR1_DFF; // A0_false; SPI1->CR1 |= SPI_CR1_SPE; A3_false; ..... A3_true; SPI1->CR1 &= ~SPI_CR1_SPE; // A0_true; SPI1->CR1 |= SPI_CR1_DFF; // A0_false; SPI1->CR1 |= SPI_CR1_SPE; A3_false; ..... Несмотря на смену DFF при отключенном модуле (SPE = 0), время выполнения откл SPI смены DFF и вкл SPI меньше чем выполнение крайнего клока. (Есть ненужная передача 0x00) Предыдущий код работал потому что переключение флагов, вносило своего рода задержки. Когда я убрал эти переключения, время на выполнение всех операций сократилось и стало меньше чем окончание передачи. Поэтому и пошли ошибки. После этого я закоментил строки: //A3_true; //SPI1->CR1 &= ~SPI_CR1_SPE; .... //SPI1->CR1 |= SPI_CR1_SPE; //A3_false; Видно, что бит DFF меняется во время крайнего КЛОКА, отключение SPI вообще не происходит, есть лишний бит 0x00. После этого я просто добавил несколько __NOP(); перед сменой DFF. (Экспериментально, я нашел), что бы пропала лишня передача 0х00 и код стал правильно работать, смена DFF должна заканчиваться через ~0,25 мкс после крайнего клока, что бы все правильно работало (При том что сам модуль я не отключаю SPE =1 и я его не трогаю) void SPI1_STM32F1_write_8bit_irq(uint8_t *data, int32_t len_8bit) { A1_true; if(len_8bit<=0) return; A4_true; while(SPI1->SR & SPI_SR_BSY) ; A4_false; __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); ..... ..... __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // A3_true; //SPI1->CR1 &= ~SPI_CR1_SPE; // A0_true; SPI1->CR1 &= ~SPI_CR1_DFF; A0_false; //SPI1->CR1 |= SPI_CR1_SPE; // A3_false; flag =0; tx_index_8_bit = 0; tx_len_8_bit = len_8bit; tx_data_8_bit = data; SPI1->CR2 |= SPI_CR2_TXEIE; A1_false; } Как видно, все работает правильно, никаких лишних передач нет, все работает как надо. При этом сам модуль я не отключал (SPE =1 и я его не трогал). ИТОГИ: На самом деле было много экспериментов, я рассказал об основном. Сделать вывод можно такой.... Битность "на лету" менять можно, но смена должна заканчиваться не раньше, чем ~0,25мкс после крайнего тика(всего массива!!!!)! И даже если битность менять, только во время отключения модуля, то включать его тоже нельзя раньше чем ~0,25 мкс после крайнего тика, иначе (чисто моя теория) модуль думает, что до этого он передавал 16 битные данные, 8 передал и надо еще 8. Отсюда и появлялись "лишние" передачи. Вот такая особенность. Это все было про кварц 8 Мгц, частота ядра 72 Мгц, частота SPI /256 Надеюсь это кому то пригодиться =) @MasterElectric Спасибо за совет! 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 10 июня, 2019 Поделиться Опубликовано 10 июня, 2019 Ок тогда дам еще один в BSRR можно просто писать он только для записи. Но я таки смысла так и не понял с этим DFF. Некоторые процессы в модулях происходят на тактовой частоте передачи данных, Например USART передает данные с задержкой в байт после разрешения передатчика лично с этим столкнулся. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
ruhi Опубликовано 11 июня, 2019 Поделиться Опубликовано 11 июня, 2019 В 10.06.2019 в 03:09, john2103 сказал: Битность "на лету" менять можно, но смена должна заканчиваться не раньше, чем ~0,25мкс после крайнего тика Может не заканчиваться, а начинаться смена битности должна не раньше чем? Так этот период зависит от частоты СПИ-ая? Какая все таки частота СПИ-ая: что /256? 8МГц? тогда один такт СПИ значит = 8000/256 => 32 мксек - и получается 0,25мкс больше чем в десять раз меньше чем длительность бита на СПИ-ай? 0 Можно сделать все! Но чем больше можно, тем больше нельзя! Ссылка на комментарий Поделиться на другие сайты Поделиться
john2103 Опубликовано 13 июня, 2019 Автор Поделиться Опубликовано 13 июня, 2019 (изменено) В 10.06.2019 в 20:59, MasterElectric сказал: Ок тогда дам еще один в BSRR можно просто писать он только для записи. Я знаю, это просто что бы выработать привычку установки нужного бит. А то потом пропускаю в нужных местах. В 10.06.2019 в 20:59, MasterElectric сказал: Например USART передает данные с задержкой в байт после разрешения передатчика Опять же, буду знать, когда буду с ним разбираться! Спасибо! Что касается DFF Нас интересует последний клок передачи 8 битного массива: Его длительность На следующим скрине, импульс изменения DFF флага: Функция передачи при этом имеет вид: void SPI1_STM32F1_write_16bit_irq(uint16_t *data, int32_t len_16bit) { if(len_16bit<=0) return; while(SPI1->SR & SPI_SR_BSY) ; A3_true; SPI1->CR1 |= SPI_CR1_DFF; A3_false; flag =1; tx_index_16_bit = 0; tx_len_16_bit = len_16bit; tx_data_16_bit = data; SPI1->CR2 |= SPI_CR2_TXEIE; } Как видно изменение бита DFF произошло, раньше чем закончился крайний клок. Это произошло потому, что выбранная мной скорость работы SPI модуля ( SPI1->CR1 |= SPI_CR1_BR// --- BR[2:0]: Выбор скорости передачи // 000: fPCLK/2 // 001: fPCLK/4 // 010: fPCLK/8 // 011: fPCLK/16 // 100: fPCLK/32 // 101: fPCLK/64 // 110: fPCLK/128 // 111: fPCLK/256 на много меньше, чем скорость работы ядра контроллера.Флаг BSY опускается в 0 раньше, чем SCK опускает линию на крайнем импульсе и программа успевает выполнить смену DFF за это время. Как это видно на рис 3 Длительность этого импульса (3 рисунок) намного меньше чем длительность клока (2 рисунок) 0.5 мкС. Если в функцию передачи добавить включение и отключение SPI (SPE = 0 ... SPE = 1) перед и после DFF соответственно, функция будет иметь вид: void SPI1_STM32F1_write_16bit_irq(uint16_t *data, int32_t len_16bit) { if(len_16bit<=0) return; while(SPI1->SR & SPI_SR_BSY) ; A3_true; SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR1 |= SPI_CR1_DFF; SPI1->CR1 |= SPI_CR1_SPE; A3_false; flag =1; tx_index_16_bit = 0; tx_len_16_bit = len_16bit; tx_data_16_bit = data; SPI1->CR2 |= SPI_CR2_TXEIE; } На рис 4, видно что длительность увеличилась, но все еще меньше чем конец SCK Поэтому, все равно есть лишняя передача. Как только длительность этого импульса выходит за пределы крайнего клока минимум на больше чем 0,25 мкС, все начинает работать правильно. Как я понял, что бы все работало правильно, изменение DFF не должно начинаться и заканчиваться пока идет клок сигнал (И как видно вкл и откл модуля на это не влияет) На рисунке 5 показано, когда модуль начинает правильно работать: Как видно пропала лишняя передача. В 11.06.2019 в 10:39, ruhi сказал: тогда один такт СПИ значит = 8000/256 => 32 мксек - и получается 0,25мкс больше чем в десять раз меньше чем длительность бита на СПИ-ай? Не понял вопроса ? В 11.06.2019 в 10:39, ruhi сказал: Какая все таки частота СПИ-ая: что /256? 8МГц? 8Мгц - это внешний кварц который установлен на отладочной плате. 72 Мгц - это частота с которой работает контроллер (с 8 Мгц частота через PLL увеличивается до 72 Мгц) /256 - это предделитель выставленный для SPI Частота работы SPI 281.25 Кбит/с Изменено 13 июня, 2019 пользователем john2103 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterElectric Опубликовано 13 июня, 2019 Поделиться Опубликовано 13 июня, 2019 Мне тоже стало интересно будет время проверю. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
ruhi Опубликовано 14 июня, 2019 Поделиться Опубликовано 14 июня, 2019 18 часов назад, john2103 сказал: Не понял вопроса ? ну да, как то я коряво сформулировал, но вы все ответили! Вот такую работу с осцилографом я очень люблю и уважаю! 0 Можно сделать все! Но чем больше можно, тем больше нельзя! Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.