flann 0 11 марта, 2008 Опубликовано 11 марта, 2008 · Жалоба Извиняюсь за задержку с ответом - праздники, даже не заходил на форум :) Решить вашу проблему можно, заведя переменную для хранения значения предыдущей нажатой кнопки, следующим образом: unsigned char XX; // переменная которая будет изменяться unsigned char key=0,keyold=0; key=GetButton(); if(key==12){ if(keyold!=12) XX++; }else if(key==13){ if(keyold!=13) XX--; } keyold=key; Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Transon 0 12 марта, 2008 Опубликовано 12 марта, 2008 (изменено) · Жалоба :a14: Это самая лучшая разработка одного человека какую я видел за последнее время. Я сам пытался разработать цифровой осциллограф, но так до конца не доделал, АЦП не заработал (AD9283 100Msps), сделал его только как логический анализатор через LPT порт с частотой дискретизации 48MHz и 8 каналов, потом забросил, щас снова интерес появился, я хочу повторить ваш осциллограф для себя. Аналогов такого осциллографа со схемами я не нашёл. Изменено 12 марта, 2008 пользователем Transon Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 13 марта, 2008 Опубликовано 13 марта, 2008 · Жалоба Спасибо всем ответившим и помогающим.Не надо извиняться, все мы ведь понимаем , что кроме и-нета у каждого есть ещё и личная жизнь, работа и многое другое, так что всё нормально, спасибо, что отозвались. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 13 марта, 2008 Опубликовано 13 марта, 2008 · Жалоба unsigned char XX; // переменная которая будет изменяться unsigned char key=0,keyold=0; key=GetButton(); if(key==12){ if(keyold!=12) XX++; }else if(key==13){ if(keyold!=13) XX--; } keyold=key; тут не совсем так как надо получается, а именно- значение переменной ХХ меняется только один раз, при повторном нажатии на ту же кнопку оно уже не меняется. А нужно , чтобы оно увеличивалось(или уменьшалось) на единицу при каждом нажатии. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 14 марта, 2008 Опубликовано 14 марта, 2008 · Жалоба unsigned char XX; // переменная которая будет изменяться unsigned char key=0,keyold=0; key=GetButton(); if(key==12){ if(keyold!=12) XX++; }else if(key==13){ if(keyold!=13) XX--; } keyold=key; тут не совсем так как надо получается, а именно- значение переменной ХХ меняется только один раз, при повторном нажатии на ту же кнопку оно уже не меняется. А нужно , чтобы оно увеличивалось(или уменьшалось) на единицу при каждом нажатии. Почему же? Все будет ОК если функция GetButton() будет возвращать 0 если не получила никакого кода клавиши. Тогда переменная keyold занулится (в момент отжатия) и при следующем нажатии на ту же кнопку произойдет необходимая операция :) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 15 марта, 2008 Опубликовано 15 марта, 2008 · Жалоба дело в том , что момент отжатия невозможно установить точно, так как он происходит в произвольный момент времени и там ведь ещё целая куча задач выполняется.Плохо то, что я не могу назначить прерывание по изменению состояния порта РА5,в компиляторе такого почему-то не прописано(может его вобще не существует для ПИКа 18Ф4550), хотя в общей доке для компилятора описание имеется.Плёхо, очень плёхо...... Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 15 марта, 2008 Опубликовано 15 марта, 2008 · Жалоба дело в том , что момент отжатия невозможно установить точно, так как он происходит в произвольный момент времени и там ведь ещё целая куча задач выполняется.Плохо то, что я не могу назначить прерывание по изменению состояния порта РА5,в компиляторе такого почему-то не прописано(может его вобще не существует для ПИКа 18Ф4550), хотя в общей доке для компилятора описание имеется.Плёхо, очень плёхо...... Есть 2 выхода: Во первых можно перекинуть с RA5 на одну из ног: RB0, RB1, RB2 - ноги на которых можно настроить прерывания по фронту или по спаду. Либо можно завести внутренний таймер, с периодом переполнения, например 100 мс и настроить прерывание, по переполнению. А уже в прерывании выполнять GetButton(). - появиться гарантированное время между опросами клавы. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 15 марта, 2008 Опубликовано 15 марта, 2008 (изменено) · Жалоба перекидывать ножки на порт РВ как-то не очень хочется, так как с него читаются данные(вдруг какие-нибудь баги полезут и картинка начнёт портиться.А вот второй вариант наверное подойдёт, только вот с прерываниями у меня сложности..... вот перечень прерываний.какие мои дальнейшие действия? ////////////////////////////////////////////////////////////////// INT // Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(), // CLEAR_INTERRUPT(), INTERRUPT_ACTIVE(), // EXT_INT_EDGE() // // Constants used in EXT_INT_EDGE() are: #define L_TO_H 0x40 #define H_TO_L 0 // Constants used in ENABLE/DISABLE_INTERRUPTS() are: #define GLOBAL 0xF2C0 #define INT_RTCC 0xF220 #define INT_TIMER0 0xF220 #define INT_TIMER1 0x9D01 #define INT_TIMER2 0x9D02 #define INT_TIMER3 0xA002 #define INT_EXT 0xF210 #define INT_EXT1 0xF008 #define INT_EXT2 0xF010 #define INT_RB 0xFFF208 #define INT_AD 0x9D40 #define INT_RDA 0x9D20 #define INT_TBE 0x9D10 #define INT_SSP 0x9D08 #define INT_CCP1 0x9D04 #define INT_CCP2 0xA001 #define INT_BUSCOL 0xA008 #define INT_LOWVOLT 0xA004 #define INT_COMP 0xA040 #define INT_EEPROM 0xA010 #define INT_OSCF 0xA080 #define INT_SPP 0x9D80 #define INT_USB 0xA020 #list Изменено 15 марта, 2008 пользователем andreichk Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 15 марта, 2008 Опубликовано 15 марта, 2008 (изменено) · Жалоба Так... насколько я понял компилятор у вас CCS - я с ним не знаком (дружу в основном с C18, PICC18) Ну ничего, бум думать, где-то он у меня валялся... Хреново что реализация прерываний сильно зависит от компилятора, но постараюсь помочь хотябы идеологически) Тактовая частота, насколько я понял - 40 МГц (т.е. 10 MIPS) ? Для начала ссобщите какие остались свободные таймера и использовали ли вы CCP модули? Да, и еще, используется ли у вас в программе на данный момент уже хоть одно прерывание? И на последок - какая сейчас используется длина импульса кодировки. Насколько я понял вы идеологию кодировки не поменяли? Изменено 15 марта, 2008 пользователем Илья Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 15 марта, 2008 Опубликовано 15 марта, 2008 (изменено) · Жалоба частота 40 МГц. ни один из трёх таймеров не задействован, прерывания тоже. ССР также отключены. длительность импульса 4мкс, между импульсами тоже 4 мкс идеология не поменялась, хотя меня долго кто-то уговаривал,но я не поддался..... Изменено 15 марта, 2008 пользователем andreichk Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 16 марта, 2008 Опубликовано 16 марта, 2008 (изменено) · Жалоба Хорошо. Теперь приступим: Возьмем за базу TMR0, у него большой прескалер (на 10 MIPS можно получить до 1.6 с.) ..... //Гдето в инициализации программы в T0CON указываем: as 16 bit timer/counter Internal instruction cycle clock TMR0 prescaler is assigned Prescaler выбираем из следующих соображений: 1:8 - 0.0524288 с 1:16 - 0.1048576 с можно и другие варианты, достаточное значение опредилится опытным путем TMR0H=0; // Зануляем таймер TMR0L=0; TMR0IF=0; //Очищаем флаг TMR0IE=1; //Включаем прерывание по переполнению IPEN=0; //Отключаем приоритет прерываний PEIE=1; //Включаем прерывания перефирии GIE=1; //Включаем глобальный флаг разрешения прерываний TMR0ON=1; //Затем стартуем таймер: ..... Почитал я немного про CSS, походу там обработка прерываний делается так: (для экономии времени на вызов функции лучше тело GetButton перенести сюда, также нужно сделать глобальными переменные key и keyold) ... где- то в программе: int8 key=0,keyold=0; // незнаю, как в CCS но в PICC18 я бы добавил ключевое слово volatile ... //Непосредственно обработчик прерываний #int_timer0 void timer0_isr(void){ TMR0IF=0;// Очистим флаг прерывания key=0; if (!input(TASTE_EN)){//теперь, раз уж мы сюда зашли, придется дождаться начала передачи кода клавиши while(!input(TASTE_EN)); }else{// а если зашли уже в момент передачи кода кнопки то придеться дождаться окончания передачи... while(input(TASTE_EN)); while(!input(TASTE_EN));//а также ждем начало следующей передачи } while(input(TASTE_EN))//пока активно RA5 { while(!input(Code_Out))//ждём фронт { if (!input(TASTE_EN)) break;//проверяем: если передача законилась то выходим } if (!input(TASTE_EN)) break;//проверяем: если передача законилась то выходим while(input(Code_Out));//ждём спад key++; } //по хорошему эту обработку тоже нужно занести сюда: if(key==12){ if(keyold!=12) XX++; //XX тоже должна быть глобальной }else if(key==13){ if(keyold!=13) XX--; } keyold=key; } ... А уже в теле программы можно спокойно, в любой момент, проверять переменную key.... В особо критичных моментах можно будет на время выключать прерывания, например: GIE=0; бла, бла,бла.... GIE=1; Да, и еще - не совсем понял как кодируется "не нажата ни одна клавиша" - по хорошему, нужно чтобы был импульс на TASTE_EN, без импульса на Code_Out Изменено 16 марта, 2008 пользователем Илья Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 16 марта, 2008 Опубликовано 16 марта, 2008 · Жалоба компилятор не хочет это признавать TMR0IF=0;// Очистим флаг прерывания Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 16 марта, 2008 Опубликовано 16 марта, 2008 (изменено) · Жалоба компилятор не хочет это признавать TMR0IF=0;// Очистим флаг прерывания Значит этот бит либо не прописан, либо прописан каким либо другим образом. Вообще-то этот бит принадлежит регистру INTCON. Можно попробывать варианты: INTCON.TMR0IF=0 или INTCONbits.TMR0IF=0. Ну вообще-то вам лучше знать как обращаться к битам регистров в вашем компиляторе. :) На крайняк такой вариант точно проканает: INTCON&=0b11111011; Изменено 16 марта, 2008 пользователем Илья Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andreichk 0 16 марта, 2008 Опубликовано 16 марта, 2008 · Жалоба пробую так его прописать set_timer0(0); // TMR0IF=0;// Очистим флаг прерывания тоже не катит INTCON&=0b11111011; вообще это идиотизм, что эти компиляторописатели подменяют стандартные описания какими-то собственновыдуманными конструкциями, поди разбери, что чем заменяется. Вот что я решил, у меня тут с ПЛИСкой проблемы, вернее с обьеденением некоторых функций, которые я в ней заложил.Поэтому я решил инициализировать ещё 4 пина и напрямую ввести их в ПИК на порты РА0,РА1,РА2,РА3(они у меня ничем не заняты).И тогда я смогу простым нажатием на соотв.кнопку увеличивать-уменьшать значение переменной ХХ.Прошу пока все дальнейие изыскания на эту тему приостановить, сделать паузу и попить пивка напр. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flann 0 16 марта, 2008 Опубликовано 16 марта, 2008 · Жалоба Ну ладно, удачи, все способы полезны - главное, чтобы цель была достигнута. :) П.С. Единственный плюс, помоему, этого CCS - в том, что в нем написана куча библиотек для периферии. А так, IMHO не серьезный компилятор. 8) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться