While условие с побитовым значением и PINx считывание

Я просматривал данные ATmega32U4 для настройки SPI, и там есть фрагмент инициализации для передачи данных.

void SPI_MasterTransmit(char cData)
{
    /* Начать передачу */
    SPDR = cData;
    /* Дождитесь завершения передачи */
    while(!(SPSR & (1<<SPIF)));
}

Что я не совсем понял, так это последнюю строку фрагмента с условием while для проверки состояния бита SPIF в регистре SPSR.

Что я думаю, я понимаю, что это означает, если бит SPIF с условным значением 1, которое было бы в ALU для сравнения с фактическим состоянием бита в SPSR. Если это верно с помощью побитового оператора&, что было бы верно, если фактический бит в SPSR установлен с заданным значением (1 << SPIF).

Мои вопросы:

  1. Правильно ли я это понимаю?
  2. Что на самом деле означает эта строка?
  3. Я удалил точку с запятой в конце строки, и все в порядке! То, что я сделал, нормально?

, 👍2

Обсуждение

Я предпочитаю писать это так: "пока(!(SPSR & (1<, @Gerben

Он не будет компилироваться для меня, если я опущу последнюю точку с запятой: “_error: ожидается"; "перед ‘}’ токен_"., @Edgar Bonet

Я попробовал это с фигурными скобками, и на самом деле это не сработало. Тот, в котором на удивление работает только точка с запятой. Что для меня является новой техникой. Я также знаю, что вы можете выполнить условие if без фигурных скобок, и оно активирует только следующую строку кода. Так что эта техника в то время как с фигурными скобками или без них для меня нова. Так что да, спасибо :), @R1S8K

После некоторого тестирования с помощью кода с выводами ввода-вывода. Я обнаружил, что есть еще одна команда, которая выполняла бы то же самое, что и while (условие); это if (условие){ } и if (условие) без фигурных скобок. Итак, пока с точкой с запятой и если с фигурными скобками! Хорошо, теперь это звучит хорошо для меня :) Спасибо всем за помощь., @R1S8K


1 ответ


Лучший ответ:

3

Передача SPI начинается с записи одного байта в SPDR. И этот код не вернется из функции SPI_MasterTransmit до ее завершения. Завершение передачи объявляется установкой SPIF аппаратным обеспечением (и если включены прерывания SPI и глобальные прерывания, он также запустится ISR и очистит этот флаг).

Если вы запишете в SPDR до завершения передачи, вы повредите текущую "транзакцию", поэтому вам придется подождать, пока она не будет завершена, прежде чем начать другую запись.

Побитовое & используется для битовой маскировки. Биты в результате задаются, если оба бита в соответствующих позициях аргументов заданы:

0b00110011
         &
0b00100001
        ==
0b00100001

Поэтому, если бит в позиции SPIF не установлен, он будет повторять цикл снова, и когда он установлен, он выходит из цикла, так как существует перевернутая логика.

( SPSR     & (1<<SPIF))                    !(SPRS &(1<<SPIF))
0b0xxxxxxx & 0b10000000 == 0b00000000  =>  !0b00000000 == true
0b1xxxxxxx & 0b10000000 == 0b10000000  =>  !0b10000000 == false
,

ХОРОШО, во-первых, SPIF будет всегда установлен независимо от того, включен SPIE или нет. Итак, в этом фрагменте кода условие while находится в конце функции передачи, будет ли условие while работать одинаково независимо от того, установлен SPIE или нет? Если бы это было так, это работало бы так же, потому что это связано с битовой маской SPIF и SPSR. Если SPIE включен, то запрос на прерывание выполнит другое действие, отличное от условия while., @R1S8K

@PerchEagle Ну, если включены SPIE и глобальные прерывания, это может привести к бесконечному циклу или невыполнению ISR. Зависит от того, как выполняется ISR в аппаратном обеспечении, когда вы снимаете этот флаг перед вводом ISR (несколько тактов). Поэтому, если у вас есть передача, управляемая прерыванием, вы можете записать ее в буфер, и ISR отправит ее.., @KIIV

Итак, если мне нужно прерывание, я должен удалить строку кода while и применить другой код с включением обработки SPIE и ISR. Правильно? Таким образом, техника здесь заключается в том, что им не требуется прерывание для завершения SPI TX, поэтому они делают это только путем проверки SPIF с требованием ISR., @R1S8K

Если вам нужен SPI, управляемый прерыванием, вам понадобится буфер, размер буфера, обработчик ISR, который отправит следующий символ из буфера и уменьшит размер и, возможно, контакт CS, чтобы освободить его в конце транзакции. Первый символ должен быть отправлен в запросе на передачу (который добавляет остальные данные в буфер и устанавливает правильный размер)., @KIIV

Хорошо, я провожу тестирование с выводами ввода-вывода, все они настроены как выходы с одним выводом, а два других выводятся на максимум с помощью тестирования различных конфигураций кода while и if: Итак, 1. в то время как (условие); код >>> перемещайте контакты o/p от низкого до высокого 2. в то время как (условие){код} > > > > > > > сделайте обратное, перемещайте их от высокого до низкого 3. если (условие) {код} >>>>>>>>>>> привод от высокого к низкому 4. если (!(условие)){код} >>>>>>>>>>>>>>> двигайтесь от низкого к высокому >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> таким образом, единственные два, которые работают так, как я хочу, - это while (условие); код и если(!(условие)){код}, но я не понимаю, как они работают?!, @R1S8K

Я думаю, вам следует взглянуть на [этот учебник](http://www.add.ece.ufl.edu/4924/docs/C_Bit_Manipulation_Franklin.pdf)., @KIIV

Хорошо, спасибо :) Это хорошо, что я должен узнать больше позже в этом PDF-файле. Итак, у меня есть еще один вопрос, я не знаю, подходит ли его размещать здесь или в новой теме. Что касается возврата SPI на МИСО. Я прочитал в PDF-файле, что тот же код SPI указан в таблице данных, а именно: void SPI_TX(данные символов){ SPDR = данные; в то время как (!(SPSR & 0x80)); <<< which has to end in this arrangement, and the author of the PDF file added a last line which is return SPDR as to be read on MISO } >> как это работает? является ли это тем, что SPI автоматически получает на MISO после завершения передачи?, @R1S8K

"SPI" - это протокол "Полного дуплекса", и только "Ведущему" разрешено отправлять сигнал "Часы". Итак, если "Ведущему" нужны какие-то данные от "Ведомого", должны быть отправлены фиктивные байты., @KIIV

Извините, я забыл упомянуть, что я применяю метод обратной связи SPI для тестирования функциональности SPI. Что меня интересует, так это то, что если я применю обратную связь, то как это работает, поскольку код показывает, что автор добавил возвращаемый SPDR в конце функции TX, это действительно сработает? когда MOSI напрямую подключен к MISO той же платы? Является ли SPI на самом деле после отправки данных MISO активен для получения данных, когда вы на самом деле не настроили модуль SPI для приема данных, пока вы находитесь в главном режиме?, @R1S8K

Я имею в виду, что если бы вы были мастером, как бы вы прочитали возвращенные данные, поступающие от подчиненного, на контакт MISO мастера?, @R1S8K

Сигнал прерывания от ведомого устройства или опроса на ведущем устройстве., @KIIV

Я не понимал, как работать с SPI, поэтому я публикую еще одну тему о том, как использовать SPI для отправки данных от ведущего устройства и выполнить простое мигание на ведомом устройстве. Большое вам спасибо :), @R1S8K