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

А можно просто сделать на логике счетчик и снимать с него данные с помощью мк?

Как вариант, Вы можете использовать специализированные микросхемы, предназначенные для этого, либо (если нет дребезга) что-нибудь на базе D-триггеров и счетчиков из дискретной логики. Но еще лучше, опять же ИМХО, взять CPLD и организовать на ней необходимые функции.

Поделиться сообщением


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

Вот так я делал на Mega16.

Работает без глюков при частоте импульсов 500 Гц. Тактовая МК 16МГц.

Фаза А сидит, одновременно, на INT0 (нарастание) и INT1 (спад).

 

#include <avr/io.h>
#include <avr/interrupt.h>
  ...
#define PHASA_B_PORT     PORTD
#define PHASA_B_DDR      DDRD
#define PHASA_B_PIN      PIND 
#define PHASA_B_n        1  
  ...
volatile signed char count_temp;
  ...
ISR (INT0_vect)
{
    if (bit_is_clear(PHASA_B, PHASA_B_n))
        count_temp++;    
}

ISR (INT1_vect)
{
    if (bit_is_clear(PHASA_B, PHASA_B_n))
        count_temp--;
}

void int_init ( void )
{
    PHASA_B_DDR  &= ~(1 << PHASA_B_n);
    PHASA_B_PORT &= ~(1 << PHASA_B_n);
    count_temp = 0;
    MCUCR = (1 << ISC01) | (1 << ISC00) | (1 << ISC11) | (0 << ISC10);
    GICR  |= (1 << INT0) | (1 << INT1);    
}

int main ( void )
{
    signed char count_temp2;
    long counter;
    ...
    int0_init();
    sei();
    ...
    while(1)
    {
        ...
        cli();
        count_temp2 = count_temp;
        sei();
        counter += count_temp2;
        cli();
        count_temp -= count_temp2;
        sei();
        ...
    };
    return 0;
}

Поделиться сообщением


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

C вывода каждого триггера счетчика, сигнал идет параллельно счетчику на МК?

На мк снимаем двоичный сигнал и переводим его в десятиричный формат, тем самым узнаём сколько импульсов мы имеем в данный момент?

Поделиться сообщением


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

PaulB вот эту темку http://electronix.ru/forum/index.php?showtopic=60502 посмотрите (если конечно раньше не видели).

Поделиться сообщением


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

Нашел схемку, думаю выдернуть из неё счетную часть. Что вы об этом думаете?

http://radiokot.ru/circuit/digital/measure/07/index.shtml

Поделиться сообщением


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

А кто нибудь, что нибудь, о таких микросхемах слыхал?

LS7084

HCTL 2032

Да, но не применял.

Поделиться сообщением


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

Оба вывода энкодера подаются на 2 прерывания по обоим фронтам. Или (лучше) опрашивать энкодер с частотой, достаточной для ловли его состояний. Обработчик прерывания один и тот же:

 

Читаем энкодер. При вращении вперёд он проходит значения 1-0-2-3-1-0-2-3..., назад - наоборот. Если считанное состояние 2, предыдущее 0, пред-предыдущее 1 то шаг++. Если текущее 1, предыдущее 0, пред-предыдущее 2 то шаг--. Всё другое - это дрожание вала ака "дребезг". Регистровая переменная "шаг" изменяется в прерывании, переменная "шаги" в основной программе не реже, чем 100 шагов: шаги+= шаг; шаг=0.

Анализ, изменилось ли состояние, занимает 9 циклов контроллера и шаг++/шаг-- ещё 14. Ну и на вход-выход в прерывание ваш С-компилятор накрутит не знаю сколько :)

Изменено пользователем Maik-vs

Поделиться сообщением


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

Сделал счетчик от прерывания, оказалось что такого вполне должно хватить.

Энкодер подключен напрямую к мк без логики т.к. сначало хочется хотябы просто считать импульсы в одном направлении.

