Расширение портов Atmega8 с помощью 74HC165

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 4
Зарегистрирован: Вт мар 14, 2017 15:46:23

Сообщение uvers »

Здравствуйте, уважаемые коты.
Помогите пожалуйста начинающему.
Задача:
подключить к Atmega8 74HC165 для расширения портов. На выход дополнительного порта повесить светодиоды(7 шт) и заставить из загораться слева направо и гаснуть справа налево.

Прочитал что для этих целей существует интерфейс SPI(расположен на порту В), но , поскольку пины порта с 1 по 5 заняты, то решил попробовать реализовать программный SPI и управление сдвиговым регистром повесить на оставшихся 3 пина(5,6,7).
Нашел на просторах интернета подходящий код, немного подправил и вроде как заработало. Но! Не совсем как хотелось. Диоды загораются слева направо, но по очереди, а мне нужно, чтобы загорались все.
Пожалуйста, подскажите как подправить код чтобы добиться результата.

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

oid ioinit (void)
{
	DDRB = 0b11100000; //1 = output, 0 = input
	PORTB = 0b00000000;
}

void output_led_state(unsigned char __led_state)
{       int _p;
	PORTB&=~(1<<PB6);

	PORTB&=~(1<<PD5);
	
	for (_p=0;_p<8;_p++)
	{
		if(__led_state == 0x80)

		   PORTB|=(1<<PB7);
		else
		{
		   PORTB&=~(1<<PB7);
		}

		PORTB|=(1<<PB5);

		PORTB&=~(1<<PB5);
		__led_state <<= 1;
	}


	PORTB|=(1<<PB6);
}
   
Реклама
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Сообщение Пока_без_кота »

74НС165 служит для перевода параллельного кода в последовательный, а Вам нужна 74НС164 - для перевода последовательного кода в параллельный.
Реклама
Родился
Сообщения: 4
Зарегистрирован: Вт мар 14, 2017 15:46:23

Сообщение uvers »

Пока_без_кота писал(а):74НС165 служит для перевода параллельного кода в последовательный, а Вам нужна 74НС164 - для перевода последовательного кода в параллельный.
Ой! прошу прошу прощения. Не правильно указал номер сдвигового регистра. Использую 74НС595
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

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

unsigned char data[]= {0,1,3,7,15,31,63,127,63,31,15,7,3,1};
...
main()
{
for(temp= 0; temp< 14)
{
output_led_state(data[temp]);
delay_ms(сколько_надо);
}
}
В функции исправить на

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

if(__led_state & 0x80)
От себя: к чёрту 595, даёшь 164! Экономия одной лапки.
Docendo discimus
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Потрогал лапой паяльник
Сообщения: 359
Зарегистрирован: Чт авг 08, 2013 01:06:54

Сообщение Пока_без_кота »

Можно вообще по 1 проводу (+ земля и питание): http://easyelectronics.ru/upravlenie-se ... ovodu.html
Реклама
Родился
Сообщения: 4
Зарегистрирован: Вт мар 14, 2017 15:46:23

Сообщение uvers »

pyzhman, спасибо за код. Сейчас попробую применить.

Добавлено after 1 minute 42 seconds:
Пока_без_кота, спасибо за ссылку. Интересная идея. Можно будет попробовать переделать когда все заработает.
Реклама
Родился
Сообщения: 4
Зарегистрирован: Вт мар 14, 2017 15:46:23

Сообщение uvers »

pyzhman, пожалуйста, объясните суть этой записи...
if(__led_state & 0x80)
ни как не складывается мозаика в голове. Как то странно себя ведет условие... Очень хочется не просто перекатать, а именно понять. Читал в интернете, но, не могу понять сути это строчки в контексте моей функции

Добавлено after 50 minutes 46 seconds:
как я понимаю:
есть некое число __led_state(не скажем равное 0)
есть второе 0x80 ,т.е 8

unsigned char data[]= {0,1,3,7,15,31,63,127,63,31,15,7,3,1};
.......
for (i=0;i<8;i++)
{
if(data & 0x80)
{PortControl|=(1<<PCdata);
PortControl|=(1<<PCshift);}
else
{PortControl&=~(1<<PCdata);

тогда визуализация функции if(data & 0x80) будет такая:
//data = 0
0b00000000 - это ноль
0b11111111 - это 8
на выходе получим 0b00000000 т.е 0 , а это значит false тогда if(false) на первой итерации не попадет в PortControl|=(1<<PCdata)

}

я все правильно понимаю или ошибаюсь?
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

uvers писал(а):if(__led_state & 0x80)
Это условие истинно, когда бит №7 в __led_state установлен и ложно когда сброшен, если конечно __led_state однобайтный тип данных.
uvers писал(а):есть второе 0x80 ,т.е 8
Шестнадцатеричное 0x80 - это 128 десятичное или 0b10000000 двоичное.
uvers писал(а):if(data & 0x80)
Наверное Вы хотели сделать вот так

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

if(data[i] & 0x80)
uvers писал(а):0b11111111 - это 8
Это 255, но десятичные цифры неудобны, двоичные длинны, лучше 0xFF.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

Вернуться в «AVR»