Перейти к содержанию

Расширитель Входящих Сигналов Для Lpt


maix

Рекомендуемые сообщения

Здравствуйте форумчане !

Делаю расширитель входящих данных для LPT порта, наваял такую схему и код.

Данные передает по своему собственно-выдуманному протоколу, так как на данном этапе мне легче придумать, чем использовать уже готовое =))

Это мой первый опыт работы с ATMEGA16, да и вообще с AVR, поэтому хотелось бы услышать адекватную критику по коду и схеме..

shema.png

#include <mega16.h>
#include <delay.h>
#define pause delay_ms(10)
int pins;
void avr_init(void) {
PORTA=0xFF;
DDRA=0xFF;
PORTB=0x01;
DDRB=0x01;
PORTC=0x00;
DDRC=0x07;
PORTD=0x00;
DDRD=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
MCUCSR=0x00;
TIMSK=0x00;
ACSR=0x80;
SFIOR=0x00;
}
void peredacha(void) {

PORTC.1 = 1;
pause;
if (PINA.0 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.1 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.2 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.3 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.4 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.5 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.6 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.7 == 1){
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
else{
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
 pause;
 PORTC.2 = 1;
 pause;
 PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

}
void main(void) {
avr_init();
// считываем состояние пинов A
pins = PINA.0+PINA.1+PINA.2+PINA.3+PINA.4+PINA.5+PINA.6+PINA.7;
while (1) {
 // если состояние пинов изменилось
 if(pins != PINA.0+PINA.1+PINA.2+PINA.3+PINA.4+PINA.5+PINA.6+PINA.7) {
	 pins = PINA.0+PINA.1+PINA.2+PINA.3+PINA.4+PINA.5+PINA.6+PINA.7;

	 while (PINB.0 == 0){ // если lpt занят другим контроллером
		 pause;
	 }

	 PORTC.0 = 1; // говорим другим контроллерам что lpt занят

	 peredacha();

	 PORTC.0 = 0;
 }

}
}

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

если поясните, что это вообще такое - поможем ))))))))

взращенный Протеусом быть хорошим электронщиком да и программером быть не может

построение схемы начинайте с чтения даташитов на детальки...

а то потом: АААА!!! мне хреновый МК продали!!! в Протеусе работает, а на плате нет.... АААЫЫЫ!!! и стонов на 15 листов... :(

Изменено пользователем Гость
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Александр Д, это расширитель входящих сигналов для lpt порта, так как стек Status у LPT имеет всего 5 пинов, мне нужен расширитель что бы у меня было не 5 пинов, а больше =)

а то потом: АААА!!! мне хреновый МК продали!!!

Да я и не кричу же ! сижу копаю, как видите... Прошу критики, не более...

Изменено пользователем maix
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Может конструкцию pins = PINA.0+PINA.1+PINA.2+PINA.3+PINA.4+PINA.5+PINA.6+PINA.7 заменить на pins = PINA?

А передачу данных в порт сделать обычной проверкой нулевого бита с последующей операцией сдвига регистра pinsв право (посмотрите пример работы со сдвиговыми регистрами, там передача сделана таким образом).

Изменено пользователем korsaj
Ссылка на комментарий
Поделиться на другие сайты

а зачем МК???

перед тем как что-то изобрести обязательно загляни в учебник ;)

пробовали воспользоваться поиском?

в своё время разное делал на LPT - в сети куча-мала информации о расширении!!

Ссылка на комментарий
Поделиться на другие сайты

А как засунуть вот это полотно в цикл ?

