roboforum.ru

Технический форум по робототехнике.

Помогите разобраться

Помогите разобраться

Perdimonocle » 29 мар 2012, 05:37

А у меня такая проблема - решил попользовать две такие кнопки Изображение
По инструкции (http://domko.ru/pdf/DFROBOT/DFR0029.pdf) всё просто...
Под WinAVR написал проверочный код - две кнопки + 2 светодиода - по нажатию определённой кнопки зажигается определённый светодиод:
Код: Выделить всёРазвернуть
#define F_CPU 12000000UL  // указываем частоту в герцах
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

unsigned char StatusKey=0;

int main(void) // начало основной программы
{

// к порту B подключена кнопка, а к порту D - светодиод

DDRB = 0x00; // все выводы порта B сконфигурировать как входы
DDRD = 0xFF; // все выводы порта D сконфигурировать как выходы

PORTB &= ~_BV(PB0);    // установить "0" (низкий уровень) на выводе PB0
PORTB &= ~_BV(PB1);    // установить "0" (низкий уровень) на выводе PB1
PORTD &= ~_BV(PD5);   // установить "0" (низкий уровень) на выводе PD5 // светодиод не горит
PORTD &= ~_BV(PD6);   // установить "0" (низкий уровень) на выводе PD6 // светодиод не горит

while (1) // Начало бесконечного цикла
{

// Обработка нажатия кнопки
_delay_ms(1000); // Пауза на 0.01 сек

// Кнопка подключена к PB0. Светодиод подключен к PD5.
if((PINB = 0b11111110) && (StatusKey==0))
   {
   PORTD |= _BV(PD5); // установить "1" (высокий уровень) на выводе PD5
   StatusKey=1;
   }

else // Кнопка подключена к PB1. Светодиод подключен к PD6.
{
if((PINB = 0b11111101) && ((StatusKey==0) || (StatusKey==1)))
   {
   PORTD |= _BV(PD6); // установить "1" (высокий уровень) на выводе PD6
   StatusKey=2;
   }

else  //Если ни одна кнопка не нажата
   {
   StatusKey=0;
   return 0;
   }
};

} // Конец бесконечного цикла
} // закрывающая скобка основной программы


И... в результате ничего!

Подскажите, пожалуйста, в чём ошибка?

И ещё вопрос вдогонку... "Возясь" с кнопками заметил, что на некоторых пинах МК светодиод не светится ярко, а еле-еле "тлеет"...
Попробовал с другими светодиодами - тоже самое.
А на других портах всё ок!
Что это? Сгоревшие ножки МК?

Добавлено спустя 2 часа 38 минут 7 секунд:
Упростил до одной кнопки и одного светодиода
Код: Выделить всёРазвернуть
#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>

int main(void) // начало основной программы
{

// к порту A0 подключена кнопка, а к порту B0 - светодиод

DDRA = 0x00; // все выводы порта A сконфигурировать как входы
DDRB = 0xFF; // все выводы порта B сконфигурировать как выходы

PORTA = 0X00;
PORTB = 0X00;

while (1) // Начало цикла
{
   _delay_ms(500);
   if(PINA == 0x01) {PORTB = 0X01;};
}; // Конец цикла

} // Конец программы


Но, светодиод загорается не по нажанию кнопки, а после задержки...
Подскажите, пожалуйста, где ошибка в коде?

Re: Помогите разобраться

elmot » 29 мар 2012, 10:36

Эм. _delay_ms(500) - это задержка на полсекунды. В таком алгоритме оно и будет включать со случайной задержкой от 0 до полусекунды.

Re: Помогите разобраться

Perdimonocle » 29 мар 2012, 10:50

elmot писал(а):Эм. _delay_ms(500) - это задержка на полсекунды. В таком алгоритме оно и будет включать со случайной задержкой от 0 до полусекунды.


Подскажите как исправить код, чтобы светодиод загорался по нажатию кнопки.

Re: Помогите разобраться

elmot » 29 мар 2012, 11:39

В первом приближении - задержку уменьшить или совсем убрать

Re: Помогите разобраться

Perdimonocle » 29 мар 2012, 11:59

Проверил, дело не в задержке - светодиод всё-равно загорается без нажатия кнопки.

Кстати, вот код для Ардуино из описания данной кнопки:
Код: Выделить всёРазвернуть
Sample Code
///Arduino Sample Code
///www.DFRobot.com
///Last modified on 16th September 2010
int ledPin = 13; // choose the pin for the LED
int inputPin = 3; // Connect sensor to input pin 3
void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inputPin, INPUT); // declare pushbutton as input
}
void loop(){
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, LOW); // turn LED OFF
} else {
digitalWrite(ledPin, HIGH); // turn LED ON
}

