Звуковое подтверждение нажатия клавиш на Atmega8

Модератор: boogyman

Ответить
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Звуковое подтверждение нажатия клавиш на Atmega8

#1

Сообщение vehvfycr »

Как в программу с подключенной матричной клавиатуры на Atmega8 добавить звуковое подтверждение нажатия клавиш? К этой: http://radioparty.ru/index.php/prog-avr ... x-keyboard
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#2

Сообщение AntonChip »

Используется обычный динамик без встроенного генератора, в обработчике прерывания по переполнению таймера 0 получаем меандр на выходе PC0, там же можно менять длительность сигнала

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

/*** Подключение матричной клавиатуры к микроконтроллерам AVR ***/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define buzzer TCCR0 |= (1 << CS01);

// Массив значений для порта вывода
unsigned char key_tab[4] = {0b11111110,
                            0b11111101,
       			    0b11111011,
			    0b11110111};

// Функция опроса клавиатуры
unsigned char scan_key(void)
{

unsigned char key_value = 0;
unsigned char i;

for(i = 0;i < 4;i++)
{
PORTB = key_tab[i]; // выводим лог. 0 в порт вывода
_delay_us(10);

switch (PINB & 0xF0)
{
case 0b11100000:
key_value = 1 + i * 3;
return (key_value);
case 0b11010000:
key_value = 2 + i * 3;
return (key_value);
case 0b10110000:
key_value = 3 + i * 3;
return (key_value);
default:
break;
}
}
return (key_value);
}

// Обработчик прерывания по переполнению Т0(Буззер)
ISR(TIMER0_OVF_vect)
{
static unsigned int w;
	
if(w++ < 100) 
PORTC ^= _BV(PC0);
else
  {
  w = 0;
  TCCR0 = 0;
  }
}

int main(void)
{
// массив цифр для индикатора
unsigned char num[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1)|(1 << PB0); // Порт вывода
DDRB &= ~(1 << PB7)|(1 << PB6)|(1 << PB5)|(1 << PB4); // Порт ввода
PORTB = 0xF0; // Устанавливаем лог. 1 в порт ввода
DDRD = 0xFF; // Выход на индикатор
PORTD = 0x00;
DDRC |= (1 << PC0); // Выход буззера
TIMSK |= (1 << TOIE0); // Разрешение прерывания по переполнению таймера 0

_delay_ms(10);
sei(); // Глобально разрешаем прерывания

while(1)
{
if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
{
buzzer; // Сигнал буззера
PORTD = num[1];
}

if(scan_key()==2)
PORTD = num[2];
if(scan_key()==3)
PORTD = num[3];
if(scan_key()==4)
PORTD = num[4];
if(scan_key()==5)
PORTD = num[5];
if(scan_key()==6)
PORTD = num[6];
if(scan_key()==7)
PORTD = num[7];
if(scan_key()==8)
PORTD = num[8];
if(scan_key()==9)
PORTD = num[9];
if(scan_key()==11)
PORTD = num[0];
}
}

Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#3

Сообщение vehvfycr »

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

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#4

Сообщение AntonChip »

vehvfycr писал(а):Почему-то работает только когда жмёшь на клавишу "1"
Да, надо добавить buzzer; в другие кнопки так:

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

if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
{
buzzer; // Сигнал буззера
PORTD = num[1];
}
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#5

Сообщение vehvfycr »

Спасибо! Ура, заработало.
Аватара пользователя
Sergey F
Любитель
Сообщения: 13
Зарегистрирован: 13 мар 2014, 15:33

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#6

Сообщение Sergey F »

А как сделать, чтобы был прерывистый сигнал типа пи-пи-пи...?
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#7

Сообщение vehvfycr »

Я хотел спросить: Как сделать одиночный сигнал при нажатии? Где меняется длительность?
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#8

Сообщение vehvfycr »

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

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#9

Сообщение AntonChip »

vehvfycr писал(а):Я хотел спросить: Как сделать одиночный сигнал при нажатии? Где меняется длительность?
Добавил немного строк чтоб менялась длительность сигнала буззера

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

/*** Подключение матричной клавиатуры к микроконтроллерам AVR ***/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define buzzer TCCR0 |= (1 << CS01);
volatile unsigned int time;
// Массив значений для порта вывода
unsigned char key_tab[4] = {0b11111110,
                            0b11111101,
       			    0b11111011,
			    0b11110111};

