Программирование через регистры atmega328p

Tima123
Offline
Зарегистрирован: 29.01.2020

Здравствуйте, уважаемые форумчане!
Учусь программировать через регистры, мк atmega328p, и в одном коде нашел следующую запись:
 

DDRC |= ( 1<<PORTC1 );
DDRD &= ~( 1<<PORTD5 );

Что означает данная запись? Есть ли тут ошибка? Очень смущает, что в скобках написано "PORT". Разве там не должно быть название бита? Или двоичного/шестьнадцатеричного числа? Кому несложно, объясните, пожалуйста.

sadman41
Offline
Зарегистрирован: 19.10.2016

А вы напечатайте в Serial Monitor этот PORTD5, как число, и сразу поймете - похож он на номер бита или нет.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Tima123 пишет:
Что означает данная запись?

PC1 кофигурируется как OUTPUT, а PD5 - как INPUT.

Tima123 пишет:
Есть ли тут ошибка?

Откуда же нам знать? Ошибка - это когда код делает не то, что хотел сделать автор. А мы ведь не знаем что автор хотел сделать.

Tima123 пишет:
Очень смущает
Да, ладно! Вы гимназистка? Покраснейте ещё! Cмущает его :-)

Tima123 пишет:
Разве там не должно быть название бита? Или двоичного/шестьнадцатеричного числа?
Там должен быть номер бита. А уж в каком виде его туда запихают, это никого особо не волнует. Константы наподобие "PORTC1" - нормальные числовые константы для обозначения номеров битов.

Tima123
Offline
Зарегистрирован: 29.01.2020

Так нету Serial Monitor, код написан на Atmel Studio 7.

Tima123
Offline
Зарегистрирован: 29.01.2020

Просто насколько я понял есть три регистра для управления пинами (DDR, PORT и PIN). И если записывать PORT то только с левой стороны. Или это какой-то другой PORT? Не регистр а типа как переменная?

Tima123
Offline
Зарегистрирован: 29.01.2020

Вот например, код для мигания сведодиодом:

int main(void) {
	DDRD  |= 1<<2;
	PORTD &= ~1<<2;
	while(1) {
		PORTD |= 1<<2;
		_delay_ms(1000);
		PORTD &= ~1<<2;
		_delay_ms(1000);
	}
}

тут DDR настраивает пин D2 на выход, а PORT управляет состоянием выхода D2.

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

Tima123 пишет:

Вот например, код для мигания сведодиодом:

код мигалки можно написать вдвое короче

int main(void) {
	DDRD  |= 1<<2;
	while(1) {
		PIND = 1<<2;
		_delay_ms(1000);
		}
}

 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Tima123 пишет:

Так нету Serial Monitor, код написан на Atmel Studio 7.

Тогда еще проще. Правой кнопкой мыши щелкнуть на PORTC1 и выбрать верхний пункт "Go Implementation".

rkit
Offline
Зарегистрирован: 23.11.2016

b707 пишет:

		PIND = 1<<2;

Эка мы писать в регистры только для чтения.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Tima123 пишет:

Здравствуйте, уважаемые форумчане!
Учусь программировать через регистры, мк atmega328p, и в одном коде нашел следующую запись:
 

DDRC |= ( 1<<PORTC1 );
DDRD &= ~( 1<<PORTD5 );

Что означает данная запись? Есть ли тут ошибка? Очень смущает, что в скобках написано "PORT". Разве там не должно быть название бита? Или двоичного/шестьнадцатеричного числа? Кому несложно, объясните, пожалуйста.

я перепишу ПОЛНОСТЬЮ эквивалентно и ты, возможно, сам посмеёшься над своим вопросом:

#define hujc1    1
#define hujd5    5 

DDRC |= ( 1<<hujc1 );
DDRD &= ~( 1<<hujd5 );

Дошло? PORC1 и PORTD5 - просто константы, определенные дефайном (или другим способом), со значениями 1 и 5.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Tima123 пишет:

Вот например, код для мигания сведодиодом:

int main(void) {
	DDRD  |= 1<<2;
	PORTD &= ~1<<2;
	while(1) {
		PORTD |= 1<<2;
		_delay_ms(1000);
		PORTD &= ~1<<2;
		_delay_ms(1000);
	}
}

тут DDR настраивает пин D2 на выход, а PORT управляет состоянием выхода D2.

Ну, и?