Re: Помогите разобраться

dccharacter » 29 мар 2012, 12:16

if(PINA == 0x01)
откуда ты знаешь, что у тебя на пинах PORTA.1-PORTA.7?
Кнопка у тебя подтянута к питанию?

Re: Помогите разобраться

Perdimonocle » 29 мар 2012, 12:20

Данная кнопка подключается тремя проводами: к ножке МК, к +5В и также на землю.
Здесь есть описание http://domko.ru/pdf/DFROBOT/DFR0029.pdf и код для Ардуино.

Re: Помогите разобраться

dccharacter » 29 мар 2012, 13:13

Но ты же не на ардуино это делаешь?

Re: Помогите разобраться

Perdimonocle » 29 мар 2012, 14:09

Да, не под ардуино, тем не менее кнопка "подтянута" и к "-" и к "+"...

Re: Помогите разобраться

Perdimonocle » 06 апр 2012, 14:44

C вышеуказанными кнопками так и не разобрался... Поставил тактовые.
Код: Выделить всёРазвернуть
#define F_CPU 12000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

int main(void) // начало основной программы
{
// к порту D0 подключена кнопка, а к порту B0 - светодиод
DDRD = 0x00; // все выводы порта D сконфигурировать как входы
DDRB = 0x01; // порт B0 сконфигурировать как выход
PORTD = 0X00; // установить "0" на выводах порта D
PORTB = 0X00; // установить "0" на выводах порта B

while (1) // Начало цикла
{
   _delay_ms(100);
   if(PIND == 0x01) {PORTB = 0X01;}
   else {PORTB = PIND;};
}; // Конец цикла

} // Конец программы

Светодиод, по нажатию кнопки, загорается. Но меня смущает одна странность: если я оставляю else пустым, то есть else {}, то светодиод не горит...

Добавлено спустя 4 минуты 4 секунды:
Тогда для двух кнопок и двух светодиодов получается как-то так:
Код: Выделить всёРазвернуть
int main(void) // начало основной программы
{
// к порту D0 подключена кнопка 1, а к порту B0 - зелёный светодиод
// к порту C0 подключена кнопка 2, а к порту B2 - красный светодиод
DDRD = 0x00; // все выводы порта D сконфигурировать как входы
DDRC = 0x00; // все выводы порта C сконфигурировать как входы
DDRB = 0b00000101; // порт B0 и B2 сконфигурировать как выходы
PORTD = 0X00; // установить "0" на всех выводах порта D
PORTC = 0X00; // установить "0" на всех выводах порта C
PORTB = 0X00; // установить "0" на всех выводах порта B

while (1) // Начало цикла
{
   _delay_ms(100);
   if(PIND == 0x01) {PORTB |= _BV(PB0);}
   else {PORTB = PIND; if(PINC == 0x01) {PORTB |= _BV(PB2);} else {}
   };
}; // Конец цикла
} // Конец программы

И опять же, если из else убрать PORTB = PIND;, то при нажатии кнопки на D0 светодиод на порту B0 не загорается...


Rambler\'s Top100 Mail.ru counter