Дублирование сигнала на пине

nibiluk
Offline
Зарегистрирован: 10.01.2016

Доброго времени суток, извиняюсь если вопрос слишком глупый, я совсем новичёк в этом.

Что собственно нужно:

подаём на пин 1 импульсы скажем 8кГц, 

с пина 2 нужно снять такой же сигнал,

с пина 3 такой же по частоте, но инвертированый.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

nibiluk, проще простого..

void setup() {
pinMode(2, INPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
attachInterrupt (0, myfunc,CHANGE);
}

void myfunc(){
  if (PIND&1<<2) { PORTD|=1<<PB3; PORTD&=~(1<<PB4); }
   else { PORTD|=1<<PB4; PORTD&=~(1<<PB3); } 
}

void loop() { }
alexvs
Offline
Зарегистрирован: 22.07.2014

Мне кажется, что  на начальном этапе проще и понятнее, если функция myfunc будет выглядеть так

​void myfunc(){
bool a = digitalRead(2);
digitalWrite(3,a);
digitalWrite(4,!a);
}

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexvs,  на начальном да, полностью согласен.  Хотя свой пример я тоже упростил.. Есть способ посложнее  на таймере, чтоб не съедать ресурсы М.К.  В вашем примере тайминги на 8 кГц собьются, прямой и инверсный сигналы начнут "налезать" друг на друга. Не знаю, на сколько критично для Т.С. такой недостаток..

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Что нибудь типа 74ALS04 дешевле получится.

 

nibiluk
Offline
Зарегистрирован: 10.01.2016

Большое спасибо, вот про прерывания я как то вобще не подумал.

alexvs
Offline
Зарегистрирован: 22.07.2014

dimax, если не cложно, дайте пример на таймере, с целью обучения страждующих масс :)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

alexvs, к сожалению я немножко ошибся, не получается чисто аппаратными средствами таймера повторить на его выходе входную частоту. Я думал про такой вариант:

void setup() {
pinMode(5,INPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0)|(1<<WGM11); //oc1a oc1b enable , 
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12)|(1<<WGM12)|(1<<WGM13);//тактирование от входа Т1, MODE14
ICR1=1;
}
void loop() {}

В этом варианте МК не используется, загрузка будет 0%, но частота поделится надвое , на выходах будут сигналы как и задумано в инверсии. Возможно есть вариант аппаратно-программный, но это уже не интересно.

alexvs
Offline
Зарегистрирован: 22.07.2014

dimax, все равно спасибо.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну, ежели надо одновременно, то пример dimax, точнее должен выглядеть как-то так:

void setup() {
  pinMode(2, INPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  attachInterrupt (0, myfunc,CHANGE);
}

void myfunc()
{
  unsigned char dataD = pinD;  // читаем всё содержимое порта D

  // умножаем содержимое на маску, сбрасывая ОБА бита и добавляем только тот, который инверсный
  // , пишем обратно весь порт одновременно:
  if ( dataD & (1<<2) ) { PORTD = (dataD & B11100111) |  (1<<PB3); }
   else                 { PORTD = (dataD & B11100111) |  (1<<PB4); }
}

void loop() { }

Но, при этом все равно останется сдвиг обоих сигналов относительно входящего на время реакции на прерывание и длительность его работы.

Gres
Gres аватар
Offline
Зарегистрирован: 26.03.2013

Плюс каждая операция выполняется за определенное время в тактах. Если нужна синхронность придеться использовать аппаратные средства, стоимость копеечная. Для таких простейших задач не нужно использовать микроконтроллеры.