Пт окт 13, 2023 08:22:16
//***************************************************************************
//
// Author(s)...: Pashgan http://ChipEnable.Ru
//
// Target(s)...: ATMega8
//
// Compiler....: GNU GCC
//
// Description.: Опрос матричной клавиатуры. Использование конечного автомата.
//
// Data........: 06.03.10
//
//***************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include "keyboard.h"
//отправка символа по usart`у
void USART_SendChar(unsigned char sym)
{
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}
//прерывание таймера Т0 - опрос клавиатуры
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x83;
ScanKeyboard();
}
int main( void )
{
unsigned char key;
//инициализация USART`a
UBRRH = 0;
UBRRL = 51; //скорость обмена 9600 бод при Fcpu = 8MГц
UCSRB = (1<<TXEN); // разр передачи.
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
//инициализация таймера Т0
TIMSK = (1<<TOIE0); //разрешение прерывания по переполнению
TCCR0 = (1<<CS02)|(0<<CS01)|(0<<CS00); //предделитель 256
TCNT0 = 0x83; //прерывания каждые 4 мс
//инициализация портов и переменных
InitKeyboard();
sei();
while(1){
//если зафиксировано нажатие,
//отправить код кнопки в терминал
key = GetKey();
if (key)
USART_SendChar(key);
}
return 0;
}
//***************************************************************************
//
// Author(s)...: Pashgan http://ChipEnable.Ru
//
// Target(s)...: ATMega8
//
// Compiler....: GNU GCC
//
// Description.: Опрос матричной клавиатуры. Использование конечного автомата.
//
// Data........: 06.03.10
//
//***************************************************************************
#ifndef KEYBOARD_H
#define KEYBOARD_H
#include <avr/io.h>
#include <avr/pgmspace.h>
//инициализация портов и внутренних переменных
void InitKeyboard(void);
//сканирование клавиатуры
void ScanKeyboard(void);
//возвращает код нажатой кнопки
unsigned char GetKey(void);
#endif //KEYBOARD_H
#include "keyboard.h"
//хранит текущее состояние автомата
unsigned char keyState;
//хранит код нажатой кнопки
unsigned char keyCode;
//хранит символьное значение нажатой кнопки
unsigned char keyValue;
//флаговая переменная - устанавливается, если кнопка удерживается
unsigned char keyDown;
//флаговая переменная - устанавливается, когда нажата новая кнопка
unsigned char keyNew;
//таблица перекодировки
PROGMEM unsigned char keyTable[][2] = {
{ 0x11, '1'},
{ 0x12, '2'},
{ 0x14, '3'},
{ 0x21, '4'},
{ 0x22, '5'},
{ 0x24, '6'},
{ 0x41, '7'},
{ 0x42, '8'},
{ 0x44, '9'},
{ 0x81, '*'},
{ 0x82, '0'},
{ 0x84, '#'}
};
//прототипы функций используемых автоматом
unsigned char AnyKey(void);
unsigned char SameKey(void);
void ScanKey(void);
unsigned char FindKey(void);
void ClearKey(void);
//инициализация портов, обнуление переменных
void InitKeyboard(void)
{
DDRD |= 0xf0;
PORTD &= 0x0f;
DDRC &= ~0x07;
PORTC &= ~0x07;
keyState = 0;
keyCode = 0;
keyValue = 0;
keyDown = 0;
keyNew = 0;
}
//автомат реализующий опрос клавиатуры, защиту от дребезга
// и распознование нажатой кнопки
void ScanKeyboard(void)
{
switch (keyState){
case 0:
if (AnyKey()) {
ScanKey();
keyState = 1;
}
break;
case 1:
if (SameKey()) {
FindKey();
keyState = 2;
}
else keyState = 0;
break;
case 2:
if (SameKey()){}
else keyState = 3;
break;
case 3:
if (SameKey()) {
keyState = 2;
}
else {
ClearKey();
keyState = 0;
}
break;
default:
break;
}
}
//возвращает true если какая-нибудь кнопка нажата
unsigned char AnyKey(void)
{
PORTD |= 0xf0;
return (PINC & 0x07);
}
// возвращает true если удерживается та же кнопка
//что и в предыдущем цикле опроса
unsigned char SameKey(void)
{
PORTD = (PORTD & 0x0f) | ( keyCode & 0xf0);
return ((PINC & keyCode) & 0x07);
}
//Генерирует нужные сигналы на линиях
//считывает код нажатой кнопки
void ScanKey(void)
{
unsigned char activeRow = (1<<4);
while (activeRow) {
PORTD = (PORTD & 0x0f)|activeRow;
if (PINC & 0x07) {
keyCode = (PINC & 0x07);
keyCode |= (PORTD & 0xf0);
}
activeRow <<= 1;
}
}
// преобразует код кнопки в соответствующий символ
// устанавивает флаги
unsigned char FindKey(void)
{
unsigned char index;
for (index = 0; index < 12; index++) {
if (pgm_read_byte(&keyTable [index][0]) == keyCode) {
keyValue = pgm_read_byte(&keyTable [index][1]);
keyDown = 1;
keyNew = 1;
return 1;
}
}
return 0;
}
//сбрасывает флаг
void ClearKey(void)
{
keyDown = 0;
}
//если зафиксировано нажатие кнопки
//возвращает ее код
unsigned char GetKey(void)
{
if (keyNew){
keyNew = 0;
return keyValue;
}
else
return 0;
}
Пт окт 13, 2023 11:32:36
Пт окт 13, 2023 11:48:00
union
{
unsigned char arr[8];
unsigned long long chislo;
}keys;
Пт окт 13, 2023 16:10:31
Пт окт 13, 2023 16:13:32
Сб окт 14, 2023 19:34:01
// Author(s)...: Pashgan http://ChipEnable.Ru
Сб окт 14, 2023 19:57:31
Сб окт 14, 2023 20:06:34
Вс окт 15, 2023 17:17:04
int main( void )
{
unsigned char key;
char buttons[4]; // массив нажатых кнопок
int k = 0; // счетчик нажатий
int j;
...............
...............
...............
while(1){
//если зафиксировано нажатие,
key = GetKey();
if ((key)&&(key!= '*')){
buttons[k] = key; // сохраняем значение кнопки в массиве
k = k + 1; // увеличиваем счётчик нажатий на 1
}
else if(key == '*')
{
for(j=0; j<4; j++){
USART_SendChar(buttons[j]); //отправить код кнопки в терминал
}}
}
return 0;
}
Вс окт 15, 2023 17:53:43
for(j=0; j<4; j++) ...
for(j=0; j<k; j++) ...
Вс окт 15, 2023 17:57:06
for(j=0; j<4; j++) ...
for(j=0; j<k; j++) ...
Вс окт 15, 2023 18:45:16
Вс окт 15, 2023 19:11:13
//***************************************************************************
//
// Author(s)...: Pashgan http://ChipEnable.Ru
//
// Target(s)...: ATMega8
//
// Compiler....: GNU GCC
//
// Description.: Опрос матричной клавиатуры. Использование конечного автомата.
//
// Data........: 06.03.10
//
//***************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include "keyboard.h"
#include <util/delay.h>
//отправка символа по usart`у
void USART_SendChar(unsigned char sym)
{
while(!(UCSRA & (1<<UDRE)));
UDR = sym;
}
//прерывание таймера Т0 - опрос клавиатуры
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x83;
ScanKeyboard();
}
int main( void )
{
unsigned char key;
char buttons[4]; // массив нажатых кнопок
int k = 0; // счетчик нажатий
int j;
//инициализация USART`a
UBRRH = 0;
UBRRL = 51; //скорость обмена 9600 бод при Fcpu = 8MГц
UCSRB = (1<<TXEN); // разр передачи.
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
//инициализация таймера Т0
TIMSK = (1<<TOIE0); //разрешение прерывания по переполнению
TCCR0 = (1<<CS02)|(0<<CS01)|(0<<CS00); //предделитель 256
TCNT0 = 0x83; //прерывания каждые 4 мс
//инициализация портов и переменных
InitKeyboard();
sei();
while(1)
{
key = GetKey(); //если зафиксировано нажатие,
if ((key)&&(key!= '*')&&(key != '#'))
{
buttons[k] = key; // сохраняем значение кнопки в массиве
k = k + 1; // увеличиваем счётчик нажатий на 1
}
else if(key == '*')
{
for(j=0; j<k; ++j)
{
if(k>5)k=0;
USART_SendChar(buttons[j]); //отправить код кнопки в терминал
}
memset(buttons, '\0', sizeof(buttons) / sizeof(buttons[0]));
}
else if(key == '#')
{
memset(buttons, '\0', sizeof(buttons) / sizeof(buttons[0]));
}
}
return 0;
}
Вс окт 15, 2023 19:31:19
if (k < 3)
{
k++; // увеличиваем счётчик нажатий на 1
}
else
{
// делаем что-то в случае переполнения счётчика, например, обнуляем его
}
if (k < 4)
{
buttons[k] = key; // сохраняем значение кнопки в массиве
}
else
{
// делаем что-то в случае выхода за границы массива
}
if (k > 3)
{
// делаем что-то в случае выхода за границы массива
}
else
{
buttons[k++] = key; // сохраняем значение кнопки в массиве и затем увеличиваем счётчик нажатий на 1
}
++
buttons[0]
k=k+1
k=k+1
buttons[1]
Пн окт 16, 2023 13:57:40
while(1)
{
key = GetKey(); //если зафиксировано нажатие,
if ((key)&&(key!='*'))
{
buttons[k] = key; // сохраняем значение кнопки в массиве
k = k + 1; // увеличиваем счётчик нажатий на 1
}
if(key == '*')
{
if(k<5)
{
for(j=0; j<k; j++)
{
USART_SendChar(buttons[j]); //отправить код кнопки в терминал
}
memset(buttons, '\0', sizeof(buttons) / sizeof(buttons[0])); //очистить массив
k=0; //сбросить счётчик нажатий
}
else // если в массиве больше 4 символов
{
memset(buttons, '\0', sizeof(buttons) / sizeof(buttons[0])); //очистить массив
k=0;//сбросить счётчик нажатий
}
}
}
return 0;
}
Пн окт 16, 2023 14:11:47
Пн окт 16, 2023 15:31:51
Пн окт 16, 2023 15:35:59
Пн окт 16, 2023 15:42:39
Пн окт 16, 2023 15:50:50
while(1)
{
key = GetKey(); //если зафиксировано нажатие,
if (key)
{
if (k > 3)
{
k=0; //сбросить счётчик нажатий
}
if (key!='*')
{
buttons[k++] = key; // сохраняем значение кнопки в массиве и увеличиваем счётчик нажатий на 1
}
else
{
for(j=0; j<k; j++)
{
USART_SendChar(buttons[j]); //отправить код кнопки в терминал
}
}
}
}