Светодиод и кнопка

Модератор: boogyman

Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#21

Сообщение AntonChip »

Вот пример опроса кнопок по таймеру

Код: Выделить всё

volatile unsigned char kod_key;

ISR (TIMER2_OVF_vect)
{
     if (bit_is_clear(PIND, PD0))  kod_key = 1;
else if (bit_is_clear(PIND, PD1))     kod_key = 2;
else if (bit_is_clear(PIND, PD2))   kod_key = 3;
else if (bit_is_clear(PIND, PD3)) kod_key = 4;
else kod_key = 0;
}
настройка таймера

Код: Выделить всё

TCCR2 |= (1 << CS22)|(1 << CS21)|(1 << CS20); // Таймер 2 для опроса клавиатуры раз в 32 мс
TIMSK |= (1 << TOIE2); // разрешение прерывания по переполнению таймера 2
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#22

Сообщение Scroodge »

Всем привет! Подскажите знающие, как решить задачу: при первом нажатии светодиод моргает с одной частотой, при следующем нажатии - частота меняется, при последнем нажатии - выключается? Интересует на си в avr студии. Спасибо!
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#23

Сообщение AntonChip »

Для формирования разных частот можно использовать 16-ти битный таймер, который работает в режиме СТС , где для управления частотой сигнала в регистр ICR1 заносятся предварительно расчитанные значения, сигнал снимается с выхода OC1A.
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#24

Сообщение Scroodge »

А получится без применения таймера? С помощью util_delay? Если можно, пример для светодиода и одной кнопки.
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#25

Сообщение AntonChip »

Самый простой пример

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>    

int main(void)
{
DDRB = 0x00; // Кнопка к PB0
PORTB = 0xFF;
DDRD = 0xFF; // Светодиод к PD0
PORTD = 0x00;	

char s_1 = 0;

while(1)
{
  if((PINB & ( 1 << PB0)) == 0)
   {
    while((PINB & ( 1 << PB0)) == 0){} // Ждем отпускания кнопки
    _delay_ms(10);
    s_1++;
    if(s_1 > 2) s_1 = 0;
   }

if(s_1 == 0)
{
PORTD &= ~(1 << PD0); // Выключаем светодиод
}

if(s_1 == 1)
{
PORTD |= (1 << PD0); // Включаем светодиод
_delay_ms(250); 
PORTD &= ~(1 << PD0); // Выключаем светодиод
_delay_ms(250);
}

if(s_1 == 2)
{
PORTD |= (1 << PD0); // Включаем светодиод
_delay_ms(25); 
PORTD &= ~(1 << PD0); // Выключаем светодиод
_delay_ms(25);
}

}
}
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#26

Сообщение Scroodge »

Спасибо! В протеусе все работает прекрасно. Поясни, пожалуйста: char s_1 = 0 -объявили число s_1 и присвоили ему число 0, правильно? Что потом с ним происходит: s_1++; и почему мы сравниваем s_1 с 0, 1 и 2?
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#27

Сообщение AntonChip »

При инициализации контроллера, т.е. после включения питания переменной s_1 присвоено значение 0, значит светодиод не горит при включении питания.
Этой командой s_1++ к нашей переменной добавляем единицу при каждом отпускании кнопки.
В бесконечном цикле переменную проверяем на значение 0, 1, 2, где уже запускается уже определенный цикл.
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#28

Сообщение Scroodge »

Не могу вкурить, мы ведь в установке на порт D уже подали все 0, потушили светодиод PortD=0x00?
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#29

Сообщение AntonChip »

Scroodge писал(а):Не могу вкурить, мы ведь в установке на порт D уже подали все 0, потушили светодиод PortD=0x00?
Это инициализация, а дальше идет основной цикл
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#30

Сообщение Scroodge »

Спасибо, Антон. Почитаю еще Белова
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#31

Сообщение Scroodge »

Слушай, Антон, а можно в этой же программе добавить:если нажать и удерживать кнопку в любом месте светодиод выключится? Или тут уже без прерываний не обойтись?
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#32

Сообщение AntonChip »

Можно без прерываний сделать
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#33

Сообщение Scroodge »

Подскажи, если не трудно. Хочу в машине регулировать обороты мотора отопителя с помощью программного ШИМа, но знаний пока не хватает, именно по программированию. Спасибо!
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#34

Сообщение AntonChip »

ШИМ это значит все равно использование прерывания по таймеру, если хочешь чтоб все нормально работало. На сайте есть статья "Использование ШИМ", для примера пойдет. А для контроллера мотора я бы посоветовал использовать аппаратный ШИМ. Кстати контроллер печки я делал на attiny13, с переменным резистором, выкладываю код
Вложения
oven_attiny13.rar
Контроллер печки
(39.26 КБ) 2137 скачиваний
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#35

