Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
12.09.2007, 06:26
|
|
Прописка
Регистрация: 16.04.2004
Сообщений: 201
Сказал спасибо: 337
Сказали Спасибо 6 раз(а) в 6 сообщении(ях)
|
Вот исходник для ПИКа, но на С, думаю разберешься.
Код:
|
#define Key INPUT_B(),1 //Порт RB1, вход с кнопочки
#define KeyReactTime 40 //Время реакции после нажатия кнопки (x*50мс)
short //1-bit
StoreSpeed, //Признак необходимости отработать нажатие кнопки
char //8-bit
IntTMR0Count, //Счетчик количества прерываний по таймеру
KeyTimer, //Число циклов TMR0, в течении которых кнопка была нажата
KeyPressed, //Число достоверных нажатий кнопки (одинарное - тройное)
KeyReactonTimer, //Таймер от начала первого нажатия кнопки
#int_timer0
//Прерывание для отсчета реального времени 1 раз в 50 мсек
void TMR0_Interrupt ()
{
set_timer0 (60); //Это чтобы следующее прерывание произошло через 50 мсек
IntTMR0Count++; //Считаем, циклы таймера
//Считаем число циклов с момента нажатия кнопочки
//если не нажата или дребезг, то обнуляем таймер
if (!bit_test (Key)) KeyTimer++; else KeyTimer=0;
//Если нажата в течении 150 мсек то значит точно нажата
//увеличим число достоверных нажатий, но не более 3-х
if (KeyTimer == 3) {if (KeyPressed ‹ 3) KeyPressed++;}
//Теперь если произошло хоть одно нажатие и таймер реакции стоит, пускаем его
if ((KeyPressed › 0)&(KeyReactonTimer == KeyReactTime)) KeyReactonTimer = 0;
if (KeyReactonTimer ‹ KeyReactTime) KeyReactonTimer++;
if (KeyReactonTimer == KeyReactTime - 1) {StoreSpeed = 1;}
} |
Далее уже в основном цикле реагируем на StoreSpeed = 1, и по завершении действия обнуляем его. Если тебе надо реагировать только на одинарные нажатия, то все будет еще проще. Типа того:
Код:
|
#define Key INPUT_B(),1 //Порт RB1, вход с кнопочки
char //8-bit
KeyTimer; //Число циклов TMR0, в течении которых кнопка была нажата постоянно
short //1-bit
KeyPressed, //Признак достоверного нажатия
#int_timer0
//Прерывание для отсчета реального времени 1 раз в 50 мсек
void TMR0_Interrupt ()
{
set_timer0 (60); //Это чтобы следующее прерывание произошло через 50 мсек
//Считаем число циклов с момента нажатия кнопочки
//если не нажата или дребезг, то обнуляем таймер
if (!bit_test (Key)) KeyTimer++; else KeyTimer=0;
//Если нажата в течении 150 (3 раза по 50)мсек то значит точно нажата
if (KeyTimer == 3) {if (KeyPressed == false) KeyPressed = True;}
} |
В основном цикле пишем
if (KeyPressed == true)
{Делаем то, что надо, а
в конце KeyPressed = false}
|
|
|
|
12.09.2007, 11:53
|
|
Временная регистрация
Регистрация: 01.11.2006
Сообщений: 66
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Цитата:
|
rremix: Не сработало
|
совсем не сработать не могло. Если только дребезг.
Пока кнопку держишь, знчения ведь не меняются?
а против дребезга:
Код:
|
char pressed;
if(PIND.6==0)
{
if (0==pressed)
n=n+1;
pressed = 1;
} else {
pressed = 0;
};
int i;
for (i=0;i‹10000;i++){
asm("nop");//в IAR так. для своего компилера примерь, как NOP ставить
}; |
и кондер на кнопку.
ЗЫ: я полагаю, подтягивающий-то резистор висит? [/code]
|
|
|
|
12.09.2007, 17:37
|
|
Почётный гражданин KAZUS.RU
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
|
rremix
Сам еще не сильно в коде,посижу попыхчу над кодом на асеме,узать бы что записывается в регистрах KbdS ,KbdN,ZumCnt,ZumInit ,ZumCnt? или хоть примерно понять за что отвечают
|
|
|
|
12.09.2007, 18:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
|
Код:
|
clrf PORTB ; очистка порта в
Delay .10 ; Макрос - дает задержку 10 тактов
banksel TRISB ;переходим в банк где TRISB
movlw b'11110111' ;вывод порта 4 на выход
movwf TRISB
banksel PORTB ;банк где PORTB
bsf PORTB,3 ;устанавливаем его
Delay .50
movfw PORTB ;считываем с порта в
andlw 0x07 ;0х07 & portb |
Для чего это? перевод на выход,установка и опрос,если на выводе будет ноль то просто коротнет,потом считываем и логическое И,а зачем потом не опрашиваем же Z
|
|
|
|
12.09.2007, 21:01
|
|
Временная регистрация
Регистрация: 01.11.2006
Сообщений: 66
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Цитата:
|
Для чего это? перевод на выход,установка и опрос,если на выводе будет ноль то просто коротнет,потом считываем и логическое И,а зачем потом не опрашиваем же Z
|
Прошу прощения, не оговорился:
это процедурка изначально предназначалась для матрицы кнопок. при этом часть кода, получающая данные с физики пишется всякий раз для новой схемы. (она несложная - динамический матричный опрос - выставили нолик (еденичку) в столбец и посмотрели, что на входах со строк, подтянутых к еденичке(нолику) соответственно).
Эта прога использовалась для схемы на картинке.
(до сих пор работает на моем маслянном обогревателе с uC-регулированием )))
При некоторой фантазии ее легко дорастить до 8 кнопок, а при чуть больших усилиях:
Код:
|
rrf KbdN,F
bcf KbdN,7
btfsc Carry
bsf KbdN,7 |
превращаем в
Код:
|
rrf KbdN2,F
rrf KbdN,F
bcf KbdN2,7
btfsc Carry
bsf KbdN2,7 |
и для большего числа кнопок. (соответственно увеличиваем счетчик до 16):
Код:
|
movlw 0x08
movwf Int_Tmp |
Цитата:
|
узать бы что записывается в регистрах KbdS ,KbdN,ZumCnt,ZumInit ,ZumCnt? или хоть примерно понять за что отвечают
|
KbdS - KeyBoard State - состояние клавы (фзическое)
KbdN - Состояние новое
ZumCnt - Счетчик опросов дребезг-фильра
ZumInit - Стартовое значение счетчика. Подбирается, в зависимости от частоты опросов клавы. бОльшее значение - задержка на реакцию от кнопок. Меньшее - нефильтрованный дребезг.
-- Прилагается рисунок: --
|
|
|
|
12.09.2007, 23:39
|
|
Временная регистрация
Регистрация: 01.11.2006
Сообщений: 66
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
если кому-то интересно...
я подумал, и решил выложить тот же код, только откоментированный подробно. Сорри, если флуд
Код:
|
ScanKbd
clrf PORTB
Delay .10
banksel TRISB
movlw b'11110111' ; Переключаем вывод стобца на выход, остальные пины - на вход
movwf TRISB
banksel PORTB
bsf PORTB,3 ; ставим еденичку в столбец, т.к.
;строчки потянуты вниз (неявно, через pn переходы индикатора и упр. ключей)
Delay .50 ; ждем сиреневой звезды
movfw PORTB ; читаем с порта состояние строк
andlw 0x07 ; отсекаем маской мусор (всего 3 кнопки)
movwf KbdS ; и записываем в состояние клавы для дребезг-фильтра
banksel TRISB
movlw 0x00
movwf TRISB
banksel PORTB
movfw KbdS ; берем текущее физическое состояние
xorwf KbdN,W ; и сравниваем с последним изменением
btfss Zero
goto SK.CopyNewZ ; если изменилось -
decfsz ZumCnt,F ; если не изменялось - отсчитвыем, сколько опросов оно стабильно
return
movlw ZumInit
movwf ZumCnt
goto SK.Stable ; если счетчик кончился, а состояние не менялось
SK.CopyNewZ
movlw ZumInit ; а если изменилось - считаем дребезгом, сбрасываем счетчик
movwf ZumCnt
movfw KbdS ; и копируем физическое состояние для сравнения
movwf KbdN ; (а вдруг именно оно и окажется стабильным)
return
SK.Stable
movfw KbdN ; сюда попали, только если состояние стабильно (без дребезга)
xorwf KbdO,W ; и сравнили со старым значением
btfsc Zero ; Теперь в W еденички на местах кнопок, состояние которых изменилось
goto SK.NoChange
; Сбрасываем счетчик холда и инит его же
movlw HoldTimeDecCountInit ; Куча регистров предназначена для отсчета времени,
movwf HoldTimeDecCount ; в течении которого наступает событие "кнопка удержана"
movlw HoldInitInit ; а еще это время (HoldInit) можно изменять в программе для, например,
movwf HoldTime ; ускорения приращения значения при длительном удержании
movwf HoldInit
; смотрим, что изменилось
movfw KbdN ; старое состояние никуда не упало - заменяем его на маску изменения состояния
; теперь в KbdO еденички на местах кнопок, состояние которых менялось, а по KbdN мы можем
; судить, в какую сторону.
; в процессе анализа будем циклически поворачивать регистр, т.к. косвенной адресации
; битов не придумали, а прямой анализ не дает гибкости кода. Счетчик цикла покажет,
; какую кнопку сейчас смотрим
xorwf KbdO,F ;- KbdO - установлены измененные кнопки
movlw 0x08
movwf Int_Tmp ; Счетчик цикла. ЗНАЧЕНИЕ СООТВЕТСТВУЕТ РАЗМЕРУ РЕГИСТРА, т.к. при выходе из
; цикла состояние KbdN должно остаться. (тратим время, экономим байт памяти на
; сохранение состояния)
SK.S.Loop
btfss KbdO,0 ; Если ноль - пропускаем. состояние не менялось
goto SK.S.L.Skip
movfw Int_Tmp ; если еденица, берем счетчик в W (он же номер кнопки)
btfss KbdN,0 ; и смотрим, что с ней произошло
call BtnRelease ; отпустилась
btfsc KbdN,0 ; или
call BtnPress ; нажалась
SK.S.L.Skip
rrf KbdO,F ; проворот регистра маски изменения
bcf KbdO,7 ; закольцовка - переносим C в бтарший бит, т.к. является предыду-
btfsc Carry ; щим значением младшего
bsf KbdO,7
rrf KbdN,F ; то-же для состояния
bcf KbdN,7
btfsc Carry
bsf KbdN,7
decfsz Int_Tmp,F
goto SK.S.Loop
; Запоминаем новое состояние как старое
movfw KbdN
movwf KbdO
return
SK.NoChange
decfsz HoldTime,F
return
; Сбрасываем счетчик времени
movfw HoldInit
movwf HoldTime
; Смотрим, нажато ли вообще
movf KbdO,W
btfsc Zero
return
; смотрим, какя(ие) кнопка(ки) удерживаются
; методика та же
movlw 0x08
movwf Int_Tmp
SK.NC.Loop
btfss KbdN,0
goto SK.NC.L.Skip
movfw Int_Tmp
call BtnHold
SK.NC.L.Skip
rrf KbdN,F
bcf KbdN,7
btfsc Carry
bsf KbdN,7
decfsz Int_Tmp,F
goto SK.NC.Loop
return |
|
|
|
|
13.09.2007, 03:32
|
|
Вид на жительство
Регистрация: 27.07.2006
Сообщений: 308
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Мозг отключен. Думаю глазами. Спасибо всем огромное за ответы! Они мне здорово помогли.
Вот итог:
Код:
|
if(PIND.6==0)
{
delay_ms(50);
if(PIND.6==0)
{
delay_ms(50);
n++;
if(n==4)
n=1;
}
else
n=0;
if(n==1)
{
lcd_clear();
delay_ms(300);
lcd_gotoxy(1,0);
lcd_putsf("Clock");
}
else if (n==2)
{
lcd_clear();
delay_ms(300);
lcd_gotoxy(1,0);
lcd_putsf("Temperatura");
}
else if(n==3)
{
lcd_clear();
delay_ms(300);
lcd_gotoxy(1,0);
lcd_putsf("Radiation");
}
delay_ms(50);
} |
|
|
|
|
13.09.2007, 06:15
|
|
Почётный гражданин KAZUS.RU
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
|
retcom
Более менее,но чтоб лучше читалось смещай код при написании вправо после условий и циклов.
rremix
Спасибо посижу поразбираюсь,вопросы будут задам
|
|
|
|
13.09.2007, 08:22
|
|
Почётный гражданин KAZUS.RU
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
|
Не сочти за наглость,но не мог бы ты написать какие у тебя подпрограмы работают:
1)если кнопка была нажата и не изменялась
2)если кнопка нажата была и был дребизг контактов
|
|
|
|
13.09.2007, 11:07
|
|
Временная регистрация
Регистрация: 01.11.2006
Сообщений: 66
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
2 retcom
Цитата:
|
Код:
|
if(PIND.6==0)
{
delay_ms(50);
if(PIND.6==0)
{
delay_ms(50);
n++;
if(n==4)
n=1;
}
else
n=0; |
|
некорректно. Проверь на предмет следующих глюков:
1. При удержании значения будут меняться с интервалом Delay(100) + чуть-чуть
2. при возникновении дребезга (внешнее условие - истина - внутреннее - ложь) счетчик сбросится на 0
2 CERGEI1982
Цитата:
|
какие у тебя подпрограмы работают:
1)если кнопка была нажата и не изменялась
2)если кнопка нажата была и был дребизг контактов
|
1)
Код:
|
SK.NC.Loop
btfss KbdN,0
goto SK.NC.L.Skip
movfw Int_Tmp
call BtnHold |
2)
Код:
|
SK.CopyNewZ
movlw ZumInit ; а если изменилось - считаем дребезгом, сбрасываем счетчик
movwf ZumCnt
movfw KbdS ; и копируем физическое состояние для сравнения
movwf KbdN ; (а вдруг именно оно и окажется стабильным)
return |
Формат таблиц BtnHold, BtnPress, BtnRelease смотри выше.
Заметные нелогичности в коде: если допускать нажатие более 1 кнопки, возникнет ситуация, что пока держишь одну кнопку, и в то же время нажимаешь вторую, эффект по задержкам, как будто перенажал первую (кроме события press) - то есть при использовании ускорения, циферки снова медленней побегут.
Но с этим я предпочел смириться, чтобы не вводить счетчики задержек для каждой кнопки
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
Задержка нажатой кнопки
|
yostaf |
Электроника - это просто |
31 |
15.04.2008 13:37 |
Опрос кнопки
|
Electric111 |
Микроконтроллеры, АЦП, память и т.д |
15 |
18.12.2007 22:48 |
Снова кнопки....
|
dosikus |
Микроконтроллеры, АЦП, память и т.д |
34 |
10.08.2007 20:46 |
Часовой пояс GMT +4, время: 09:55.
|
|