Как использовать порты вместо digitalWrite и digital Read?

cactous
Offline
Зарегистрирован: 18.11.2013

  В имеющемся на сайту туториале написано использовать порты, но как подать единичку на конкретный пин порта не понятно. Где про это почитать? 

Leshiy
Offline
Зарегистрирован: 19.07.2014

Можно посмотреть скетчи, идущие вместе со средой раработки Arduino. Раздел Digital. Или гугл Ардуино для начинающих.

leshak
Offline
Зарегистрирован: 29.09.2011

Ну почему же нет в этом туториале? есть это в Управление портами через регистры Atmega | Аппаратная платформа Arduino

Смотрите на коммент "это менее рискованно". Там направление порта выставляется дл конкретных пинов. Состояние пинов вообще-то аналогично делаются.

Что-бы легче было понять "эту магию", смотрите битовые операторы Arduino - BitwiseAnd  (русского перевода нет, можете поискать описание битовых опираторов в любом книге по C/C++).

Если покопаетесь в Arduino - Reference то возможно найдете и функции для манипулирования битами, но.... я бы рекомендовал, все-таки через операторы разобраться .

Motto
Offline
Зарегистрирован: 05.06.2014

Функции digitalWrite и digital Read занимают много процессорного времени и для работ на больших частотах не подходят.

Обратите внимание на библиотеку cyberlib.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

попробуйте так

#define Port              PORTB
#define CSn             2

...


DDRB  = (1<<CSn); //включаем на выход PortB.2


...


 PORTB = (1<<CSn); //записали 1 на нашем пине

но проще заранее все объявить

#define CS_On           PORTB = 1<<2        // CS    PB2
#define CS_Off          PORTB = 0<<2
#define DAT_On          PORTB = 1<<3        // Data  PB3
#define DAT_Off         PORTB = 0<<3
#define CLK_On          PORTB = 1<<5        // Clock PB5
#define CLK_Off         PORTB = 0<<5

 

cactous
Offline
Зарегистрирован: 18.11.2013

Я правильно понимаю соответствие входов битам порта?

два первых бита нельзя использовать.  Можно что-то испортить  меняя их состояние? Или его невозможно изменить?

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

http://www.hobbytronics.co.uk/image/data/tutorial/arduino-hardcore/atmeg...

http://www.hobbytronics.co.uk/image/data/tutorial/arduino-hardcore/atmeg...

смотрите по этим картинкам. насчет менять эти пины не пробовал честно сказать

на выход проще настраивать функцией pinmode

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

leshak
Offline
Зарегистрирован: 29.09.2011

cactous пишет:

Я правильно понимаю соответствие входов битам порта?

два первых бита нельзя использовать.  Можно что-то испортить  меняя их состояние? Или его невозможно изменить?

 

Ну, почти правильно... кварц непонятно откуда приплелся. И не очень понятно откуда вы взяли эту картику... немного не соотвестувует выводы...
Смотрите сюда (для 328 и 128) камня.
http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry  (я уже давал эту ссылку, или не?)


 

Смотрите как мы ее "читаем". Хотим мы скажем вместо digitalWrite(2,HIGH), сделать прямой вывод в порт.
Ищем на картинке "цифровой вывод 2".
Это 4-тая нога камушка.
Возлее нее подпись. PD2
Это PD2 расшифровывается: "за эту ногу. отвечает Port D, второй бит". Следовательно "напрямую", для второй ноги мы должны использовать DDRD - для установки режима, PORTD - для вывода на эту ногу. PIND - для чтения состояния этой ноги. Во всех случаях, оперируем мы именно вторым битом этих DDRD,PORTD, PIND
 

Или у D8, подписанно PB0. Значит нам нужен порт B, нулевой бит...

 

cactous
Offline
Зарегистрирован: 18.11.2013

Спасибо. Теперь наконец все понял. Все перключается. Разобрался с  & и |  , понял как менять состояние. Осталось разобраться как считывать:)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

http://arduino.ru/themes/framework/images/menu-leaf.gif);">оно же и для портов С и В :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

блииииин, чёта не так вставилось....

посмотрите назначение регистров DDRD, PORTD, PIND - оно же и для портов С и В

а считывает - PIND - оно же и для портов С и В :)

cactous
Offline
Зарегистрирован: 18.11.2013

Я это почитал и даже понял:)  Как один бит из этого байта считать?

PIND  возвращает десятичное число эквивалентное двоичному значению байта.  Каже получить состояние отдельного пина?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Каже получить состояние отдельного пина?

побитовые операции, сдвиги, маска....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