// Функция опроса клавиатуры
unsigned char scan_key(void)
{

unsigned char key_value = 0;
unsigned char i;

for(i = 0;i < 4;i++)
{
PORTB = key_tab[i]; // выводим лог. 0 в порт вывода
_delay_us(10);

switch (PINB & 0xF0)
{
case 0b11100000:
key_value = 1 + i * 3;
return key_value;
case 0b11010000:
key_value = 2 + i * 3;
return key_value;
case 0b10110000:
key_value = 3 + i * 3;
return key_value;
default: time = 0;
break;
}
}
return key_value;
}

// Обработчик прерывания по переполнению Т0(Буззер)
ISR(TIMER0_OVF_vect)
{
static unsigned int w;
time++; // Увеличиваем счетчик сигнала буззера	
if(w++ < 100) // Тут меняем частоту сигнала 
PORTC ^= _BV(PC0);
else
  {
  w = 0;
  TCCR0 = 0; // Останавливаем таймер
  }
}

int main(void)
{
// массив цифр для индикатора
unsigned char num[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1)|(1 << PB0); // Порт вывода
DDRB &= ~(1 << PB7)|(1 << PB6)|(1 << PB5)|(1 << PB4); // Порт ввода
PORTB = 0xF0; // Устанавливаем лог. 1 в порт ввода
DDRD = 0xFF; // Выход на индикатор
PORTD = 0x00;
DDRC |= (1 << PC0); // Выход буззера
TIMSK |= (1 << TOIE0); // Разрешение прерывания по переполнению таймера 0

_delay_ms(10);
sei(); // Глобально разрешаем прерывания

while(1)
{

if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
{
PORTD = num[1];
if(time < 1000) // Пока длительность сигнала буззера меньше 1000
  {
  buzzer; // Сигнал буззера
  }
}

if(scan_key()==2)
PORTD = num[2];
if(scan_key()==3)
PORTD = num[3];
if(scan_key()==4)
PORTD = num[4];
if(scan_key()==5)
PORTD = num[5];
if(scan_key()==6)
PORTD = num[6];
if(scan_key()==7)
PORTD = num[7];
if(scan_key()==8)
PORTD = num[8];
if(scan_key()==9)
PORTD = num[9];
if(scan_key()==11)
PORTD = num[0];
}
}
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#10

Сообщение vehvfycr »

Сделал на всех цифрах одинаково. Почему-то цифры 1,2,3 только работают. Не могу понять почему. Может потому, что идёт опрос портов PB0, PB1, PB2, PB3 и на них не получится?
Аватара пользователя
AntonChip
Администратор
Сообщения: 265
Зарегистрирован: 24 дек 2011, 22:11
Откуда: Киров
Контактная информация:

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#11

Сообщение AntonChip »

Заинтересовали меня ребята, скоро напишу программку опрос клавиатуры по таймеру и чтоб с зуммером
Аватара пользователя
Sergey F
Любитель
Сообщения: 13
Зарегистрирован: 13 мар 2014, 15:33

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#12

Сообщение Sergey F »

Еще интересует вопрос как сделать так чтобы при нажатии на кнопку 1 прозвучал 1 короткий сигнал, при нажатии на кнопку 2 - 2 коротких сигнала и т.д.
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#13

Сообщение vehvfycr »

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

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#14

Сообщение AntonChip »

vehvfycr писал(а):Сделал на всех цифрах одинаково. Почему-то цифры 1,2,3 только работают. Не могу понять почему. Может потому, что идёт опрос портов PB0, PB1, PB2, PB3 и на них не получится?
Пришлось написать заново функцию опроса клавиатуры, проверил в железе работает

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

/*** Подключение матричной клавиатуры к микроконтроллерам AVR ***/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define buzzer TCCR0 |= (1 << CS01);
unsigned char buzzer_flag;

// Массив значений для порта вывода
unsigned char key_tab[4] = 
{
0b11111110,
0b11111101,
0b11111011,
0b11110111
};

