Звуковое подтверждение нажатия клавиш на Atmega8
Модератор: boogyman
Звуковое подтверждение нажатия клавиш на Atmega8
Как в программу с подключенной матричной клавиатуры на Atmega8 добавить звуковое подтверждение нажатия клавиш? К этой: http://radioparty.ru/index.php/prog-avr ... x-keyboard
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Используется обычный динамик без встроенного генератора, в обработчике прерывания по переполнению таймера 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];
}
}
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Почему-то работает только когда жмёшь на клавишу "1"
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Да, надо добавить buzzer; в другие кнопки так:vehvfycr писал(а):Почему-то работает только когда жмёшь на клавишу "1"
Код: Выделить всё
if(scan_key()==1) // Выводим значение нажатой кнопки на индикатор
{
buzzer; // Сигнал буззера
PORTD = num[1];
}
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Спасибо! Ура, заработало.
Re: Звуковое подтверждение нажатия клавиш на Atmega8
А как сделать, чтобы был прерывистый сигнал типа пи-пи-пи...?
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Я хотел спросить: Как сделать одиночный сигнал при нажатии? Где меняется длительность?
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Sergey F писал(а):А как сделать, чтобы был прерывистый сигнал типа пи-пи-пи...?
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Добавил немного строк чтоб менялась длительность сигнала буззера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];
}
}
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Сделал на всех цифрах одинаково. Почему-то цифры 1,2,3 только работают. Не могу понять почему. Может потому, что идёт опрос портов PB0, PB1, PB2, PB3 и на них не получится?
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Заинтересовали меня ребята, скоро напишу программку опрос клавиатуры по таймеру и чтоб с зуммером
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Еще интересует вопрос как сделать так чтобы при нажатии на кнопку 1 прозвучал 1 короткий сигнал, при нажатии на кнопку 2 - 2 коротких сигнала и т.д.
Re: Звуковое подтверждение нажатия клавиш на Atmega8
AntonChip писал(а):Заинтересовали меня ребята, скоро напишу программку опрос клавиатуры по таймеру и чтоб с зуммером
- AntonChip
- Администратор
- Сообщения: 265
- Зарегистрирован: 24 дек 2011, 22:11
- Откуда: Киров
- Контактная информация:
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Пришлось написать заново функцию опроса клавиатуры, проверил в железе работает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];
}
}
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Спасибо! Очень понравилась работа устройства.
Re: Звуковое подтверждение нажатия клавиш на Atmega8
Ребята, мучаюсь с подключением матричной клавиатуры на 30 кнопок. 5 строк 6 колонок. Выводы на разных портах и в произвольном порядке. Не подскажете такую библиотеку??