• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!

ura308

Members
  • Публикации

    2
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

О ura308

  • Звание
    Новенький

Электроника

  • Стаж в электронике
    1-2 года
  • Сфера радиоэлектроники
    радиолюбитель
  1. Только начал осваивать "Си" для AVR Архив с проектом в конце сообщения ( WinAvr 2010,симуляция Proteus 7.на семисегментниках ) Проект с радиокота http://radiokot.ru/f...hp?f=61&t=84965 Вариант с Lcd16х2 не рассматриваю - некомфортно,нечитабельно с расстояния! только на сегментных индикаторах! Поставил дома на станок в качестве линейки,А он считает реверсивно только в одном направлении - если при резе дошел до "0" то при резе в другом направлении относительно "0" счет не происходит. Толку от него ровным счетом ноль! У заводского на другой оси все в порядке! у него энкодер имеет выходы A ,B и Z-изменение направления. У меня стоит обычный оптический 200 импульсов энкодер A и B выходы. Нужно чтобы при изменении направления вращения энкодера относительно "0" (допустим после первого импульса ) -инверсировался опрос энкодера так, что бы счетчик считал как и считал ранее а минус высвечивался в зависимости он направления счета относительно "0" Вывод на индикацию через 74HC595 чтобы освободить ножки для вывода "индикации - (Минус)" Неплохо бы было и делитель добавить чтоб убрать погрешность (количество импульсов на 1мм) Довести проект "до ума" Таких проектов в интернете просто нет! Я думаю он многим будет полезен! сам код опроса энкодера : //! Файл : button_enc.h //!************************************************** #include "button_enc.h" #include "hard_config.h" //----------------------------- Константы: ----------------------------------- enum { State0, StateA, StateB, StateAB }; //состояния энкодера //----------------------------- Переменные: ---------------------------------- static char EncPrev; //предыдущее состояние энкодера static char EncPrevPrev; //пред-предыдущее состояние энкодера //----------------------- Инициализация энкодера: ---------------------------- void Encoder_Init(void) { EncPrev = State0; //инициализация предыдущего состояния EncPrevPrev = State0; //инициализация пред-предыдущего состояния PORTA=0xFF; } //------------------------- Обработка энкодера: ------------------------------ REZ_ENC Encoder_Exe(void) { char EncCur = 0; char cRezEnc=NULL_ENC; if(!Pin_ENC_F1) {EncCur = StateA;} //опрос фазы 1 энкодера if(!Pin_ENC_F2) {EncCur |= StateB;} //опрос фазы 2 энкодера if(EncCur != EncPrev) //если состояние изменилось, { if(EncPrev == StateAB && //если предыдущее состояние StateAB EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны, { if(EncCur == StateB) {cRezEnc= MINUS_ENC;} else{ cRezEnc=PLUS_ENC;} } //---------------------------------------------------------------------------------------------------------------- вот когда это дописал считает реверсивно!только в другом направлении вращения Но неправильно( начал пропускать импульсы) а реверсивно в этом направлении вообще почти не считает ( на 200 импульсах в сек) а на 24 считает кое как ( в другом направлении когда считает импульсы не пропускает) как автоматизировать процесс переключения между ними? в зависимости от направления вращения если на табло "0" или сброс в ноль с какой переменной брать результат счетчика - или этот ноль? что подправить чтоб импульсы не пропускал? ------------------------------------------------------------------------------------------------------------------// else if(EncPrev == StateAB && //если предыдущее состояние StateAB EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны, { if(EncCur == StateB) {cRezEnc=PLUS_ENC;} else{ cRezEnc= MINUS_ENC;} } //--------------------------------------------------------------------------------------------------------------------- EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния EncPrev = EncCur; //сохранение предыдущего состояния } return cRezEnc; } главная функция; //!************************************************** //! Файл : main.c //! Авторское право (с) : //! Разработка : urry <urry1@rambler.ru> //! Дата создания : //! Описание //! //!************************************************** #include "hard_config.h" // определяем массив вывода и флаги volatile sFlags_ strFlags; volatile uchar cCalculate[DIGIT]; static unsigned long lCnt; // определение используемых функций -------------- static void fnInit(void); void fnBtEnc(void); void fnLtoA(unsigned long tmp); void fnCalc(unsigned long l); //------------------------------------------------ //========================================= int __attribute__((naked)) main (void) //========================================= { fnInit(); for(; { if(strFlags.bTick) { strFlags.bTick=false; fnBtEnc(); if(BITTST0(PINA,1))// пропадание напряжения ! { fnEepSave(lCnt); // записываемся off: asm("wdr"); goto off;// до сброса питания ничего не делаем } } //end strFlags.bTick asm("wdr"); }// end for }// end main //========================================= //----------------------------------------- static void fnInit(void) { DDRD=0; DDRD|=(1<<R_1)|(1<<R_2)|(1<<R_3)|(1<<R_4)|(1<<R_5); PORTD=0xFF; DDRB=0xFF; // Timer/Counter 0 initialization TCCR0A=0x00; TCCR0B=0x00; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 1 initialization TCCR1A=0x00; TCCR1B=0x01; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization GIMSK=0x00; MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x80; // Universal Serial Interface initialization USICR=0x00; // Analog Comparator initialization ACSR=0x80; asm("wdr"); wdt_enable(WDTO_1S); lCnt=fnEepRead(); fnCalc(lCnt); strFlags.bReady=1; Encoder_Init(); //-------------------------------- sei(); } //------------------------------------ void fnBtEnc(void) { static uchar cButt; static uchar cEnc; //------------------ cButt=fnReadButt(); if(cButt) { lCnt=0; fnCalc(lCnt); } //------------------ cEnc=Encoder_Exe(); if(cEnc != NULL_ENC) { switch(cEnc) { case PLUS_ENC: lCnt+=5; break; case MINUS_ENC: if(lCnt)lCnt-=5; break; } fnCalc(lCnt); } } //------------------------------------ void fnLtoA(unsigned long tmp) { const unsigned long step[DIGIT]={10000,1000,100,10,1}; uchar i,atemp; unsigned long val,temp; char flag=0; val=tmp; for (i=0; i<DIGIT; i++) { if(i==3){flag =1;} temp=step[i]; atemp=0; while(val >= temp) { atemp++; val-=temp; } if((flag) || (atemp)) { cCalculate[i]=atemp; flag=1; } else{cCalculate[i]=10;} } } //------------------------------------ void fnCalc(unsigned long l) { if(l >= 99999){l=0;} fnLtoA(l); strFlags.bReady=1; } //------------------------------------ kot_impuls_metr_05.rar
  2. Подскажите как реализовать? реверсивный счетчик, энкодер крутит в сторону вычитания до нуля и счетчик останавливается-как сделать чтоб неостанавливалось дальше считало от нуля 1,2,3,...реверсивно void fnBtEnc(void) { static uchar cButt; static uchar cEnc; //------------------ cButt=fnReadButt(); if(cButt) { lCnt=0; fnCalc(lCnt); } //------------------ cEnc=Encoder_Exe(); if(cEnc != NULL_ENC) { switch(cEnc) { case PLUS_ENC: lCnt+=1; // энкодер вправо break; case MINUS_ENC: if(lCnt)lCnt-=1; //энкодер влево break; } fnCalc(lCnt); } }