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

Расширитель Входящих Сигналов Для 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 пользователей онлайн

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

    • Он довольно бесполезен в нашу современность. Всё, что нужно добавить к 7104 вместо второго чипа, находится на скрине, который вы скинули. Основная проблема с дискретной реализацией, имхо, в ключах и в таймингах. И если вторые ещё кое-как можно обеспечить чисто ардуиновскими костылями при таких разрядностях, то побороть утечку ключей трудно. Можно искать ADG411 конечно, и делать полностью дискретную реализацию самому, но эту проблему как раз и призвана решить 7104. Проектировщику остаётся взять два хороших ОУ, компарь, опору, и сделать схему похожую 8052 со скрина, а 7104 сама разберется с управлением Два 74hc165 регистра, и данные можно выгружать в МК. Что интересно, эта топология автонуля ещё ближе к схеме АЦП В7-38. Такая система автонуля мне больше нравится, чем автонуль в 7135, в которой ключ автонуля включен между очень чувствительным к утечкам инвертирующим входом интегратора и выходом, а тут между выходом и неинвертом, что не даёт утечке ключа автонуля "подсаживать" конденсатор интегратора. Я могу ошибаться в том, насколько хорошо это реально влияет на характеристики, мне просто больше нравится такая раздельная система, когда конденсатор автонуля не включен в цепь интегратора. Так или иначе, эти АЦП, по сути, есть пик двухтактной топологии, и что-то более крутое придумать будет сложно, остаётся лишь повторять, будь то в дискрете или используя микросхемы. Выжать больше 16 бит я думаю не выйдет, сложно объяснить, но это упирается в размахи напряжения, и слишком большое увеличение резистора интегратора/его емкости (что увеличивает влияние утечек, ухудшающих линейность). Не зря в 7104 питание аналоговой части +/-15В, а на интеграторе аж 9В. На эту тему там написано, что это компромисс между всеми ошибками:   И на всякий случай, нет, MAX132 не считается, потому что у неё многотактное интегрирование
    • Всем здравствуйте! Пока на улице идут ливни, я занялся написаем скетча для приемника. Написал, подключил, проверил, все работает! Но вылезла очень большая проблема. Когда подаю питание, севера становится в среднее положение, но потом ее начинает не по детски колбасить. То в одну сторону, то в другую, то она не двигается, то очень сильно гудит и "вибрирует" качалкой. При этом L7805CV дико греется. Уже спустя 3 секунды палец обжигает. В чем может быть дело? Я так полагаю, это нехватка тока для сервы? Кушает она немало...
    • а можете ткнуть именно в ваши разработки ?
    • Ничего особенного. Перерисованная мною вот эта схема.
    • По схеме из журнала , я  33  для С8, С9  не нашёл ...  Впихнул  на 22  , но пока не подцепил подстроечник . тоисть пока что просто увидеть работу  , а потом  буду вгонять в точность  Пока планирую буду баловатся входной частью как в журнале . потом  буду думаать дальше   
    • Кстати, можете померить ёмкость БЭ, у оригиналов в районе 6000 пФ.
    • Общая ёмкость С8 и С9 должна быть 33 пФ, а судя из номиналов получается минимум 39, максимум 58 пФ. А должно быть 24-42 пФ, для этого С9 = 18 пФ. Ну это если с подстрочником. Если его нет (как у большинства) то все норм.
  • Похожий контент

×
×
  • Создать...