Jump to content
Sign in to follow this  
maix

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

Recommended Posts

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

Делаю расширитель входящих данных для 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;
 }

}
}

Share this post


Link to post
Share on other sites
Guest

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

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

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

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

Edited by Guest

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

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

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

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

Edited by maix

Share this post


Link to post
Share on other sites

Вебинар "Новый BlueNRG-LP с Bluetooth 5.2 и Long Range — волшебная палочка разработчика IoT" (04/02/2021)

Приглашаем 4 февраля на бесплатный вебинар о BlueNRG-LP - новой системе-на-кристалле (SoC) STMicroelectronics. На вебинаре будут детально рассмотрены функциональные блоки, особенности подключения, аппаратные и программные средства для разработки, настройка сценариев с помощью BlueNRG-GUI, практические примеры работы с микросхемой, а также примеры применения BlueNRG-LP в устройствах интернета вещей.

Подробнее

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

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

Edited by korsaj

Share this post


Link to post
Share on other sites

Новые компактные конденсаторы Panasonic серии TPS. Закаленный характер.

Panasonic представил новую серию TPS твердотельных танталовых конденсаторов с проводящим полимером для поверхностного монтажа. Конденсаторы серии TPS обладают уникальными особенностями, что делает их отличным выбором для использования в приложениях с высокими требованиями.

Подробнее

Guest

а зачем МК???

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

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

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

Share this post


Link to post
Share on other sites

SiC MOSFET на 1200 В для схем флайбэк до 500 Вт!

Компания Wolfspeed выпустила новые карбид-кремниевые транзисторы C3M0350120D/J на 1200 В, предназначенные для маломощных устройств мощностью до 500 Вт. Карбид-кремниевые транзисторы в сравнении с кремниевыми демонстрируют меньший на 75% уровень потерь на переключение и меньшее на 50% значение потерь проводимости в рабочем режиме при температуре кристалла 100…150°С.

Подробнее

Guest

так и делалось всегда )))

книгу не помню - подарил, там была глава по LPT

в Сети множество материалов на эту тему...

Share this post


Link to post
Share on other sites

korsaj, спасибо за дельные советы.

Александр Д., Электронщик, Хочу освоить AVR, поэтому делаю на амеге

Share this post


Link to post
Share on other sites

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

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++
}

Edited by maix

Share this post


Link to post
Share on other sites

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

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?

Edited by COKPOWEHEU

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

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

Share this post


Link to post
Share on other sites

немного не так (это я о посте #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++
}

Edited by korsaj

Share this post


Link to post
Share on other sites

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

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

#define pause delay_ms(10)

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

Share this post


Link to post
Share on other sites

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

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

Форматировать код, впрочем не исключаю, что это вина движка форума, он упорно удаляет значимые пробелы в начале строки. Визуально разделить блоки (ну там пустую строчку или комментарий, например между #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 раз.

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Сообщения


  • Осциллограф DOS1102 (клон Owon sds1102) 100МГц

  • Similar Content

    • By Обычный Человек
      Микроконтроллер ATmega328p, внешний кварц 16МГц. Компилятор avr-gcc с оптимизацией O1

      Написал код для управление шаговым двигателем. Работает так: требуемая скорость задается переменной STP1_ReqSpeed, дальше с частотой 100Гц срабатывает таймер TIM0, который высчитывает с какой частотой надо подавать сигналы на вход шагового драйвера. TIM1 работает в режиме частотно импульсной модуляции и по прерыванию меняет значение пина на противоположное.

      Управление работает, скорость регулируется, но по какой то причине случаются пропуски шагов. Чаще всего во время ускорения. Количество пропусков от 0 до 4, обычно 2-3, длятся 32мс.

      Из кода вырезал неиспользуемое. Заменить прерывания на аппаратный ШИМ возможности нет. Как убрать эти пропуски?
      Осциллограммы:
       
       
    • By Артур Измаилов
      1.Создать схему в которой два светодиоды загораются в следующей последовательности:  1 и 2, 2 и 3, 3 и 4, …, 15 и 16, 1 и 2 и т.д. (т.е. создается эффект движения двух светодиодов).
      Дано условие выше. Решение задачи нужно представить в Proteus. Код для программирования пишу в AtmelStudio 7. Схему собрал в Proteus. Вывел 16 светодиодов через 2 порта (Порт B и Порт D). МК использовал ATMEGA 8 вариации в корпусе DIP с 28 ножками (SPDIL28). 
      До этого смог написать схему, чтобы работали светодиоды в последовательности 1.2.3.4.5....16.1.2.3.4 и тд. Делал через оператор FOR. Однако с этим кодом начались проблемы. Помогите пожалуйста. 
      Нижу представил изображение кода. 
      Заранее спасибо!
       

    • By Lisitsin
      Собираем компьютер ZX Spectrum на микроконтроллерах AVR своими руками!
      Проект открытый, все исходники и информация проекта по ссылке
      https://yadi.sk/d/9S2S0ZmNqsLykQ
      Проект печатной платы выполнен в PCAD-2006, программное обеспечение разработано в AVRStudio  4b401
      Здесь отвечу на все возникающие вопросы и помогу со сборкой и запуском
    • By O5-14
      По поводу этого https://cxem.net/mc/mc220.php девайса. Как напоминалка паролей думал сделать, только в моих краях 1604 нету( Под wg12864 нет случаем модификации ? 
      И что такое значит "Текстовые файлы должны быть в обычном txt формате и без форматирования" - первая часть понятна. А без форматирования ? Одна длинная строка ? Пробелы-то хоть можно ?
    • By Karl-Ieronim
      Коллеги, всем привет. 
      Увидел вот такой проект. 
      Несмотря на явную привлекательность что-то совсем мало повторивших. 
      Может кто-то из завсегдатаев форума делал этот проект? 
      Интересует ваше мнение: хочу повторить, но не силен в программировании, поэтому беспокоюсь на счёт подводных камней с которыми не смогу справиться. 
×
×
  • Create New...