Код: Выделить всё
#include <mega8.h>
#include <delay.h>
void main(void)
{
PORTD=0x02;
DDRD=0x01;
label0:
while(PIND.1==1)
{
PORTD.0=0;
}
while (1)
{
PORTD.0=1;
delay_ms(10);
while(PIND.1==0)
{goto label0;}
}}
Код: Выделить всё
#include <mega8.h>
#include <delay.h>
void main(void)
{
PORTD=0x02;
DDRD=0x01;
label0:
while(PIND.1==1)
{
PORTD.0=0;
}
while (1)
{
PORTD.0=1;
delay_ms(10);
while(PIND.1==0)
{goto label0;}
}}
просто хочу рассмотреть все способы кроме внешних прерыванийshads писал(а):Не темни... объясни сразу что за причина, по которой нужно использовать именно прерывание...
приведи пример кодом если несложноshads писал(а):Просто - опрос кнопок правильнее делать в регулярном прерывании по таймеру\счетчику
напиши тут пожалуйста,некоторые ветки не для codivision,хотелось бы на этом компилятореshads писал(а):Где то в этих ветках, кроме прочих есть мои примеры...
http://radiokot.ru/forum/viewtopic.php?f=57&t=101520
Блин... я им не пользуюсь, и у меня все для AVRSTUDIO...sirha писал(а):напиши тут пожалуйста,некоторые ветки не для codivision,хотелось бы на этом компилятореshads писал(а):Где то в этих ветках, кроме прочих есть мои примеры...
http://radiokot.ru/forum/viewtopic.php?f=57&t=101520
буду ждать,спасибоshads писал(а): Ну ща попробую установить CV и поправить свою либу...
громоздко(,буду разбираться,а еше как -нибудь можно порощеshads писал(а):![]()
В общем там примерчик управления 8-мю светиками с помощью 4-х кнопок... короткие нажатия - управляют младшими 4-мя светиками, длинные нажатия - управляют старшими 4-мя светиками...
ПАСИБ я сам не специалист еще в программировании поэтому разобраться сразу не смогу,знаю не мало,в прерываниях слаб ещеshads писал(а):Ну ща сделаю для одной кнопки...
буду разбиратьсяshads писал(а):Вот для одной кнопки...
Сложность кажущаяся только в прерывании....
Код: Выделить всё
//анализ состояния кнопки
//если на линии - лог 1, то кнопка не нажата, когда кнопка нажата, то соотв на линии - лог 0.
//вот тут мы и вылавливаем лог 0 на линии, т.е. ждем когда результат сравнения будет противоположный значению TRUE (отрицание !)
if (! (BTN_PIN & BTN_LINE)){
//итак кнопка нажата, и мы инкрементируем счетчик защелки LockCoun, для отсеивания дребезга
//почему (BTN_LOCK_TIME/10), да потому что частота прерываний 100 Гц (т.е. 100 прерываний в секунду)
//а задаем мы время защелки в милисекундах (т.е. 1000 отсчетов в секунду)
//вот вам и разница в 10 раз... поэтому константу задержки и делим на 10...
if (LockCoun < (BTN_LOCK_TIME/10)){
LockCoun++;
//пока защелка не дощитала до значения (BTN_LOCK_TIME/10) - просто выскакиваем
return;
}
//ага... счетчик защелки дотикал, значит можно предварительно отметить, что факт фиксации нажатия свершился
BtnLockBit =1;
//дальше нужно посчитать время удержания кнопки, для того чтобы определить короткое это нажатие или длинное...
if (LongCoun >= (BTN_LONG_TIME/10))
//сюда попадем, если счетчик длительности нажатия уже равен константе длинного нажатия
//а это означает что он еще раньше дотикал до этого состояния,
//и следовательно, все что нужно в связи с этим уже было сделано, соответственно - просто выходим...
return;
//раз мы сюда проскочили, то время удержания пока что меньше чем нужно для фиксации длинного нажатия
//поэтому продолжаем инкремент переменной времени удержания
if (++LongCoun >= (BTN_LONG_TIME/10))
//ух ты... счетчик только что досчитал до значения времени длинного нажатия...
//это и есть момент фиксации длинного нажатия, устанавливаем бит длинного нажатия
BtnFlags |= BTN_LONG;
//ну и дальше мы уже будем выскакивать на идущей раньше строчке if (++LongCoun >= (BTN_LONG_TIME/10))
//до тех пор пока кнопка не отпустится...
}
else{
//клавиша отжата
//если кнопка до этого удерживалась, то нужно опять обработкть счетчик защелки, только в обратном направлении
if (LockCoun){
//начинаем декремент счетчика защелки, чтобы определить - это точно отжатие, или это просто звон некачественной кнопки
LockCoun --;
//защелка еще не обнулилась - возврат
return;
}
//ага... клавиша точно отпущена, смотрим, была ли она до этого определена как нажатая
// (! BtnLockBit) то же самое что (BtnLockBit == 0)
if (! BtnLockBit)
//увы... кнопка до этого не была нажата, поэтому выходим
//это место я назвал "СТАТИЧЕСКИЙ ВОЗВРАТ", т.к. программа именно тут выскакивает в режиме бездействия кнопок
return;
//так, это интересно... раз мы тут, то кнопка была ранее нажата...
if (LongCoun < (BTN_LONG_TIME/10))
//установка бита короткого нажатия
//ЕСЛИ значение счетчика времени удержания меньше чем время необходимое для длинного удержания,
//то значит это было короткое нажатие, соответстенно надо установить флаг короткого нажатия
//т.е. как вы поняли, установка флага короткого нажатия, происходит в момент отпускания кнопки, при условии
//что кнопка удерживалась меньше времени необходимого для фиксации длинного удержания
//ЕСЛИ же значение счетчика было равно времени длинного удержания, то мы обойдем эту строку,
//т.к. в таком случае, флаг длинного удержания кнопки, был уже установлен ранее строкой BtnFlags |= BTN_LONG;
BtnFlags |= BTN_SHRT;
//ну и хвосты подчистить надобно...
//отжатие зафиксировано
BtnLockBit =0;
//сброс счетчика длительности нажатия
LongCoun = 0;
} а я невнимательно посмотрел на назначения битов wgm21 и 20shads писал(а):Режим CTC - это когда счетчик считает от нуля до значения в регистре OCR2...
При совпадении происходит сброс счетчика на 0 и происходит прерывание (если включено).
Счетчик при этом устанавливать не нужно... вообще все автоматом происходит...