Считать то вроде считает, но неправильно. энкодер отключил, после включения питания на дисплее показания сразу добегают до пары тысяч, и изменяются каждую секунду.

значит дело в коде?

#include<mega128.h>
#include <delay.h> 
#include <stdlib.h>  
#include <stdio.h>  
#include <lcd.h>

#asm
.equ __lcd_port=0x15;PORTC
#endasm

unsigned long q;        
interrupt [EXT_INT0] void ext_int0_isr(void)   // процедура обработки прерывания
{ 
  
          q++;             //с каждым прерыванием значение переменной увеличивается на 1
           
}
                
int main()
{
         char w[32];    //для преобразования числа в строку/символы
DDRA=0x00;
PORTA=0x00;
DDRB=0xF0;
PORTB=0x00;
DDRE = 0b00110000;
PORTE = 0b00100000;
lcd_init(16); 


  lcd_gotoxy(5,0);
      lcd_putsf("Hello!"); 
   Privet();     
     delay_ms(3000);
      
       while(1) {
       q=0;
      lcd_clear();
     
      Go(); 
      lcd_putsf(" "); 
      Stop();
       lcd_putsf(" ");
      Reset(); 
      delay_ms(10); 
            
    if  (!(PINA & 0b00000001))  {                //Пуск
    lcd_clear();
      Go(); 
      delay_ms(1000);
          SREG.7 = 1;
        EIMSK = 0x01;
        EICRA = 0x0C;
        EICRB = 0x0C;  
          
       while(PINA & 0b00000100){                 //Сброс 
         lcd_clear(); 
        sprintf(w,"adc= %d\n",q);
        lcd_puts(w);
         delay_ms(50);
        } 
       lcd_clear();          
         Reset(); 
         delay_ms(2000);
         } 
           
      }         
  return 0;

}

Поделиться сообщением


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

значит дело в коде?

Риторический вопрос :laughing:

Вы дребезг как давите?

Датчик кодируется кодом Грея?

Попробуйте применить RC-цепочку на входе ИНТ0 с постоянной цепи скажем так в 5 раз меньшей максим. частоты импульсов, или примените логику на входе для подавления дребезга например на елементах исключающее ИЛИ.

 

Поделиться сообщением


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

я же вроде указал что датчик от платы совсем отключил, а прошивка в момент работы сама считает не пойми какие прерывания, хотя должна показывать 0 т.к. энкодер отключон и прерываний не происходит.

 

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

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

Поделиться сообщением


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

я же вроде указал что датчик от платы совсем отключил, а прошивка в момент работы сама считает не пойми какие прерывания, хотя должна показывать 0 т.к. энкодер отключон и прерываний не происходит.

 

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

Посмотрите для начала как генерирует код начальной инициализации Ваш помощник встроенный в Вашем компиляторе.

Посмотрите как опрашиваются кнопки.

Что такое Go(); , Stop();, и Reset(); остаётся только догадываться.

Ваши значения счётчика могут так изменятся из-за наводок на входе ИНТ0 или неправильной инициализации МК.

Что в MCUCR и GICR ? ЗачемВам здержки? посмотрите хотябы код предложенный Vetal-Soft. прочитайте ссылку данную выше. Обнлвление на ЖКИ сделайте к примеру по прерыванию таймера а не в цикле

Поделиться сообщением


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

Все заработало. считает нормально :)

теперь незнаю как сделать реверс, чтобы сначало при вращении вала значение увеличивалось, а при в ращении в другую сторону уменьшалось. наверное надо использовать логику?

Поделиться сообщением


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

я когда-то делал на асм для старой 8515 - тоже через прерывания - датчики положения для станков ЧПУ по принципу sin-cos - всё работало как часы - в любую сторону - делал по фронту .

Мой коллега сделал на рассыпухе (ИЕ7 и другая логика) а я программно реализовал на аврке

Поделиться сообщением


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

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

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

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