PORTC.1 = 1;
pause;
if (PINA.0 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.1 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.2 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.3 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.4 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.5 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.6 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

PORTC.1 = 1;
pause;
if (PINA.7 == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;

Пытался вот так, но выдает ошибку..

int i;
i=0;
while (i<8){
PORTC.1 = 1;
pause;
if (PINA.i == 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;
i++
}

Изменено пользователем maix
Ссылка на комментарий
Поделиться на другие сайты

а нормальная адресация к битам не работает что ли?

for(char i=1 ; i != 0 ; i<<=1){
if((PINA & i)!=0){
 PORTC |= (1<<2);
 //что такое pause; я не понял, судя по названию - задержка, но ведь не функция! Может макрос?
 pause;
//ну и дальше ваш код, что-то там накручено, не стал разбираться, да и непривычно копаться в этих PORTC.5
}
}

Это достаточно оптимизированный вариант, вот более очевидный:

for(char i=0;i<8;i++){
if((PORTA & (1<<i))!=0){
 //код
}
}

Но это гораздо медленнее: если сдвиг на 1 бит идет за 1 такт (команда lsr/lsl/rol/ror/может_еще_какую_забыл), а сдвиг константы на константу не занимает вообще ничего (это делает препроцессор) то сдвиг числа или переменной на переменную выполняется в цикле с проверками, что в несколько раз дольше. Тем более что конкретное значение i а только проверка i-го бита.

ДОБАВИЛ: исправление, первый цикл начинался с 0. Очевидно, он был бы бесконечным

P.S. Что все-таки такое pause, это какой-то макрос cvavr?

Изменено пользователем COKPOWEHEU

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

немного не так (это я о посте #9, а с постом #10 полностью согласен)

unsignet char i, in_pins;
i=0;
in_pins=PINA;
while (i<8){
PORTC.1 = 1;
pause;
if (in_pins .0== 1){
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
else{
PORTC.2 = 1;
pause;
PORTC.2 = 0;
pause;
PORTC.2 = 1;
pause;
PORTC.2 = 0;
}
pause;
PORTC.1 = 0;
pause;
in_pins=in_pins>>1;
i++
}

Изменено пользователем korsaj
Ссылка на комментарий
Поделиться на другие сайты

COKPOWEHEU, korsaj, спасибо, сижу разбираюсь =)

что такое pause; я не понял, судя по названию - задержка

#define pause delay_ms(10)

Просто пришел из PHP, сложновато сразу перескочить на СИ и биты..

Ссылка на комментарий
Поделиться на другие сайты

Могу дать еще пару советов по повышению читаемости кода:

Убрать инициализации всего подряд нулями: после сброса там и так нули.

Форматировать код, впрочем не исключаю, что это вина движка форума, он упорно удаляет значимые пробелы в начале строки. Визуально разделить блоки (ну там пустую строчку или комментарий, например между #include и #define, да и дальше есть пара мест).

Сгруппировать однотипные операции в какую-нибудь структуру - макрос или процедуру, например #define blink PORTC|=(1<<2); pause; PORTc &= ~(1<<2); pause;

Внятно сформулировать алгоритм работы программы: вполне может найтись более красивое решение чем копипаст PORTC.2 :-)

Ну и конкретно по участку из постов #9-11

#define blink PORTC |= (1<<2); pause; PORTС &= ~(1<<2); pause; //можно было сделать и процедурой, но ради 4 команд не стоит, на вызовах потеряем больше.
unsignet char i; //тут можно обойтись просто char, сравнение идет на строгое равенство, там уже без разницы, есть знак или нет.
for(i=1; i!=0; i<<=1){ //может показаться, что это страшное побитовое колдунство, но это не так, оно не страшное. Оператор A<<=b - сдвиг числа A на b бит в сторону увеличения, то есть умножение на 2^b, это на случай если кто не знал. Вообще, сдвиги - хорошая штука.
PORTC.1 = 1;
pause;
blink;			 //раз уж дерганье порта все равно происходит хотя бы один раз независимо от результатов опроса бита - почему бы не вынести его за пределы цикла?
if ((PINA & i)==0){blink} //здесь фигурные скобки обязательны, поскольку макрос - не одна команда а последовательность. Впрочем можно скобки поставить в самом макросе, это будет даже правильнее.
//это условие лучше перепроверить, я мог ошибиться, возможно стоит поставить !=
//кстати если оптимизатор включен, он эту проверку должен проводить за 1 такт (не считая макроса, разумеется) командой sbic/sbis, так что сдвиг копии порта ничего не даст.
PORTC.1 = 0;
pause;
}

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Про инициализацию всего подряд не знал, думал надо все явно указывать =)) , разделение кода делаю, мне самому так приятнее, вина движка.. на счет группировки, я сначала хотел написать для начала "просто что бы работало", чуть позже уже буду оптимизировать..

Пока что читаю, вникаю, еще раз спасибо за пояснения.. =)

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...