Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Простой делитель на простом МК ATMEL?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
The Fresh
Понимаю, что старо, как мир. Может есть готовые примеры на базе суперпростого TINY? Погуглил ничего не нашел, знаю плохо искал, но уже забадался smile.gif. Посоветуйте дайте ссылку. Спасибо.
domowoj
Дольше искать.
Тупо опрашиваешь 4 входа, фиксируешь переход из 0 в 1(или наоборот) , програмно организуешь
каждый счетчик, 4 выхода!
Задержка распространения будет определяться скоростью опроса + некоторая програмная задержка.
The Fresh
На каком самом простом AVR можно организовать, так чтобы с внутреним генератором т.е. минимум железа, простой делитель, на входе 5в на выходе 5в
domowoj
На любом где входов-выходов больше 8-ми,
например:
AT90s2313, Atniny2313, Attiny24 и тд.
The Fresh
Спасибо. Скачал AVR32Studio и AVRStudio 4.13, на чем лучше начать и если можно скиньте пожалуйста исходник пустышку, куда я смогу вставить свои while(1)
{
if gpio1=1 {i1++}
if gpio2=1 {i2++}
if gpio3=1 {i3++}
if gpio4=1 {i4++}

if i1=10 {gpio5=1 }
...........
}
Палыч
Вам нужен транслятор языка С для AVR. Если Вы - только учитесь, то, наверное, лучше взять CodeVisionAVR.

P.S. Но, такая простая программа может быть написана и на ассемблере. Будите изучать ассемблер?
The Fresh
Понятно, что на асме быстрее будет в плане выполнения программы, но мне хотелось бы while do, тем более скорость не критична т.к. речь идет о герцах. Для ламера сомое то smile.gif
defunct
Цитата(The Fresh @ Apr 11 2008, 17:19) *
Скачал AVR32Studio и AVRStudio 4.13,

AVR32Studio под другой кристал - под AVR32.

Так что останавливайтесь на AVRStudio 4.13.
Вам еще потребуется WinAVR.
Скачайте и установите самый свежий WinAVR.
После установки WinAVR, запустите AVRStudio. В первом отрывшемся диалоговом окне выбрать New Project -> AVR GCC, и следовать инструкциям (имя каталога проекта, .c файла, чип, отладчик и т.п.)
начать можно так:

Код
#include <avr/io.h>
#include <avr/interrupt.h>

void main(void)
{
   ...
}
The Fresh
Спасибо. Еще один небольшой вопрос. Как сделать по простому задержку на выходе на определенное количество сек,мсек, ведь выходов будет четыре, следовательно во времени эти задержки будут смещены?
domowoj
Не понял.
The Fresh
Например на первый счетный пришло 10 импульсов, следовательно на выходе формируем единицу с задержкой Nмсек. В следующий момент скажем через Kмсек на второй счетный пришел 10-ый импульс, формируем единицу на нем, но время выходного импульса на обоих выходах должны быть одинаковы, а события происходят в разное время т.е. не получится сделать

set gpio5=1;
delay (1000);
Или применить простые счетчики и считать в процессе иттерации какой выход сколько был в состоянии 1 т.е.
output1++;
if output>1000 set gptio5=0;
Далее опытным путем или дизассемблировав посчитать потактово время выполнения иттерации, ну это я так по ламмерски рассуждаю.
tazik
Подойдет, например ATtiny26 - 2 порта по 8 I/O, внутренний RC генератор. Но есть одно но: при программировании придется выставить fuse RSTDSBL - так как Reset является альтернативной функцией одного из IO пинов. После этого контроллер можно будет перепрограммировать только с помощью параллельного программатора. Такие пироги crying.gif