считали с порта в переменную А_3 = В01001110, например, и нужен бит 3-ий... ( биты 0.....7 )

три сдвига вправо - в переменной станет А_3 = В00001001 ( бит 3 сместился в бит 0 ), и маска для выделения 0-го бита В00000001 

А_3 = А_3 & В00000001 - в переменной останется В00000001

....можно сначала выделить бит 3 - А_3 = А_3 & В00001000 и потом 3 сдвига вправо - будет тоже самое :)

leshak
Offline
Зарегистрирован: 29.09.2011

cactous пишет:

Спасибо. Теперь наконец все понял. Все перключается. Разобрался с  & и |  , понял как менять состояние. Осталось разобраться как считывать:)

Ну так если "разобались", то вот так и считывать...

Скажем дано у нас число B0001110
Нужно узнать установлен ли у него 3-тий бит  (биты считаетются справа на лево). Значит делаем ему & с числом у которого установлен только второй бит:
B0001110 & B0000100 = ????? (что получится в итоге? что-то отличное от нуля или нет?)
вот проверяем "другое число". то же выясняем про третий бит.

B0001010 & B0000100= ?????  (что получится в итоге? что-то отличное от нуля или нет?)

Мысленно попробуйте в "проверяемом" числе поменять другие биты. Влияют они на результат?

Ну а для того, что-бы руками не выписывать "проверочное число", не считать "сколько там нулей", у нас есть "операция сдвига".
То же самое "проверочное число" B0000100 мы могли "сформировать так".
Берем B00000001  или просто 1. не важно, это одно и тоже.
И "сдвигаем" все его биты влево. Раз нам нужно проверять "второй бит", то и сдвигаем на две позиции влово (1<<2)  (число<<на сколько сдвинуть) в итоге у нас получится число B00000100

 

Pyotr
Offline
Зарегистрирован: 12.03.2014
leshak
Offline
Зарегистрирован: 29.09.2011

Pyotr пишет:

bitRead()

И смотрим его исходник:

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)

Все теже "битовые операции".
Так что, мое мнение, все-таки знать как это делать именно через "битовые", и только потом можно брать в руки bitRead()
Просто потому что... он редко используется. Только в ардуине (а частенько приходится и AVR код читать).
Да и в самое ардуине, в исходниках библиотек, примерах   конструкцию вида |=& (1<<Номер-бита) встретишь гораздо чаще чем bitSet() 

leshak
Offline
Зарегистрирован: 29.09.2011

leshak пишет:

Да и в самое ардуине, в исходниках библиотек, примерах   конструкцию вида |=& (1<<Номер-бита) встретишь гораздо чаще чем bitSet() 

Даже преувеличил чуток. Специально поискал щас в папке ардуино строку bitSet - только в документации и обнаружился.
Зато 1<< - на каждом шагу.
Практически в каждой библиотеке, в бутлоадере, в core и т.п.
Так что сами "авторы ардуино" - его тоже не сильно жалуют :)

Pyotr
Offline
Зарегистрирован: 12.03.2014

Я случайно наткнулся на эту функцию. Для начинающих, как я, использовать то можно....Мож кому пригодится...

leshak
Offline
Зарегистрирован: 29.09.2011

Pyotr пишет:

Я случайно наткнулся на эту функцию. Для начинающих, как я, использовать то можно....Мож кому пригодится...

Можно :) Только лучше после того как знаешь через битовые - пригодится :)

deftvk
Offline
Зарегистрирован: 27.05.2016

Ув. коллеги, а не подскажите смысл регистра PINx, если для получения значения бита можно считать bitRead(PORTB,i)?

Простыми словами в чем разница между bitRead(PORTB,i) и bitRead(PINB,i)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

deftvk, у порта 2 режима -порт на вход и на выход. В первом случае макрос считает состояние выхода, во втором случае -входа.

deftvk
Offline
Зарегистрирован: 27.05.2016

Правильно ли я пониманию, что в режиме INPUT, будет работать только bitRead(PINB,i) (что эквивалентно digitalRead()), а в режиме OUTPUT будет работать только bitRead(PORTB,i) - которая покажет в каком состоянии сейчас пин выхода HIGH или LOW?

b707
Offline
Зарегистрирован: 26.05.2017

tonna пишет:

Почему так,  записанное 60  не всегда(правда чаще) приводится к 0 при чтении?

а что ты ждал?

Вот твой вывод числа 60 - вторая диаграмма сверху:

Почитай где-нить, как работает analogWrite() и что такое PWM

например https://www.arduino.cc/en/Tutorial/Foundations/PWM