Atmega8535 для ардуино

добрый день, я написал код определения угла по энкодеру и атмега8535, подсчет проходит корректно и отображается как в прямом так и в реверсном направлении и генерирует сигнал полного оборота то есть тахометра, вот я уперся в стенку каким образом преобразовать этот сигнал тахометра в число оборотов и вывести на дисплей , вот с выводом на дисплей все понятно там есть хранение переменной в второй строке а вот как прописать функцию ума не приложу, вернее какими командами прописать



```
#include <avr/pgmspace.h>

#include <LiquidCrystal.h>
LiquidCrystal lcd(0, 3, 4, 5, 6, 7);                      // дисплей подключен порт B PB0,PB3,PB4,PB5,PB6,PB7
char LCD_Row_1[17];                                       //выводит информацию на дисплей из LCD_Row_1
char LCD_Row_2[17];                                       //выводит информацию на дисплей из LCD_Row_2


// ***** Stepper Motor *****
//#define Motor_X_SetPulse()           PORTC &= ~(1<<2)     // PC1
//#define Motor_X_RemovePulse()        PORTC |= (1<<2)      // PC1
//#define Motor_X_Forward()            PORTC |= (1<<3)      // PC2
//#define Motor_X_Reverse()            PORTC &= ~(1<<3)     // PC2
//#define Motor_X_Enable()             PORTC |= (1<<4)      // PC3
//#define Motor_X_Disable()            PORTC &= ~(1<<4)     // PC3
boolean Step_On_flag = false;                             // Флаг разрешаем/запрещаем счет до "шагать"
boolean Mode_On_flag = false;                             // Флаг On/Off режим
#define Feed_Info
#define Feed_Step



// ***** Taho *****
#define TahoSetPulse()              
#define TahoRemovePulse()  

// ***** Encoder *****
#define Enc_Line_per_Revolution       360                          // Кол-во линий энкодера
#define Enc_Line                      Enc_Line_per_Revolution      // Рабочее кол-во тиков
#define Enc_Read()                    (PIND & B00000100)           //подключение пинов энкодера канал А
#define Enc_Read()                    (PIND & B00001000)                   //подключение пинов энкодера канал Б
volatile int Enc_Pos = 0;                                          // Счетчик положения энкодера
int Enc_Pos_tmp = 0;
long Spindle_Angle = 0;
#define Spindle_Direction_CW         0                             // прямое вращение
#define Spindle_Direction_CCW        1                             // обратное вращение
boolean Spindle_Direction = Spindle_Direction_CW;





void setup()
{
  TIMSK = 0;                       // !Отключаем таймер! (он в фоновом режиме обрабатывает не нужные нам функции)
  DDRA=B11111111;                   // включить пины порта
  PORTA = B00000000;                // подтяжка PIN_
  DDRD=B00000011;                    // включить пины порта
  PORTD = B00001100;                // подтяжка PIN_
  GIFR = (1<<INTF0);                //EICRA = B00000001;                // INT_0 по фронту + по спаду
  GICR  |= (1 << INT0);             // Enable INT_0
  DDRC=B00000000;                   // включить пины порта
  PORTC = B11000000;                // подтяжка PIN_
  
  lcd.begin(16, 2);
  
}

void loop()
{
  Enc_Pos_tmp = Enc_Pos;                                                          // ниже будем читать повторно и сравнивать
  if (Enc_Pos == Enc_Pos_tmp)                                                   // Читаем повторно и сравниваем 
  {
    Spindle_Angle = (Enc_Pos*360/(Enc_Line));                                        // Считаем угол
    snprintf(LCD_Row_2, 17, "Ang:%3ld ", Spindle_Angle/1, Spindle_Angle%1);          // Вторая строка для печати
  }

   Print();

  
}
//}
  
//}


//******************************************************************
void Print()
{
lcd.setCursor(0, 0);
lcd.print(LCD_Row_2);

lcd.setCursor(0, 1);
lcd.print(LCD_Row_1);
}

ISR(INT0_vect)
{
   TahoRemovePulse();
     if (!Enc_Read())                                     // Вращение шпинделя вправо
   {
      Spindle_Direction = Spindle_Direction_CW;
      Enc_Pos++;
      if (Enc_Pos == Enc_Line)                          // полный оборот
      {                                           
         Enc_Pos = 0;
         TahoSetPulse();                                // при проходе 0 генерим сигнал Taho
         if (Mode_On_flag == true)                      // проверка режима на ON/OFF, только! после прохода 0 разрешаем счет до к.деления
         {
            Step_On_flag = true;
         }
      }
   } 
   else                                                 // Вращение шпинделя влево
   {
     Spindle_Direction = Spindle_Direction_CCW;
     Enc_Pos--;
     if (Enc_Pos < 0)                                  // полный оборот
     {
     Enc_Pos = Enc_Line - 1;
         TahoSetPulse();                                // при проходе 0 генерим сигнал Taho
         if (Mode_On_flag == true)                      // проверка режима на ON/OFF, только! после прохода 0 разрешаем счет до к.деления
         {
            Step_On_flag = true;
         }

     
     }
  }
}   
 
 
 
                 

Либо Вы что-то не так формулируете, либо это учебник физики за 8 класс: частота = 1/период.

вы вырвали из контекста, в конце я написал прописать функцию, в программе есть переменная TahoSetPulse(); которая генерит импульс полного оборота, я ее хочу прописать через функцию и выдать на лсд через char LCD_Row_1[17]; визуально количество оборотов в минуту, но какие функции я не прописываю ничего не получается и ардуино постоянно ругается

и чего вы ожидаете от этих двух строчек, идущих подряд?

Манипулирования сразу всем портом через присваивание обычно это бред, а если еще и комментарии почитать…

Для этого надо как-то измерять время одного оборота, чего я в вашем коде в упор не вижу. Всех операций с таймером что вы его останавливаете в сетапе… а где измерение?

И еще в коде не все функции определены.

Лично я этот набор слов понять не в состоянии.
Не могли бы Вы попытаться сформулировать свою мысль как-то иначе. И желательно по-русски.

попытаюсь, энкодер подключен 2 каналами А Б к микроконтроллеру, у энкодера 360 импульсов на оборот , контроллер считает импульсы и при прохождении полного оборота при сбросе счета генерируется импульс в переменной , это количество импульсов надо посчитать за 1 секунду или миллисекунду и выдать на дисплей в виде количества оборотов( тахометр) без подсчета через порт, конечно у энкодера есть третий канал Z который и генерит этот импульс можно было подключить к третьему пину и посчитать через прерывания но мне надо это сделать програмно а не апаратно

и где это в коде?

TahoSetPulse(); генерит импульс при прямом вращении и реверсе

уверены? - что-то я не вижу:

после этого кода была прописана функция дергания ногой но я ее убрал, потому что тахометр был подключен отдельно

// ***** Tacho *****
#define TachoPort                    PORTL
#define TachoSetPulse()              TachoPort |= (1<<6)      // Pin43 1
#define TachoRemovePulse()           TachoPort &= ~(1<<6)     // Pin43 0

вот так было

Что-то я уже вообще нить потерял.
Давайте вернемся назад.
Чтобы рассчитать число оборотов в СЕКУНДУ или МИНУТУ - надо посчитать число срабатываний энкодера за интервал времени. Где у вас в коде интервал времени?

в коде его нет я и хочу его прописать от этой переменной :slightly_smiling_face:

Слушайте, вы приносите обрывок кода, где половины функций нет - например кроме уже перечисленных еще Enc_Read(), Print() … и просите обьяснить, почему он не работает?! - вы издеваетесь?

Давайте выкладывайте полный код, который можно вставит в ИДЕ и протестировать. Добавьте в него ваши попытки подсчета оборотов и расскажите, что именно не работает. А так как вы это делаете - это пустая трата времени вашего и моего.

я уже разные функции прописывал , ругается ардуина

сверху полный код который работает в протеусе, считает в прямом и обратном направлении просто я убрал вывод в порт тахометра и все

вы нас тролите?
Где в этом полном коде функция Enc_Read() ? как может “работать код”, если в нем не все функции определены? - он не скомпилируется

могу протеус скинуть и прошивку

так, извиняюсь, Enc_Read() нашел. Только почему их две…

1 лайк

потому что подключено 2 канала А Б прямое и реверс