Сообщение Scroodge »

Спасибо, Антон! Такой вопрос относительно твоего кода для мотора отопителя: Каким образом вход РВ2 реагирует на изменение сопротивления?
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#36

Сообщение AntonChip »

Вход PB2 это вход АЦП, в зависимости от того какое напряжение на этом входе меняется скважность ШИМ
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#37

Сообщение Scroodge »

Антон, извини за назойливость, но повторю вопрос: как на 8 меге собрать контроллер отопителя с индикацией из 8 светодиодов. Интересует код в avr studio 6. Спасибо!
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Светодиод и кнопка

#38

Сообщение AntonChip »

Scroodge писал(а):Антон, извини за назойливость, но повторю вопрос: как на 8 меге собрать контроллер отопителя с индикацией из 8 светодиодов. Интересует код в avr studio 6. Спасибо!
Вот пример кода только в AVRStudio4, в шестую переделать не составит особого труда. Код для Atmega8. Все задержки поменять на указанные в скобках или по своему усмотрению, мин. задержки сделал для симуляции в протеусе

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>

unsigned int adc_bufer = 0;

void start_pwm(void)
{
TCCR2 |= (1 << COM21)|(1 << WGM21)|(1 << WGM20)|(1 << CS20); // режим FAST PWM, сброс OC2 при сравнении
PORTB |= (1 << PB1); // включаем светодиод
}

void stop_pwm(void)
{
TCCR2 = 0x00; // выключаем таймер
OCR2 = 0x00;
TCNT2 = 0x00;
PORTB &= ~(1 << PB1); // Выключаем светодиод
}

int main (void) 
{
PORTB = 0x00;
DDRB = 0b00000011; // PB0, PB1 - выход
DDRD = 0xFF;
PORTD = 0x00;
	
ADCSRA |= (1 << ADEN)|(1 << ADPS2)|(1 << ADPS1); // Включаем ADC, предделитель на 64
ADMUX |= (1 << ADLAR)|(1 << MUX0); // Помещаем результат в ADCH, Вход ADC1

ACSR |= (1 << ACD); // Отключаем аналаговый компаратор

stop_pwm(); // Выключаем ШИМ

ADCSRA |= (1 << ADSC); // начало преобразования
while((ADCSRA&(1 << ADIF)) == 0);
{
adc_bufer = ADCH;  // Считываем  ADC в буфер
}

if(adc_bufer > 50)
{
start_pwm();
for(char a=0; a < 32; a++)
{
_delay_ms(2); // 250ms
}
}
else
{
stop_pwm();
}

while(OCR2 < adc_bufer)
{
ADCSRA |= (1 << ADSC); // начало преобразования
while((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования
{
adc_bufer = ADCH;  // Считываем  ADC
}
OCR2++; // Плавный запуск мотора
_delay_ms(1); // 100ms
}	

while(1)
{
ADCSRA |= (1 << ADSC);	//Начинаем преобразование
_delay_ms(1);
while((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования    
{
//adc_bufer = ADCH;  // Считываем  ADC 
OCR2 = ADCH;

if (ADCH > 50)
     PORTD = 0b00000001;          
else
     PORTD = 0b00000000;         
if (ADCH > 75)
	 PORTD = 0b00000011;     
if (ADCH > 100)
	 PORTD = 0b00000111;
if (ADCH > 125)
	 PORTD = 0b00001111;
if (ADCH > 150)
	 PORTD = 0b00011111;
if (ADCH > 175)
	 PORTD = 0b00111111;
if (ADCH > 200)
	 PORTD = 0b01111111;
if (ADCH > 225)
	 PORTD = 0b11111111;
}

if(ADCH > 50)
{
start_pwm();
}
else
{
stop_pwm();
}

if(ADCH > 51)
{
  if(OCR2 < 50)
  OCR2++;
 _delay_ms(100); // 100ms
}
}
}

Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#39

Сообщение Scroodge »

Почему-то в протеусе сразу подает 1 на весь порт D, а на изменение реостата не реагирует никак. Наверное где-то напортачил. Вход АЦП берем ножку PC1, верно?
Аватара пользователя
Scroodge
Любитель
Сообщения: 13
Зарегистрирован: 06 авг 2014, 22:22
Откуда: Астана, Казахстан

Re: Светодиод и кнопка

#40

Сообщение Scroodge »

И почему ты вот эту строчку закомментировал? //adc_bufer = ADCH; // Считываем ADC
Ответить