Страница 1 из 1

Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 16:25:08
kotarnold
Работаю с одним портом, причем один его вывод использую, как логический вход, второй - как логический выход. Суть - по нажатию на кнопку, соединенную с портом РВ2 должен загораться светодиод, соединенный с портом РВ3.

Схема:
Изображение

Код:

Код: Выделить всё

int main(void)
{
	DDRB &= ~(0<<PB2)|(1<<PB3); // РВ2 на вход, PB3 на выход 
	PORTB |= (1<<PB2)|(0<<PB3); // Логическое состояние порта В на старте
	
	while(1)
	{
		if (PORTB = (0<<PB2))
			{
				PORTB |= (1 << PB3);
			}
	}
}
В чем может быть ошибка?

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 16:38:04
Ivanoff-iv
вход это PINB

Добавлено after 2 minutes 15 seconds:
и условие сделано неправильно - надо маску использовать: if (PINB&(1<<3))

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 16:49:34
kotarnold
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3372692#p3372692"]вход это PINB

Добавлено after 2 minutes 15 seconds:
и условие сделано неправильно - надо маску использовать: if (PINB&(1<<3))[/uquote]

Странно, потому что

Код: Выделить всё

{
		if (PINB&(0<<PB2))
			{
				PORTB |= (1 << PB3);
			}
	}
также не работает.
ЗЫ: а где можно прочитать про смысл "==", "|=", "~" и "&"?

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 17:10:01
Dimon456
Спойлер

Код: Выделить всё

   DDRB |= (0<<2)|(1<<3); // РВ2 на вход, PB3 на выход
   PORTB |= (1<<2)|(0<<3); // Логическое состояние порта В на старте
   
   while(1)
   {
      if (!(PINB&(1<<2)))
         {
            PORTB |= (1 << 3);
         }
   }
}

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 17:18:54
kotarnold
[uquote="Dimon456",url="/forum/viewtopic.php?p=3372726#p3372726"]
Спойлер

Код: Выделить всё

   DDRB |= (0<<2)|(1<<3); // РВ2 на вход, PB3 на выход
   PORTB |= (1<<2)|(0<<3); // Логическое состояние порта В на старте
   
   while(1)
   {
      if (!(PINB&(1<<2)))
         {
            PORTB |= (1 << 3);
         }
   }
}
[/uquote]

Благодарю!

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 17:36:42
afz
kotarnold писал(а): DDRB &= ~(0<<PB2)|(1<<PB3); // РВ2 на вход, PB3 на выход
Эта операция погасит бит 2 DDRB и оставит неизменным (то есть нулём) бит 3 DDRB, т.е. оба бита порта будут работать на ввод. Если рассчитывать, что где-то раньше могли поманипулировать другими битами DDRB и все биты, кроме 2 и 3 надо сохранить неизменными, то надо отдельно погасить бит 2 (DDRB &= 0xFB;) и отдельно взвести бит 3 (DDRB |= 0x08;). Ну, а, учитывая, что остальные биты в этой задаче не задействованы, можно, по-простому, сделать DDRB = 0x08;

Да, не стоит подключать светодиод напрямую к выходу МК - добавь последовательно с ним балластный резистор, 1 кОм будет в самый раз.

Вторая ошибка - при ненажатой кнопке PB2 висит "в воздухе", его потенциал будет определяться утечками по плате, неизвестно что там будет читаться, скорее всего, всегда ноль. Надо включить "подтяжку" к плюсу, т.е. взвести в единицу бит 2 PORTB, и не забыть оставить его в единице при манипуляции с битом 3.

Дальше, вроде-бы, уже без меня подсказали.
kotarnold писал(а):ЗЫ: а где можно прочитать про смысл "==", "|=", "~" и "&"?
Ой, как все запущено!.. Берешь учебник по простому (не приплюснутому) Си и изучаешь до полного просветления.

Re: Заблудился в двух соснах одного порта атмеги.

Добавлено: Ср май 09, 2018 20:18:34
Ivanoff-iv
по началу можешь использовать побитовое обращение к портам: DDRB.3=0; PORTB.3=1; if (PINB.3==0)
по началу - потому что не все порты так можно адресовать (вроде до порта Е), поэтому всёже правильней использовать более универсальные конструкции.