ura308 Опубликовано 25 февраля, 2016 Поделиться Опубликовано 25 февраля, 2016 Подскажите как реализовать? реверсивный счетчик, энкодер крутит в сторону вычитания до нуля и счетчик останавливается-как сделать чтоб неостанавливалось дальше считало от нуля 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); } } 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 27 февраля, 2016 Поделиться Опубликовано 27 февраля, 2016 и счетчик останавливаетсяВ коде этого нет. Не понятно, из-за чего это у Вас происходит. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
солар Опубликовано 27 февраля, 2016 Поделиться Опубликовано 27 февраля, 2016 Весь код сюда. 0 Я не раздаю удочки. Я продаю рыбу. Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
ura308 Опубликовано 27 февраля, 2016 Автор Поделиться Опубликовано 27 февраля, 2016 (изменено) Только начал осваивать "Си" для 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 Изменено 27 февраля, 2016 пользователем ura308 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 29 февраля, 2016 Поделиться Опубликовано 29 февраля, 2016 case MINUS_ENC: if(lCnt)lCnt-=5; А для чего тут проверка lCnt на нулевой значение ?Оно Вам и вредит. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Starichok Опубликовано 14 декабря, 2017 Поделиться Опубликовано 14 декабря, 2017 надуманная проблема. в какой-то точке есть "0" энкодера. крутим вправо - счетчик увеличивается - получаем положительное число. крутим влево - счетчик уменьшается. при переходе через ноль после декремента получаем число 0xFFFF. это уже ОТРИЦАТЕЛЬНОЕ число и равно -1. ну, и так далее, получаем отрицательные числа. превращаем их в положительные с флагом "минус", и при выводе на индикатор сначала выводим этот минус, потом выводим само положительное число. при выводе положительной координаты флаг "минус", естественно, остается сброшенным, и выводится просто положительное число. для двухбайтового числа имеем максимальное положительное число 32767 и минимальное отрицательное -32768. думаю, такого диапазона координаты должно хватить. 0 Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду. Ссылка на комментарий Поделиться на другие сайты Поделиться
ruhi Опубликовано 20 декабря, 2017 Поделиться Опубликовано 20 декабря, 2017 В 27.02.2016 в 13:28, ura308 сказал: if(EncPrev == StateAB && //если предыдущее состояние StateAB EncCur != EncPrevPrev ) { ... } else if(EncPrev == StateAB && //если предыдущее состояние StateAB EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны, Это что за чудо??? Типа: Если условие не выполнилось (EncPrev == StateAB && EncCur != EncPrevPrev ) , проверим еще раз ничего не меняя, вдруг оно со второго раза выполнится???? Рассчитываете на глюк процессора??? Что вы добавили??? 0 Можно сделать все! Но чем больше можно, тем больше нельзя! Ссылка на комментарий Поделиться на другие сайты Поделиться
Zhuk72 Опубликовано 20 декабря, 2017 Поделиться Опубликовано 20 декабря, 2017 Этой теме скоро 2 года будет. Автор давно либо плюнул на МК, либо решил вопрос. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Darth_Vader Опубликовано 28 декабря, 2017 Поделиться Опубликовано 28 декабря, 2017 Очень сложное решение простой проблемы. Ловим, допустим, передний фронт на INTO (один вывод энкодера) и считываем состояние второго вывода энкодера. Если там 1 - в одну сторону крутится, 0 - гарантированно в другую. //функция обработчик внешнего прерывания INT0 ISR( INT0_vect ) { cw = 0; ccw = 0; if (PIND & (1 << PIND1)) { cw = 1; } else { ccw = 1; } } int main(void) { while(1) if(cw+ccw > 0) { ////////////// cw = 0; ccw = 0; } } } 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Zhuk72 Опубликовано 4 января, 2018 Поделиться Опубликовано 4 января, 2018 (изменено) В 28.12.2017 в 21:57, Darth_Vader сказал: Ловим, допустим, передний фронт на INTO (один вывод энкодера) и считываем состояние второго вывода энкодера. Если там 1 - в одну сторону крутится, 0 - гарантированно в другую. А если энкодер разболтан, его случайно коснулись и он дернул ИНТ0? Засчитаете вращение? Это самый неправильный алгоритм. По таймеру нужно считывать состояние обеих выводов и в случае изменения сравнивать с правильной последовательностью состояний (01001011 или 10000111). Могу выложить подпрограмму опроса, если интересно. Очень небольшая и работает очень стабильно. На выводах энкодера кроме подтяжек ничего фильтрующего не требует. Изменено 4 января, 2018 пользователем Zhuk72 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Darth_Vader Опубликовано 4 января, 2018 Поделиться Опубликовано 4 января, 2018 2 часа назад, Zhuk72 сказал: энкодер разболтан Неисправные детали нужно менять. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Zhuk72 Опубликовано 4 января, 2018 Поделиться Опубликовано 4 января, 2018 А может лучше правильные алгоритмы выбирать? Энкодеры разбалтываются достаточно быстро, даже фирменные. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mazzi Опубликовано 30 января, 2018 Поделиться Опубликовано 30 января, 2018 Хорошие энкодеры работают годами и дребезг граничного положения как правило можно скомпенсировать как программно так и аппаратно. Но если энкодер дешёвый, то при неправильно настроенной оптике могут происходить чудеса. 0 Пока ты жив, надежда есть. Ссылка на комментарий Поделиться на другие сайты Поделиться
ura308 Опубликовано 20 февраля, 2020 Автор Поделиться Опубликовано 20 февраля, 2020 (изменено) Всем привет! Не отвечал по теме так как были утеряны файлы проекта. Возможно кому то и пригодится в своих проектах Код был частично изменен и доработан; 1: Переход через ноль. но без индикации "минус" ( не заморачивался с отриц. показаниями). 2: Была увеличена скорость обработки (энкодер на 400 импульсов). Скорость измерения около 1м в секунду-без пропусков шагов. С индикацией 1или 2 знака после запятой. 3: Вот само решение переход через "0" .Основные изменения в коде; //------------------ cEnc=Encoder_Exe(); if(cEnc != NULL_ENC) { switch(cEnc) // считаем от нуля в обе сторны реверсивно { case PLUS_ENC: if(lCnt == 0 && (signed long)(lCnt + incStep) < 0) incStep *= -1; lCnt+=incStep; break; case MINUS_ENC: if(lCnt == 0 && (signed long)(lCnt - incStep) < 0) incStep *= -1; //на 1имп число на табло 10 десятки мм на табло lCnt-=incStep; break; } fnCalc(lCnt); } } //----------------------------------- Даташит.rar Прошивка.rar схема.rar Счетчик исходник WinAVR-2010.rar Изменено 20 февраля, 2020 пользователем Falconist 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.