А если я Ваш пример вот так перепишу:

#define  DVOIKA  2

int main(void) {
	DDRD  |= 1<<DVOIKA;
	PORTD &= ~1<<DVOIKA;
	while(1) {
		PORTD |= 1<<DVOIKA;
		_delay_ms(1000);
		PORTD &= ~1<<DVOIKA;
		_delay_ms(1000);
	}
}

Будет неправильно?

Там просто определены константы для каждого бита. И они НЕ ТАКИЕ ЖЕ как названия портов.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

rkit пишет:

b707 пишет:

		PIND = 1<<2;

Эка мы писать в регистры только для чтения.

ркит! Не позорься! Мне кажется, что на этом тебя уже ловили?

PINx = 1 это TOGGLE порта. В атмеге любой (я не встречал других) 8ми битной.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

rkit пишет:

b707 пишет:

		PIND = 1<<2;

Эка мы писать в регистры только для чтения.

Почему только?

Это нормальная операция инвертирования пина на многих АВР-ках (включая и 328P, и 2561, и Tiny85)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

https://static.chipdip.ru/lib/549/DOC001549488.pdf     стр 97

I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, DataDirection Register – DDRx, and the Port Input Pins – PINx. The Port Input Pins I/O location is read only,while the Data Register and the Data Direction Register are read/write. However, writing '1' to a bit in thePINx Register will result in a toggle in the corresponding bit in the Data Register. In addition, the Pull-upDisable – PUD bit in MCUCR disables the pull-up function for all pins in all ports when set.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

wdrakula пишет:
(я не встречал других)
В древних этого нет. В 8А, например.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Чёт мы с тобой одновременно одно и тоже пишем :-)

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Женя! Эко мы с тобой синхронно! ;))))

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Блин!

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

:-)

rkit
Offline
Зарегистрирован: 23.11.2016

Ну а в описании самого регистра решили написать не RW, а R.

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

Влад и Женя, быстро вы... я даж насладится торжеством не успел :)

Цитата из даташита на Атмегу328

18.2.2. Toggling the Pin
Writing a '1' to PINxn toggles the value of PORTxn, independent on the value of DDRxn. The SBI
instruction can be used to toggle one single bit in a port.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

ЕвгенийП пишет:

:-)

Лехаим! С отменой пропусков тебя!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

rkit пишет:

Ну а в описании самого регистра решили написать не RW, а R.

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

rkit
Offline
Зарегистрирован: 23.11.2016

wdrakula пишет:

 регистр только для чтения. При записи в него

Понятно

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А я не в Москве, у нас их и не было.

Захожу тут в магазин, тётка-сотрудница наезжает "Чего не в наморднике?", а у самой намордник просто за уши зацеплен, а сам ниже подбородка болтается. Ничего не ответил, улыбнулся, она мне в ответ. Вот так и прорвёмся!

Tima123
Offline
Зарегистрирован: 29.01.2020

Да и вправду смешно). Дошло), спасибо.

Tima123
Offline
Зарегистрирован: 29.01.2020

Теперь все понятно, спасибо.

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

rkit пишет:

Понятно

Ркит, так откройте даташит и прочитайте сами. Если есть претензии - обращайте их к Атмелу, а не ко мне :)

Green
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

А если я Ваш пример вот так перепишу:

#define  DVOIKA  2

int main(void) {
	DDRD  |= 1<<DVOIKA;
	PORTD &= ~1<<DVOIKA;
	while(1) {
		PORTD |= 1<<DVOIKA;
		_delay_ms(1000);
		PORTD &= ~1<<DVOIKA;
		_delay_ms(1000);
	}
}

Будет неправильно?


Правильно, но работать не будет.)

Green
Offline
Зарегистрирован: 01.10.2015

Tima123 пишет:

Так нету Serial Monitor, код написан на Atmel Studio 7.


Ну так откройте External Dependencies и посмотрите в  iom328p.h что означает ваш PORTC1 и подобные.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Green пишет:
Правильно, но работать не будет.)
С чего бы? МК взорвётся? Или тактовые часы остановятся?

Не бывает программ, которые не работают - все они что-то да делают. Эта будет делать ровно тоже самое, что программа ТС, с которой эта переписывалась.

Green
Offline
Зарегистрирован: 01.10.2015

Да, да, всё верно, работать будет). Только будет делать немножко не то что ожидает ТС.