Вот исходники на астме и проект для Proteus`а. В протеусе нет контроллера tiny26, пришлось использовать 90S8535. Соответственно, в asm-файле придется перекомментировать 4 первые строки.
Нажмите для просмотра прикрепленного файла

По поводу синхронизации... Можно предложить 2 варианта:
1) Зафиксировать сразу все входные сигналы во временном регистре. Потом их обработать с записью результата во временный регистр. Потом одновременно передать все на выход. - Но это, правда, не совсем та синхронизация )
2) По возможности выровнять по времени ветки исполнения алгоритма добавлением NOP-ов. В принципе, ничего сложного.
Reton
Можно и так, но лучше output1++; перенести из main в обработчик прерываний от таймера. Тогда не надо будет подсчитывать время опытным путем.
domowoj
Чтобы увеличить реакцию на входные воздействия можно применив тини2313 используя PCINT.
Палыч
Цитата(The Fresh @ Apr 13 2008, 10:06) *
Например на первый счетный пришло 10 импульсов, следовательно на выходе формируем единицу с задержкой Nмсек. В следующий момент скажем через Kмсек на второй счетный пришел 10-ый импульс, формируем единицу на нем, но время выходного импульса на обоих выходах должны быть одинаковы, а события происходят в разное время
Не совсем понятно: зачем формируется единица с задержкой Nмсек? Вы хотите таким образом учесть разное время обработки событий? Имхо, оно будет измеряться микросекундами. Впрочем, можно просто замерить уже на макетке... Вот набросок программы для деления входного сигнала INi на 10, и формирования соответствующего выходного сигнала OUTi. Нетрудно будет расширить программу на 4 канала.
Код

void main(void)
{
  // Инициализация
  xi= INi;  ci=0;  OUTi= 0;
  //...................
  for(;;)
  {
    // Делитель на 10
    if(xi != INi)
    {
      xi= INi;
      if((++ci) == 10)  { ci= 0; OUTi= ~OUTi; }
    }
    //................
  }
}
The Fresh
Цитата
Не совсем понятно: зачем формируется единица с задержкой Nмсек?

Это для того, чтобы прибор перед которым, будет ставиться делитель, смог стопроцентно захватить импульс.
domowoj
Цитата(The Fresh @ Apr 15 2008, 02:06) *
Это для того, чтобы прибор перед которым, будет ставиться делитель, смог стопроцентно захватить импульс.


Не вижу в ваших сишных виршах делителя на 10.
Если на вых. нужен меандр нужно фиксировать 5-й входной импульс,
если не меандр , то любой другой(девятый).
Т.е. с приходом 9-ого вх. имп. изменяете состояние вых., с приходом 10-ого - на противоположное.
Посмотрите диаграммы работы любого счетчика.
Палыч
Цитата(The Fresh @ Apr 14 2008, 22:06) *
Это для того, чтобы прибор перед которым, будет ставиться делитель, смог стопроцентно захватить импульс.
А, разве меандр сформировать не проще? Или обязательно нужен выходной импульс строго опредлеленной длительности после десяти импульсов на входе? Огласите условие поставленной задачи подробнее.
The Fresh
Нужен простой декадный делитель на 4 канала, входная частота максимум 5 Гц, так как на выходе нужен импульс пошире, чем ширина входного импульса, то формировать его надо с приходом 10-го импульса и держать скажем 1 сек. Это маленько выбивается из понятий обычных счетчиков, но таковы условия задачи.
Палыч
Ну, так оно и получается. Вам и никто не советовал выбрасывать девять импульсов из десяти. Если выходной сигнал менять на противоположный после каждых десяти изменений сигнала на входе - получите меандр. Так сделано в наброске программы в посте выше (№15). При 5 Гц на входе 5/10=0,5 Гц на выходе - импульс будет ровно 1 сек. При меньшей входной частоте - еще больше по времени.
domowoj
Цитата(Палыч @ Apr 15 2008, 20:34) *
Если выходной сигнал менять на противоположный после каждых десяти изменений сигнала на входе - получите меандр.

Это получится делитель на 20.
А вот если 5-того импульса менять, то на 10 и как раз 1сек.
Палыч
Цитата(domowoj @ Apr 15 2008, 16:56) *
Это получится делитель на 20.
Неправильно. Делитель на 20 получился бы, если бы мы считали не изменения на входе, а, например, нарастающие фронты, т.е. переходы из 0 в 1. Поскольку считаются любые изменения (из 0 в 1, из 1 в 0), то получается делитель на 10.
domowoj
Цитата(Палыч @ Apr 15 2008, 20:34) *
после каждых десяти изменений сигнала на входе


Извините, не рассмотрел.
Я говорил о фронтах(спадах), атак, впринципе, говорим об одном и том же.
tazik
Цитата
Нужен простой декадный делитель на 4 канала, входная частота максимум 5 Гц, так как на выходе нужен импульс пошире, чем ширина входного импульса, то формировать его надо с приходом 10-го импульса и держать скажем 1 сек. Это маленько выбивается из понятий обычных счетчиков, но таковы условия задачи.


В смысле так что-ли?
Нажмите для просмотра прикрепленного файла

Исходники на асме
Нажмите для просмотра прикрепленного файла
The Fresh
Я наверное изначально неправильно вопрос поставил, считать надо не количество изменений на входе а именно количество импульсов, т.е. физического как он есть и соответственно событие либо по переднему либо по заднему фронту. Если выбрать по переднему фронту то код надо менять так. Далее импульс на выходе будем формировать скажем после прихода 6, а скидывать с 10 т.е. ширина импульса на выходе будет всегда в диапазоне времени от 1-го до 10-го импульса вне зависимости от частоты и если вдруг питание пропадет то округление будет типа математичского (практически если брать 5 а не 6). Если неправ поправьте.
Код
void main(void)
{
  // Инициализация
  x1= IN1;  c1=0;  OUT1= 0;
  x2= IN2;  c2=0;  OUT2= 0;
  x3= IN3;  c3=0;  OUT3= 0;
  x4= IN4;  c4=0;  OUT4= 0;

  //...................
     // Делитель на 10
    if(x1 != IN1)&(IN1==1)
    {
      x1= IN1;
      ++c1;
      if(c1 == 6)  { OUT1=1; }
      if(c1 == 10)  { c1= 0; OUT1=0; }
    }
if(x2 != IN2)&(IN2==1)
    {
      x2= IN2;
      ++c2;
      if(c2 == 6)  { OUT2=1; }
      if(c2 == 10)  { c2= 0; OUT2=0; }
    }

if(x3 != IN3)&(IN3==1)
    {
      x3= IN3;
      ++c3;
      if(c3 == 6)  { OUT3=1; }
      if(c3 == 10)  { c3= 0; OUT3=0; }
    }
if(x4 != IN4)&(IN4==1)
    {
      x4= IN4;
      ++c4;
      if(c4 == 6)  { OUT4=1; }
      if(c4 == 10)  { c4= 0; OUT4=0; }
    }

    //................

}
Палыч
После Ваших объяснений стало ещё более непонятно - "что же Вам нужно"? В чём отличие Вашего устройства от обычного делителя частоты?
The Fresh
Вобщем вот
domowoj
Цитата(domowoj @ Apr 15 2008, 07:59) *
Если на вых. нужен меандр нужно фиксировать 5-й входной импульс,
с приходом 10-ого - на противоположное.

Вам это и предлагали.

Цитата(Палыч @ Apr 15 2008, 20:34) *
Если выходной сигнал менять на противоположный после каждых десяти изменений сигнала на входе - получите меандр.

Или это.
Палыч
Цитата(The Fresh @ Apr 18 2008, 14:40) *
Вобщем вот
Простой делитель... Меандр... Что не устраивает в том, что Вам здесь предлагали?
The Fresh
До конца не разобрал код. Меня смутило то что в счетчике учитывается изменение сигнала
т.е. счетчик покажет 10 уже после 5 импульсов, вот это и смутило. Теперь после Ваших недоумений, еще раз пересмотрел код и понял что вот это OUTi= ~OUTi; будет менять выход на 10 импульсе в обратное состояние. Разница в моем и вашем коде в том, что у Вас он сделан рациональнее, а я не усмотрел алгоритма. Вот и все.

Код
void main(void)
{
  // Инициализация
  xi= INi;  ci=0;  OUTi= 0;
  //...................
  for(;;)
  {
    // Делитель на 10
    if(xi != INi)
    {
      xi= INi;
      if((++ci) == 10)  { ci= 0; OUTi= ~OUTi; }
    }
    //................
  }
}
Палыч
Отслеживание изменений имеет один изъян - устройство будет формировать импульс то по фронту входного сигнала, то - по спаду, в зависимости от того, какой уровень сигнала был на входе в момент начала работы. Это легко можно устранить чуть поправив инициализацию - если это нужно, конечно.

ci= xi ? 0 : 1; // По фронту
ci= xi ? 1 : 0; // По спаду
Laserr
А я делал делитель на 10000 на асме...
точнее, делилась частота подключенного кварца.
Ну а потом без труда определил номиналы этих кварцев.
The Fresh
Ok
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.