#include <mega8>
#include <delay>
void main(void)
{
PORTD=0x02;
DDRD=0x01;
while (1) // бесконечній цикл
{
int i;
while (PIND.1 == 0) //условие обработки кнопки
{
for (i=0; i<4; i++)
{ //цикл
PORTD.0=1; //включаем пин порта
delay_ms(200); //задержка
PORTD.0=0; //віключаем пин порта
delay_ms(200); //задержка
};
};
};
}
по поводу первого варианта программы который я писал выше он тоже рабочий просто там кнопка включалась по другому с помощью внешнего подтягивающего резистора.
sheva_s писал(а):А вот Ваш вариант подправленой программы с использованием оператора " if " и нужно ставить оператор while без него работать не будет !!!
Работать будет, но только 1 раз после включения и настолько быстро это время пройдет, что автор не заметит.
Вот у меня опять возник ещё один вопрос, не как не могу сделать счётчик замыкания кнопки. Максимум что удаётся это переменной С присвоить 1. Может надо както сохранять?
#include <mega8>
#include <delay>
void main(void)
{
PORTD=0x02;
DDRD=0x01;
while (1)
{
int i,c;
c=0;
if (PIND.1==0) // считает количество замыканий
{ c++; }
for (i=0; i<c; i++) //цикл индикации,
{ //светодиод мигает столько раз, сколько замкнута кнопка
PORTD.0=1;
delay_ms(200);
PORTD.0=0;
delay_ms(200);
};
}
}
Sounds писал(а):Вот у меня опять возник ещё один вопрос, не как не могу сделать счётчик замыкания кнопки. Максимум что удаётся это переменной С присвоить 1. Может надо както сохранять?
Напиши пожалуста алгоритм работы программы которую ты хочеш сделать, а то немного непонятен вопрос. и что и как у тебя подключено.
Ты по каждому кругу работы программы постоянно обнуляешь переменную С, вот потому и ничего дальше 1 и не идет.
Эти 2 строки что я оставил - вынеси их перед while(1).
#include <mega8>
#include <delay>
void main(void)
{
int c;
PORTD=0x02;
DDRD=0x01;
c=0;
while (1)
{
int i;
while(PIND.1==0) // считает количество замыканий
{ c++;
while(PIND.1==0) {};
delay_ms(60);
};
for (i=0; i<c; i++) //цикл индикации,
{ //светодиод мигает столько раз, сколько замкнута кнопка
PORTD.0=1;
delay_ms(200);
PORTD.0=0;
delay_ms(200);
};
c=0;
}
}
только кнопкой нужно клацать так чтобы между нажатиями незажегся светодиод иначе подсчет будет неверный а вобще тут наверное неверный алгоритм работы задуман
#include <mega8>
#include <delay>
эти строки должны писаться с буквой h
почемуто на форум вылаживаются подругому.
в твоих программах ты не пишиш могут вылазить ошибки покрайней мере у меня непроходит без той буквы.
Алгоритм работы такой клацаеш кнопкой довольно быстро программа подсчитывает нажатия перестаеш клацать она начинает моргать светодиодом.
delay_ms(60);- этой строчка нужно что бы программу удержать в цикле подсчета нажатия в период пока ты отпускаеш и нажимаеш кнопку после этой строчки программа проверяет нажата ли кнопка если да повтаряеться все заново если не нажата она вываливаеться с цикла
while(PIND.1==0) // считает количество замыканий
{ c++;
while(PIND.1==0) {};
delay_ms(50);
};
и переходит на индикацию твоих нажатий после чего обнуляет переменную С и все повторяеться.
Sounds писал(а):Вот у меня опять возник ещё один вопрос, не как не могу сделать счётчик замыкания кнопки.
Для этих целей удобние использовать внешнии прерывания (INT). Тоесть кнопку нажал, основная программа останавливается, и выполняется прерывание, в котором ты увеличуеш переменную на 1, и потом программа начинает работать с места где была остановлена. Очень удобно, попробуйте.
To Krik99
Спасибо за совет, но я пока до этого ещё не дошёл, мне кажется что мне на это не хватает знаний To sheva_s
Это нето.=( To All
А можно как нибудь переменную $C записать в память, и потом её от туда считать?
Sounds, мне кажется, ваши проблемы во многом из-за того, что вы не используете подавление дребезга. Да и возможностями языка Си пользуетесь не в полной мере: советую шире использовать функции - легче станет писать и понимать.
// описываем порт ввода состояния кнопки
#define KEY PIND.1
// описываем порт управления светодиодом
#define LED PORTD.0
char key_pressed(void){
// функция, которая возвращает 0, если кнопка не нажата и не ноль, если нажата
if(KEY) return 0; // если на нужном пине 1 - не нажата
delay_ms(15); // 15 мс задержки для подавления дребезга
if(KEY) return 0; // если на пине 1 - первый раз был дребезг - вернем 0
return 1; // а иначе дребезг кончился и надо вернуть 1
}
void main(void){
// главная функция
DDRD.0 = 1; // настроим линию управления светодиодом
PORTD.1 = 1; // включим подтяжку на кнопку
// основной цикл
while(1){
if( key_pressed() ) LED = !LED; // если нажали кнопку - изменим состояние светодиода
while( key_pressed() ); // поджождем, пока кнопку отпустят
}
}
эта простенькая программка поможет вам освоиться: просто включение-выключение светодиода кнопкой. решайте похожим образом свои задачи - и будет вам щастье
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
#include <mega8>
#include <delay>
unsigned char counter;
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
delay_ms(100);
counter++;
if(counter>9)counter=9; //не даём переменной быть больше 9
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
delay_ms(100);
counter--;
if(counter<0)counter=0; //не даём переменной быть менше 0
}
void main(void){
// Port B initialization
PORTB=0x00;
DDRB=0x00;
// Port C initialization
PORTC=0x7F;
DDRC=0x7F;
// Port D initialization
PORTD=0x00;
DDRD=0x00;
// Инициализация внешних прерываний
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GICR|=0xC0;
MCUCR=0x0A;
GIFR=0xC0;
//разрешаем прерывания
#asm("sei")
while (1)
{
switch(counter){ //выводим то число которое в переменной counter
case 0:{PORTC=0b11000000; break;} //0
case 1:{PORTC=0b11111001; break;} //1
case 2:{PORTC=0b10100100; break;} //2
case 3:{PORTC=0b10110000; break;} //3
case 4:{PORTC=0b10011001; break;} //4
case 5:{PORTC=0b10010010; break;} //5
case 6:{PORTC=0b10000010; break;} //6
case 7:{PORTC=0b11111000; break;} //7
case 8:{PORTC=0b10000000; break;} //8
case 9:{PORTC=0b10010000; break;} //9
}
};
}
ARV писал(а):Krik99, вы уверены, что этот код нормально работает? у меня есть сомнения... и зачем такие громадные задержки в обработчиках прерываний?!
А в чём именно сомнения? Этот код в качестве ознакомления с внешними прерываниями, задержку можно поменять... да знаю, что индикацию цифр можно было записать в массив и выводить от туда, но так уж написал для начинающих. Схему рисовать надеюсь не надо, и думаю выводы к которым подключать кнопки INT0 и INT1 можно найти по даташиту.
PS. Не ленитесь и пользуйтесь генератором начального кода в Code Vision AVR, там довольно таки легко всё железо МК настроить...