Светодиод и кнопка
Модератор: boogyman
- winston1777
- Новичок
- Сообщения: 1
- Зарегистрирован: 18 май 2014, 14:22
Светодиод и кнопка
Привет всем ! Помогите новичку в написании программы на C в Codevisionavr. Чтобы когда на кнопку нажимая светодиод загорался, еще раз нажимая он погас ?
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Светодиод и кнопка
Светодиод подключен к PB0, кнопка подключена к PD0
Код: Выделить всё
char temp = 0;
while(1)
{
if(PIND.0 == 0} // Проверяем нажатие кнопки
{
while(PIND.0 == 0){}// Ждем отпускания кнопки
temp++;
delay_ms(100);
}
if(temp)
{
PORTB.0 = 1; // зажигаем светодиод
}
if(temp == 0)
{
PORTB.0 = 0; // гасим светодиод
}
if(temp > 1)
{
temp = 0;
}
}
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Светодиод и кнопка
Специально для Рената пример кода синхронного мигания светодиодов, с использованием прерываний от двух таймеров. Кнопки подключены к PC3 - 0, светодиоды к PD3 - 0
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
char s_1 = 0, s_2 = 0, s_3 = 0, s_4 = 0;
volatile char pwm_counter_0, pwm_counter_2;
///////////////////////////////////////////////////////////////////////////
///////////// Обработчик прерывания по переполнению Т0 //////////////
///////////// Индикация включенного состоянии светодиодов, мигание //////
///////////////////////////////////////////////////////////////////////////
ISR (TIMER0_OVF_vect)
{
pwm_counter_0++;
if(pwm_counter_0 > 40)
{
if(s_1)
PORTD &= ~(1 << PD0);
if(s_2)
PORTD &= ~(1 << PD1);
if(s_3)
PORTD &= ~(1 << PD2);
if(s_4)
PORTD &= ~(1 << PD3);
pwm_counter_0 = 0;
}
if(pwm_counter_0 > 20 && s_1)
PORTD |= (1 << PD0);
if(pwm_counter_0 > 20 && s_2)
PORTD |= (1 << PD1);
if(pwm_counter_0 > 20 && s_3)
PORTD |= (1 << PD2);
if(pwm_counter_0 > 20 && s_4)
PORTD |= (1 << PD3);
}
///////////////////////////////////////////////////////////////////////////
///////////// Обработчик прерывания по переполнению Т2 //////////////
///////////// Индикация выключенного состоянии светодиодов //////////////
///////////////////////////////////////////////////////////////////////////
ISR (TIMER2_OVF_vect)
{
pwm_counter_2++;
if(pwm_counter_2 > 40)
{
if(s_1 == 0)
PORTD &= ~(1 << PD0);
if(s_2 == 0)
PORTD &= ~(1 << PD1);
if(s_3 == 0)
PORTD &= ~(1 << PD2);
if(s_4 == 0)
PORTD &= ~(1 << PD3);
pwm_counter_2 = 0;
}
}
///////////////////////////////////////////////////////////////////////////
////// Основная программа ////////////////
///////////////////////////////////////////////////////////////////////////
int main (void)
{
DDRD = 0xFF; // Выход
PORTD = 0x00;
DDRC = 0x00; // Вход
PORTC = 0xFF;
TCCR0 = (1 << CS02); // clkI/O/256 (From prescaler)
TIMSK |= (1 << TOIE0); // разрешение прерывания от таймера
TCCR2 |= (1 << CS21); // clkI/O/8 (From prescaler)
TIMSK |= (1 << TOIE2); // разрешение прерывания от таймера
sei();
while(1)
{
///////////////////////////////////////////////////////////////////////////
///////////// Управление кнопкой 1 //////////////
///////////////////////////////////////////////////////////////////////////
if((PINC & ( 1 << PC0)) == 0)
{
while((PINC & ( 1 << PC0)) == 0){} // Ждем отпускания кнопки
_delay_ms(10);
s_1++;
if(s_1 > 1) s_1 = 0;
}
///////////////////////////////////////////////////////////////////////////
///////////// Управление кнопкой 2 //////////////
///////////////////////////////////////////////////////////////////////////
if((PINC & ( 1 << PC1)) == 0)
{
while((PINC & ( 1 << PC1)) == 0){}
_delay_ms(10);
s_2++;
if(s_2 > 1) s_2 = 0;
}
///////////////////////////////////////////////////////////////////////////
///////////// Управление кнопкой 3 //////////////
///////////////////////////////////////////////////////////////////////////
if((PINC & ( 1 << PC2)) == 0)
{
while((PINC & ( 1 << PC2)) == 0){}
_delay_ms(10);
s_3++;
if(s_3 > 1) s_3 = 0;
}
///////////////////////////////////////////////////////////////////////////
///////////// Управление кнопкой 4 //////////////
///////////////////////////////////////////////////////////////////////////
if((PINC & ( 1 << PC3)) == 0)
{
while((PINC & ( 1 << PC3)) == 0){}
_delay_ms(10);
s_4++;
if(s_4 > 1) s_4 = 0;
}
}
}
Re: Светодиод и кнопка
В общем хотел промоделировать твой код на протеусе, и хотел скомпилировать его. Ругается на <avr/io> на interrupt и на ISR (TIMER0_OVF_vect).
Даже не знаю с какой стороны подойти... SOS...SOS....SOS..
Даже не знаю с какой стороны подойти... SOS...SOS....SOS..
Re: Светодиод и кнопка
#include <mega16.h>
#include <delay.h>
// Declare your global variables here
void main(void)
{
// Port A initialization
PORTA=0x00;
DDRA=0x00;
// Port B initialization
PORTB=0x00;
DDRB=0x00;
// Port C initialization
PORTC=0b11111111;
DDRC=0b11111111;
// Port D initialization
PORTD=0b11111111;
DDRD=0b11111111;
while (1)
{
if (PINA.0==0)
{
PORTC.0=1;
delay_ms(500);
PORTC.0=0;
delay_ms(810000);
PORTC.0=1;
delay_ms(500);
PORTC.0=0;
delay_ms(60000);
}
else if(PINA.1==0)
{
PORTC.1=1;
delay_ms(500);
PORTC.1=0;
delay_ms(810000);
PORTC.1=1;
delay_ms(500);
PORTC.1=0;
delay_ms(60000);
}
else if(PINA.2==0)
{
PORTC.2=1;
delay_ms(500);
PORTC.2=0;
delay_ms(810000);
PORTC.2=1;
delay_ms(500);
PORTC.2=0;
delay_ms(60000);
}
if (PINA.3==0)
{
PORTC.3=1;
delay_ms(500);
PORTC.3=0;
delay_ms(228000);
PORTC.3=1;
delay_ms(500);
PORTC.3=0;
delay_ms(60000);
}
if (PINA.4==0)
{
PORTC.4=1;
delay_ms(500);
PORTC.4=0;
delay_ms(111000);
PORTC.4=1;
delay_ms(500);
PORTC.4=0;
delay_ms(60000);
}
if (PINA.5==0)
{
PORTC.5=1;
delay_ms(500);
PORTC.5=0;
delay_ms(111000);
PORTC.5=1;
delay_ms(500);
PORTC.5=0;
delay_ms(60000);
}
if (PINA.6==0)
{
PORTC.6=1;
delay_ms(500);
PORTC.6=0;
delay_ms(111000);
PORTC.6=1;
delay_ms(500);
PORTC.6=0;
delay_ms(60000);
}
if (PINA.7==0)
{
PORTC.7=1;
delay_ms(500);
PORTC.7=0;
delay_ms(111000);
PORTC.7=1;
delay_ms(500);
PORTC.7=0;
delay_ms(60000);
}
}
}
Вот такой код был у меня, и именно такой нужен. Только чтоб все работало одновременно. А где и как настраивать время с таймером и прерываниями, я не понимаю((((
#include <delay.h>
// Declare your global variables here
void main(void)
{
// Port A initialization
PORTA=0x00;
DDRA=0x00;
// Port B initialization
PORTB=0x00;
DDRB=0x00;
// Port C initialization
PORTC=0b11111111;
DDRC=0b11111111;
// Port D initialization
PORTD=0b11111111;
DDRD=0b11111111;
while (1)
{
if (PINA.0==0)
{
PORTC.0=1;
delay_ms(500);
PORTC.0=0;
delay_ms(810000);
PORTC.0=1;
delay_ms(500);
PORTC.0=0;
delay_ms(60000);
}
else if(PINA.1==0)
{
PORTC.1=1;
delay_ms(500);
PORTC.1=0;
delay_ms(810000);
PORTC.1=1;
delay_ms(500);
PORTC.1=0;
delay_ms(60000);
}
else if(PINA.2==0)
{
PORTC.2=1;
delay_ms(500);
PORTC.2=0;
delay_ms(810000);
PORTC.2=1;
delay_ms(500);
PORTC.2=0;
delay_ms(60000);
}
if (PINA.3==0)
{
PORTC.3=1;
delay_ms(500);
PORTC.3=0;
delay_ms(228000);
PORTC.3=1;
delay_ms(500);
PORTC.3=0;
delay_ms(60000);
}
if (PINA.4==0)
{
PORTC.4=1;
delay_ms(500);
PORTC.4=0;
delay_ms(111000);
PORTC.4=1;
delay_ms(500);
PORTC.4=0;
delay_ms(60000);
}
if (PINA.5==0)
{
PORTC.5=1;
delay_ms(500);
PORTC.5=0;
delay_ms(111000);
PORTC.5=1;
delay_ms(500);
PORTC.5=0;
delay_ms(60000);
}
if (PINA.6==0)
{
PORTC.6=1;
delay_ms(500);
PORTC.6=0;
delay_ms(111000);
PORTC.6=1;
delay_ms(500);
PORTC.6=0;
delay_ms(60000);
}
if (PINA.7==0)
{
PORTC.7=1;
delay_ms(500);
PORTC.7=0;
delay_ms(111000);
PORTC.7=1;
delay_ms(500);
PORTC.7=0;
delay_ms(60000);
}
}
}
Вот такой код был у меня, и именно такой нужен. Только чтоб все работало одновременно. А где и как настраивать время с таймером и прерываниями, я не понимаю((((
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Светодиод и кнопка
А задержки разные между переключениями светодиодов разные, это так и должно быть?
Re: Светодиод и кнопка
Да, на самом деле мне нужен сигнал 0.5 сек. для включения выпрямителей, после включения через определенное время их нужно снова выключить(снова сигнал 0.5 сек.). Для простоты, чтоб наглядно увидеть я поставил светодиоды.
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Светодиод и кнопка
При нажатии и удержании на кнопку должно быть постоянное переключение выхода или одноразовое? Просто не вникну в суть задачи
Re: Светодиод и кнопка
Вот смотри, пришел сигнал с датчика. Когда приходит сигнал с датчика, у меня порт, где стоят кнопки, заземляется через оптрон. То есть кнопка постоянно нажата. В это время начинается цикл. 0.5 секунд сигнал 5 вольт на порте где светодиоды, и снова ноль в течении некоторого времени. Потом снова 0.5 секунд сигнал и в течении минуты снова ноль. Время, как на выходе появилось 5 вольт, исчезло, снова появилось через некоторое время и исчезло примерно равно времени нажатого состояния кнопки. Постоянного переключения быть не должно. Если даже по каким то причинам сигнал исчез с датчика на секунду и снова появился цикл должен работать не обращая на это внимания пока не законцится
Re: Светодиод и кнопка
есть мысли?
Re: Светодиод и кнопка
Антооооон))) Такое возможно вообще? чтоб микроконтроллер выполнял несколько задач одновременно? Я читал про прерывания, и так и не понял, то ли процессор останавливается и выполняет команду, то ли в фоновом режиме выполняет разные команды. И если в моем случае применить прерывания на все 8 кнопок, и если придет сигнал со всех кнопок одновременно, микроконтроллер сможет обработать все команды?
Re: Светодиод и кнопка
http://www.ap-impulse.ru/podklyuchaem-k ... r-shag-12/ вот здесь есть что то подобное, но я не могу написать программу от и до чтоб она скомпилировалась без ошибок((
Re: Светодиод и кнопка
здесь есть кто?((
Re: Светодиод и кнопка
я забыт? или это с прерываниями нельзя сделать? Скажите что нибудь, или я реализую это на 8 МК((
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Светодиод и кнопка
Все 8 кнопок можно опрашивать по прерыванию таймера, например сделать чтобы прерывание было каждые 10мс, а в самом цикле прерывания смотреть какой сигнал будет с кнопок, лог. 0 или лог. 1. Останется свободных еще 2 таймера, а их использовать для синхронного включения выключения нагрузки.
Re: Светодиод и кнопка
Антон, посоветуй литературу, для дебилов)) и может это сделаем как занятие? я думаю что кому то в будущем пригодятся такие знания...
Re: Светодиод и кнопка
Я нашел код программы для 5 кнопок на атмега8
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//////////////////////////////////////////////////////////////////
// Раздел функций
//////////////////////////////////////////////////////////////////
// Функция задержки. Минимальная задержка с кварцем 8MHz, равна около 1 ms
void delay_ms2(unsigned short ms)
{
unsigned short i, j, k;
for (i=0; i<ms; i++) /* цикл формирования временной задержки */
for(j=0; j<185;j++) /* вложенный цикл формирования временной задержки */
k++; /* произвольное действие */
}
// signal handler для внешнего прерывания int0
SIGNAL(SIG_INTERRUPT0)
{
PORTD &= ~_BV(PD1);// Сбросить бит PD1 в "0" = 0V, светодиод выключен , pin=0V
delay_ms2(1000); // Ждем 1 сек.
PORTD |= _BV(PD1); // Установить бит PD1 в "1" = 5V, светодиод включен, pin=1V
}
//////////////////////////////////////////////////////////////////
int main(void) // ОСНОВНАЯ ПРОГРАММА
{
DDRD |= 1<<1; // вывод 1 порта D работает на вывод
PORTD |= _BV(PD1); // инициализировать начальное состояние, установить бит PD1 в "1"
DDRD &= ~(0<<2); // вывод 2 порта D работает на ввод
PORTD |= _BV(PD2); // активизировать подтягивающий резистор
GIMSK = 1<<INT0; // разрешить внешнее прерывание Int0
MCUCR = 1<<ISC01; // сигнал низкого уровня на Int0 вызовет внешнее прерывание
sei(); // разрешить прерывания
for (;;) { } // бесконечный цикл
}
и нифига не понятно что и как делается((
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
//////////////////////////////////////////////////////////////////
// Раздел функций
//////////////////////////////////////////////////////////////////
// Функция задержки. Минимальная задержка с кварцем 8MHz, равна около 1 ms
void delay_ms2(unsigned short ms)
{
unsigned short i, j, k;
for (i=0; i<ms; i++) /* цикл формирования временной задержки */
for(j=0; j<185;j++) /* вложенный цикл формирования временной задержки */
k++; /* произвольное действие */
}
// signal handler для внешнего прерывания int0
SIGNAL(SIG_INTERRUPT0)
{
PORTD &= ~_BV(PD1);// Сбросить бит PD1 в "0" = 0V, светодиод выключен , pin=0V
delay_ms2(1000); // Ждем 1 сек.
PORTD |= _BV(PD1); // Установить бит PD1 в "1" = 5V, светодиод включен, pin=1V
}
//////////////////////////////////////////////////////////////////
int main(void) // ОСНОВНАЯ ПРОГРАММА
{
DDRD |= 1<<1; // вывод 1 порта D работает на вывод
PORTD |= _BV(PD1); // инициализировать начальное состояние, установить бит PD1 в "1"
DDRD &= ~(0<<2); // вывод 2 порта D работает на ввод
PORTD |= _BV(PD2); // активизировать подтягивающий резистор
GIMSK = 1<<INT0; // разрешить внешнее прерывание Int0
MCUCR = 1<<ISC01; // сигнал низкого уровня на Int0 вызовет внешнее прерывание
sei(); // разрешить прерывания
for (;;) { } // бесконечный цикл
}
и нифига не понятно что и как делается((
Re: Светодиод и кнопка
Допустим как мне в этом примере сделать так чтоб при нажатии кнопки на выходе появился сигнал на 0.5 сек. и появился через 14 минут снова на 0.5 сек?
Re: Светодиод и кнопка
где обозначения пинов под кнопки? где обозначение пинов под светодиоды?
Re: Светодиод и кнопка
где настраивается прерывание от кнопки?