// Функция опроса клавиатуры
unsigned char scan_key(void)
{
unsigned char key_value = 0; // Буфер состояния клавиш, если ни одна не нажата равен 0
for(unsigned char i = 0;i < 5;i++)
{
if(i == 0)
{
  PORTB = 0b11111110; // Ноль в 1 строке
  _delay_ms(1);
  switch (PINB & 0x70)
  {
  case 0b01100000: key_value = 1;
  return key_value;
  case 0b01010000: key_value = 2;
  return key_value;
  case 0b00110000: key_value = 3;
  return key_value;
  }
}

if(i == 1)
{
PORTB = 0b11111101; // Ноль в 2 строке
_delay_ms(1);
  switch (PINB & 0x70)
  {
  case 0b01100000: key_value = 4;
  return key_value;
  case 0b01010000: key_value = 5;
  return key_value;
  case 0b00110000: key_value = 6;
  return key_value;
  }
}

if(i == 2)
{
PORTB = 0b11111011; // Ноль в 3 строке
_delay_ms(1);
  switch (PINB & 0x70)
  {
  case 0b01100000: key_value = 7;
  return key_value;
  case 0b01010000: key_value = 8;
  return key_value;
  case 0b00110000: key_value = 9;
  return key_value;
  }
}

if(i == 3)
{
PORTB = 0b11110111; // Ноль в 4 строке
_delay_ms(1);
  switch (PINB & 0x70)
  {
  case 0b01100000: key_value = 10;
  return key_value;
  case 0b01010000: key_value = 11;
  return key_value;
  case 0b00110000: key_value = 12;
  return key_value;
  }
}

if(i == 4)
{
buzzer_flag = 0; // Разрешаем сигнал буззера
}

}
return key_value;
}

// Обработчик прерывания по переполнению Т0(Буззер)
ISR(TIMER0_OVF_vect)
{
static unsigned int buzzer_time;
if(buzzer_time++ < 500) // Тут устанавливаем длительность сигнала буззера(10)
PORTC ^= _BV(PC0); // Переключаем вывод буззера
else
{
buzzer_time = 0; // Обнуляем длительность
TCCR0 = 0; // Останавливаем таймер
}
}

int main(void)
{
// массив цифр для индикатора
unsigned char num[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

DDRB |= (1 << PB3)|(1 << PB2)|(1 << PB1)|(1 << PB0); // Порт вывода
DDRB &= ~(1 << PB7)|(1 << PB6)|(1 << PB5)|(1 << PB4); // Порт ввода
PORTB = 0xF0; // Устанавливаем лог. 1 в порт ввода

DDRD = 0xFF; // Выход на индикатор
PORTD = 0x00;

DDRC |= (1 << PC0); // Выход буззера
PORTC = 0x00;

TIMSK |= (1 << TOIE0); // Разрешение прерывания по переполнению таймера 0

sei(); // Глобально разрешаем прерывания

while(1)
{
if(scan_key() != 0) // Если нажата любая кнопка
{
  if(buzzer_flag == 0) 
  {
  buzzer; // Сигнал буззера
  buzzer_flag = 1; // Запрещаем сигнал буззера
  }
}

if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
PORTD = num[1];
if(scan_key()==2)
PORTD = num[2];
if(scan_key()==3)
PORTD = num[3];
if(scan_key()==4)
PORTD = num[4];
if(scan_key()==5)
PORTD = num[5];
if(scan_key()==6)
PORTD = num[6];
if(scan_key()==7)
PORTD = num[7];
if(scan_key()==8)
PORTD = num[8];
if(scan_key()==9)
PORTD = num[9];
if(scan_key()==11)
PORTD = num[0];
}

}
Аватара пользователя
vehvfycr
Любитель
Сообщения: 11
Зарегистрирован: 29 мар 2015, 21:12

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#15

Сообщение vehvfycr »

Спасибо! Очень понравилась работа устройства.
Аватара пользователя
si4karuk
Новичок
Сообщения: 1
Зарегистрирован: 06 мар 2015, 20:33

Re: Звуковое подтверждение нажатия клавиш на Atmega8

#16

Сообщение si4karuk »

Ребята, мучаюсь с подключением матричной клавиатуры на 30 кнопок. 5 строк 6 колонок. Выводы на разных портах и в произвольном порядке. Не подскажете такую библиотеку??
Ответить