роботы робототехника микроконтроллеры


 Страниц (1): [1]   

> Без описания
Azerhud Post Id


Рядовой


Сообщений всего: 2
Дата рег-ции: Авг. 2017  



Всем доброго время суток. Начал учить avr + C. С миганием светодиода и включением через кнопку вроде немного разобрался. Но вот с операторами цикла что то ступор. Задача: На ножках B2 и D2 висят два светодиода. На ножке В1 кнопка. Так вот, мне нужно что б при нажатии кнопки каждый раз включался светодиод на ножке В2 (и это работает), после того как я пять раз нажимаю кнопку должен включится светодиод на ножке D2 (не работает). Пытался передать в цикл for через переменную i состояние из PINB, но что то не получается. Может кто поможет советом и примером.

Мой код:
CODE:
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

//#include <delay.h>
volatile unsigned char i;
volatile unsigned char x;

int main(void)
{
i&=~(1<<PD2);
DDRB|=(1<<PB2); //Настраиваем ножку PB2 в режим выхода
DDRB&=~(1<<PB1); //Настраиваем ножку PB1 в режим входа
PORTB|=(1<<PB1); //Устанавливаем pull-up режим ножки PB1
DDRD|=(1<<PD2);
PORTD|=(1<<PD2);

while(1) //бесконечный цикл
{
if((PINB&(1<<PB1))==0)//Если на PB1 логический ноль
{
PORTB|=(1<<PB2);//Зажигаем светодиод
}
else// если на PB1 логическая единица
{
PORTB&=~(1<<PB2);//Гасим светодиод
}
for (i = 0; i <5 ; i++) // основной цикл
{
PORTD|=(1<<PD2);
}
}
}
 
 Top
ОЛЕГ Супермодератор Post Id



Супермодератор


Сообщений всего: 1732
Дата рег-ции: Нояб. 2008  



Добрый день!
Попробуйте изменить логику своей программы, чтобы включать светодиод по счету, а не по состоянию ножки.
Введите переменную, которая бы изменяла значение по нажатию кнопки, а по превышению нужного Вам значения- обнуляйте ее. И зажигайте светодиод (изменяйте состояние вывода) по нужному значению этой переменной.
Удачи!
 
 Top
Predator Супермодератор Post Id


Супермодератор


Сообщений всего: 1307
Дата рег-ции: Июль 2012  



итак ваша программа работает так:

проверяет состояние ножки B1
если 0 - зажигает светодиод B2
иначе - выключает B2
а потом 5 раз включает D2.

нужно примерно так:
проверяет состояние ножки B1
если 0 - зажигает светодиод B2, считает кол-во нажатий (не цикл, просто i=i+1)
иначе - выключает B2
проверяет кол-во нажатий, если 5 - то включить D2, сбросить кол-во нажатий в 0.

и это еще не всё: у кнопки контакты "дребезжат" - будет по несколько нажатий отрабатываться за одно реальное, но это успеет.
 
 Top
killgur Post Id



Гуру


Сообщений всего: 1189
Дата рег-ции: Февр. 2010  



Насчет задержки от дребезга?, надо сразу ее добавить, иначе он нажмет кнопку и сразу или со второго раза включится d2.

Нужна задержка чтобы успеть отпустить кнопку.

Вообще то по сути программы D2 должна гореть всегда поскольку единица туда загоняется постоянно 5 раз подряд - вывод с портом D, что то не то? не инициализирован до конца?.

какая мега?

(Отредактировано автором: 14 Августа, 2017 - 19:48:14)

 
 Top
Azerhud Post Id


Рядовой


Сообщений всего: 2
Дата рег-ции: Авг. 2017  



Спасибо за отзывы. Никак не смог добиться своего. Пришлось взять код с интернета и немного переделать её. Изначально кнопками менялась скорость горения светодиодов. Я добавил код и теперь при нажатии на любую кнопку на каждый пятый раз включается светодиод. Вот только почему то первое включение происходит на третий раз, остальные правильно. схема на mega8 [img][/img]

CODE:

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>


#define nop() {asm("nop");}

int s = 5000;//переменная для задержки

unsigned int x,i,z;//перечисление переменных

// Функция задержки(пауза)
void delay(int t)
{
for (x=t; x>0 ;x--)
nop ();
}

SIGNAL(SIG_INTERRUPT1)//обработка прерываний INT1
{
cli();//запрещение прерываний на время обработки прерывания
//s = s+5000;//увеличиваем переменную s на 5000
if(z<5){
z=z+1;}
else{
z=1;}
sei();//разрешение прерываний
}

SIGNAL(SIG_INTERRUPT0)//обработка прерываний INT0
{
cli();//запрещение прерываний на время обработки прерывания
//s = s-5000;//уменьшаем переменную s на 5000
if(z<5){
z=z+1;}
else{
z=1;}
sei();//разрешение прерываний
}
int main(void)
{
DDRB = 0xFF; //все вывод
DDRC = 0xFF;
DDRD = 0x00; //все вход

GIMSK=0b11000000; //разрешаем прерывание int0 и int1 - кнопка
MCUCR=0b00001111;// int by rising front - для кнопки 1 и 2

sei();//разрешение прерываний

while (1)//вечный цикл
{
for(i=0; i<8; i++)//цикл
{
PORTB = 0b00000001 << i;//побитовое смещение
delay(s);//задержка

if(z==5){
PORTC &=~ (1<<PC0);
}
else
{
PORTC |=(1<<PC0);

}
}}
}

Прикреплено изображение
01010.jpeg

 
 Top
killgur Post Id



Гуру


Сообщений всего: 1189
Дата рег-ции: Февр. 2010  



не идеально но просто
использован флаг (в реале возможен дребезг, проверено)

видео https://youtu.be/UP9SuvpmRN4

CODE:
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#define max_count 5 //макс. число нажатий чтоб загорелся D2

volatile unsigned char i;
volatile unsigned char flag;


int main(void)
{
DDRB|=(1<<PB2); //Настраиваем ножку PB2 в режим выхода
DDRB&=~(1<<PB1); //Настраиваем ножку PB1 в режим входа
PORTB|=(1<<PB1); //Устанавливаем pull-up режим ножки PB1
DDRD|=(1<<PD2);
PORTD&=~(1<<PD2);


i=0; //начальное значение
flag=0;

while(1) //бесконечный цикл
{
if((PINB&(1<<PB1))==0) //Если на PB1 логический ноль то кнопку нажали
{
PORTB|=(1<<PB2); //Зажигаем светодиод и устанавливаем флаг
flag=1; // поднимаем флаг
if (i==max_count) // проверка "начат новый цикл нажатий?"
{
PORTD&=~(1<<PD2); //гасим светодиод 2 если начат новый цикл нажатий
i=0; // обнуляем счетчик нажатий
}
}
else //Если на PB1 логический единиц то кнопку отпустили
{
PORTB&=~(1<<PB2); //Гасим светодиод 1
if (flag==1) {i++; flag=0;} // если на PB1 логическая единица и установлен флаг то кнопку отпустили увеличиваем счетчик
}
if (i==max_count) {PORTD|=(1<<PD2);} // зажигаем светодиод 2 когда счетчик дошел до max_count нажатий
}
}

(Отредактировано автором: 15 Августа, 2017 - 23:32:47)

 
 Top
Страниц (1): [1]
« С чего начать? »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown
  Яндекс.Метрика   Рейтинг@Mail.ru