Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту


 
Опции темы

Семисегментный индикатор и клавиатура

Непрочитано 06.05.2016, 21:23  
AlesyaS
Прохожий
 
Аватар для AlesyaS
 
Регистрация: 06.05.2016
Адрес: г. Санкт-Петербург
Сообщений: 9
Сказал спасибо: 5
Сказали Спасибо 1 раз в 1 сообщении
AlesyaS на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от andron007 Посмотреть сообщение
Не думаю что этот кусок кода вам поможет.
Не пойму в чём проблема:
Код:
#include ‹inttypes.h›
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹avr/sleep.h›
#include ‹util/delay.h› 

// Массив значений для порта вывода
unsigned char key_tab[4] = {0xFE, 0xFD, 0xFB, 0xF7};
volatile int display = 0;
unsigned char segcounter = 0; //Переменная 

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

// Функция опроса клавиатуры
unsigned char scan_key(void)
{
   unsigned char key_value = 0;
   unsigned char i;
   
   for(i = 0;i ‹ 4;i++)
      {
	 PORTB = key_tab[i]; // выводим лог. 0 в порт вывода
	 asm("Nop");
	 
   switch (PINB & 0xF0)
	  {
	    case 0b11100000: key_value = 1 + i * 3; break;
	       case 0b11010000: key_value = 2 + i * 3; break;
		  case 0b10110000: key_value = 3 + i * 3; break;
		     default:
		break;
          }
	}
	return (key_value);
}

// Обработчик прерывания по переполнению таймера 2
ISR(TIMER2_OVF_vect)
{   
PORTD = 0xFF; // Гасим все разряды
PORTC = (1 ‹‹ segcounter); // Выбираем следующий разряд
     
switch(segcounter)
{   
case 0:
PORTA = ~(num[display % 10000 / 1000]); // Раскладываем число на разряды
break;
case 1:
PORTA = ~(num[display % 1000 / 100]);
break;  
case 2:
PORTA = ~(num[display % 100 / 10]);
break;      
case 3:
PORTA = ~(num[display % 10]);
break;
}
if(segcounter++ › 2) segcounter = 0; 
}


int main(void)
{
   DDRB |= (1 ‹‹ PB3)|(1 ‹‹ PB2)|(1 ‹‹ PB1)|(1 ‹‹ PB0);  // Порт вывода
   DDRB &= ~(1 ‹‹ PB7)|(1 ‹‹ PB6)|(1 ‹‹ PB5)|(1 ‹‹ PB4); // Порт ввода
   PORTB|= (1 ‹‹ PB3)|(1 ‹‹ PB2)|(1 ‹‹ PB1)|(1 ‹‹ PB0);  // Устанавливаем лог. 1 в порт ввода
   
   DDRC |= (1 ‹‹ PC3)|(1 ‹‹ PC2)|(1 ‹‹ PC1)|(1 ‹‹ PC0);  // Устанавливаем лог. 1 в порт вывода
   PORTC=0xF0;
   
   DDRA = 0xFF;   // Выход на индикатор
   PORTA = 0x3F;  // Отображаем 0 на индикаторе
  
   TCCR2 |= (1 ‹‹ CS21); // Предделитель на 8 
   TIMSK |= (1 ‹‹ TOIE2); // Разрешение прерывания по таймеру 2


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

asm("Nop"); // Небольшая задержка
   
   while(1)
      {
	 // Выводим значение нажатой кнопки на индикатор
	 switch(scan_key()){
	 case 1: PORTA = num[1]; break;
	    case 2: PORTA = num[2]; break;
	       case 3: PORTA = num[3]; break;
		  case 4: PORTA = num[4]; break;
		     case 5: PORTA = num[5]; break;
			case 6: PORTA = num[6]; break;
			   case 7: PORTA = num[7]; break;
			      case 8: PORTA = num[8]; break;
				 case 9: PORTA = num[9]; break;
				    case 11: PORTA = num[0]; break;
				       default:
			break;
       }			       
	  
}
      }
Нажимаю кнопки, на доли секунд появляются цифры в том же виде. Опять что то перепутала
Миниатюры:
Нажмите на изображение для увеличения
Название: 4.JPG
Просмотров: 0
Размер:	42.0 Кб
ID:	92439  
Вложения:
Тип файла: pdf display3.pdf (22.2 Кб, 0 просмотров)
Реклама:

Последний раз редактировалось AlesyaS; 06.05.2016 в 21:26.
AlesyaS вне форума  
Непрочитано 07.05.2016, 01:26  
Alex9797
Почётный гражданин KAZUS.RUN
 
Аватар для Alex9797
 
Регистрация: 20.08.2010
Адрес: Днепр
Сообщений: 8,548
Сказал спасибо: 5,035
Сказали Спасибо 10,605 раз(а) в 3,594 сообщении(ях)
Alex9797 на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от AlesyaS Посмотреть сообщение
Начала учить микроконтроллеры и программирование на Си совсем не давно
А я и вовсе не начинал
Сообщение от AlesyaS Посмотреть сообщение
asm("Nop"); // Небольшая задержка
Если две полоски, даже если они обе косые - это уже не небольшая задержка, а конкретный залет!

Ну, а теперь по теме. Дело в том, что даже кратковременное нажатие кнопки длится достаточно долго, чтобы за это время процессор тысячу раз успел опросить состояние клавиатуры, и выдать столько же раз код нажатой клавиши на индикацию. Поэтому индикатор мгновенно заполняется одинаковыми цифрами. Чтобы этого избежать, надо использовать не "небольшую" задержку в один асмовский ноп, а конкретную, длительностью хотя бы 100...200 миллисекунд.
Алгоритм примерно такой:
1. Опросить состояние клавиатуры
2. Если ни одна клавиша не нажата - возврат на (1)
3. Есть нажатая. Определить код нажатой клавиши
4. Преобразовать код клавиши в 7-сегментный
5. Сдвинуть все цифры в области индикации влево
6. Поместить 7-сегм код новой цифры в самое правое знакоместо
7. А вот теперь - не надо торопиться! Задержка 200 миллисекунд. Чтобы за это время палец успел отпустить нажатую клавишу. Иначе она введется еще раз (или много раз)
8. Возврат на (1)

А динамическая индикация - по прерыванию таймера.
Alex9797 вне форума  
Непрочитано 07.05.2016, 03:32  
omercury
Почётный гражданин KAZUS.RUN
 
Аватар для omercury
 
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
omercury на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Cтудент на нерест попёр - ВЕСНА!
Как бы ещё заметили такое событие?!


Сообщение от Alex9797 Посмотреть сообщение
это уже не небольшая задержка, а конкретный залет!
Это место для точки останова.



Алеся, прежде чем переходить к программе, позвольте указать Вам на одну серьёзную аппаратную ошибку и один недочёт:
1. у Вас отсутствуют в схеме развязывающие диоды на сканере кнопок. В Протеусе, конечно же, ничего фатального не случится, ну разве кроме ошибок в дешифрации кнопок, а вот в реальном устройстве рискуете налететь на выгоревший порт.
2. зачем дополнительно сканировать кнопки, если один сканер у Вас уже есть - сканер разрядов индикации?

Также есть вопрос по алгоритму индикации нажатых кнопок, ибо сюда подходят навскидку 4 варианта...
Распишите, пожалуйста, поподробнее.
omercury вне форума  
Непрочитано 07.05.2016, 08:01  
AlesyaS
Прохожий
 
Аватар для AlesyaS
 
Регистрация: 06.05.2016
Адрес: г. Санкт-Петербург
Сообщений: 9
Сказал спасибо: 5
Сказали Спасибо 1 раз в 1 сообщении
AlesyaS на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от omercury Посмотреть сообщение
, ибо сюда подходят навскидку 4 варианта...
Распишите, пожалуйста, поподробнее.
После подачи на микроконтроллер питания на 7 сегментном 4 разрядном индикаторе высвечивается 0000.
После того как я нажала цифру 1 на матричной клавиатуре на индикаторе 0001.
Затем нажимаю 2 и на индикаторе соответственно 0012.
Затем нажимаю 3 и на индикаторе соответственно 0123.
Затем нажимаю 4 и на индикаторе соответственно 1234.

Потом хочу сделать что бы при нажатии на # индикатор обнулялся снова на 0000, вдруг я набрала не те цифры...

Спасибо за подсказку про диоды.
AlesyaS вне форума  
Непрочитано 07.05.2016, 08:24  
OKF
Прописка
 
Регистрация: 17.11.2009
Сообщений: 134
Сказал спасибо: 15
Сказали Спасибо 30 раз(а) в 16 сообщении(ях)
OKF на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Если извилины прямые, то диоды там не нужны.))
OKF вне форума  
Непрочитано 07.05.2016, 08:49  
Signalshik2
Вид на жительство
 
Аватар для Signalshik2
 
Регистрация: 11.08.2015
Сообщений: 409
Сказал спасибо: 17
Сказали Спасибо 37 раз(а) в 28 сообщении(ях)
Signalshik2 на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Тут надо не код внедрять, а самому писать.

Последний раз редактировалось Signalshik2; 07.05.2016 в 08:58.
Signalshik2 вне форума  
Непрочитано 07.05.2016, 09:32  
Insector
Частый гость
 
Регистрация: 24.11.2006
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Insector на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от AlesyaS Посмотреть сообщение
...
Программирование - учебное заведение или хобби? Я могу примеры дать, но там: модульность, псевдопараллельность процессов, программные таймеры. автоматное программирование. Возможно вам эти термины покажутся страшными и сложными, но на самом деле тут ничего сложного нет. Модульность программ. Программа дробится на модули. Опрос кнопок - отдельный модуль. Вывод на семисегментный дисплей - отдельный модуль. Вывод информации - отдельный модуль.
Псевдопараллельность. Модули, задачи в свою очередь дробятся условиями, флагами, состояниями конечных автоматов. Никаких долгих зацикленностей. Итерация основного цикла должна впаковаться с запасом в системный тик (к примеру 1 мс).
Программные таймеры - аппаратный таймер настраивается на определенное время. Скажем 1 мс. В прерывании переменная-счетчик инкрементируется. Структура программного таймера: статус, счетчик. Подробнее позже распишу.
Конечные автоматы - поисковики.
Почитайте этот цикл статей. Там вы многое почерпнете.

Последний раз редактировалось Insector; 07.05.2016 в 09:53.
Insector вне форума  
Сказали "Спасибо" Insector
AlesyaS (08.05.2016)
Непрочитано 07.05.2016, 12:36  
omercury
Почётный гражданин KAZUS.RUN
 
Аватар для omercury
 
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
omercury на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от OKF Посмотреть сообщение
Если извилины прямые, то диоды там не нужны.))
Если извилины прямые, то уже дебил. Никакие диоды не помогут...


Сообщение от AlesyaS Посмотреть сообщение
После того как я нажала цифру 1 на матричной клавиатуре на индикаторе 0001.
Нажали и отпустили или удерживаете?
Нажимаете вторую, удерживая первую?
Что будет, если одновременно нажаты несколько кнопок?
Ну и так далее, вариантов масса.

Полагаю, что Ваш самый простой - нажал/отпустил.

Давайте по порядку.
1. Клавиатура
Чтоб не заморачиваться постоянным переключением порта В на вход/выход, поставьте диоды на выходы катодами к портам.
Чтобы кнопки работали, нужно в соответствующие входам биты порта В записать "1" и использовать внутреннюю подтяжку к питанию, либо поставить внешние резисторы.
Чтобы исключить ложные и многократные срабатывания нужно фильтровать сканирование кнопок по времени. Неплохо также зафиксировать отпускание предыдущей кнопки перед фиксацией нажатия следующей.
Как МК определяет, которая из строк клавиатуры в данный момент активна? Это про scan_key(), да.
2. Индикация
Динамическая индикация оттого и названа динамической, что в один момент времени может светиться только один индикатор из ряда (тут тоже возможны варианты, например чарлисэмплинг, но пока усложнять не стоит). То же, что и с клавиатурой - как МК определяет, в который разряд в данный момент выводится индикация и что ему туда выводить? У Вас четырёхразрядный индикатор, попробуйте использовать буфер индикатора длиной 4 байта и в каждый разряд выводить свой байт, должно получиться значительно лучше.
3.Логика
Считаем, что здесь пока ничего нет.
4. Говнокод
Вы сами ещё не запутались в своих нулях и единицах? Это ж ужос! Программа абсолютно нечитаема. Например вот это case 0b11100000: Ну и что здесь закодировано? Column_0_pressed будет понятнее, как думаете? Вы совершенно спокойно пользуетесь волатилами, учитесь использовать дефайны и макросы. Вынесите их в отдельную секцию, а ещё лучше в отдельный заголовочный файл, туда же сбросьте и переменные - пусть лежат в одном месте и не мешаются в тексте основной программы. Хорошим тоном будет таким же образом поступать и с самой программой - делить её на функциональные блоки-модули и сохранять и использовать отдельно. Например та же динамическая индикация. Разобрались один раз и начали наполнять свою собственную библиотеку кодов.

Ну пока хватит.

Последний раз редактировалось omercury; 07.05.2016 в 12:41.
omercury вне форума  
Непрочитано 07.05.2016, 12:44  
Insector
Частый гость
 
Регистрация: 24.11.2006
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 4 раз(а) в 4 сообщении(ях)
Insector на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Код:
//==================================================  ======================
#ifndef SEVEN_SEGM_LED_IND_H

#define SEVEN_SEGM_LED_IND_H

#include "seven_segm_led_ind.h"
//==================================================  ======================

//==================================================  ======================
#include "main_def_func.h"
//==================================================  ======================

//==================================================  ======================
#define ANODS_PORT         PORTA
#define ANODS_PIN          PINA
#define ANODS_DDR          DDRA

//#define ANODS_2_PORT       PORTA
//#define ANODS_2_PIN        PINA
//#define ANODS_2_DDR        DDRA

#define KATODS_PORT        PORTC
#define KATODS_PIN         PINC
#define KATODS_DDR         DDRC
//==================================================  ======================

//==================================================  ======================
#define ANOD_1             1‹‹2
#define ANOD_2             1‹‹3
#define ANOD_3             1‹‹4
#define ANOD_4             1‹‹5
#define ANOD_5             1‹‹6
#define ANOD_6             1‹‹7
//------------------------------------------------------------------------
#define A                  1‹‹6
#define B                  1‹‹7 //     A
#define C                  1‹‹3 //   F   B
#define D                  1‹‹2 //     G
#define E                  1‹‹1 //   E   C
#define F                  1‹‹5 //     D
#define G                  1‹‹4
#define H                  1‹‹0
//------------------------------------------------------------------------
#define ZERO               (A | B | C | D | E | F)
#define ONE                (B | C)
#define TWO                (A | B | D | E | G)
#define THREE              (A | B | C | D | G)
#define FOUR               (B | C | F | G)
#define FIVE               (A | C | D | F | G)
#define SIX                (A | C | D | E | F | G)
#define SEVEN              (A | B | C)
#define EIGHT              (A | B | C | D | E | F | G)
#define NINE               (A | B | C | D | F | G)
#define SPACE              0

#define CHAR_SPACE         10
//==================================================  ======================

//==================================================  ======================
#define MAX_LED_INDS       6

#define ANODS_MASK         (ANOD_1 | ANOD_2 | ANOD_3 | ANOD_4 | ANOD_5 | ANOD_6)
#define KATODS_MASK        (A | B | C | D | E | F | G)
//==================================================  ======================

//==================================================  ======================
extern u08 dsp_buf [];

void clr_dsp_buf (void);
//==================================================  ======================

//==================================================  ======================
void _print_val_xxx (u08 x, u08 a);
#define print_val_xxx(x, a) _print_val_xxx(((x)-1), (a))
//==================================================  ======================

//==================================================  ======================
typedef struct index_anods
{
   u08 i;
   u08 anod;
} index_anods;
//==================================================  ======================

//==================================================  ======================
void set_proc_7_segm_ind_on (void);
void set_proc_7_segm_ind_off (void);
void proc_7_segm_ind (void);
//==================================================  ======================

//==================================================  ======================
#endif
//==================================================  ======================
Код:
//==================================================  ======================
#include "seven_segm_led_ind.h"
//==================================================  ======================

//==================================================  ======================
struct index_anods __flash tab_index_anods [] =
{
   {0x01,   ANOD_2},
   {0x02,   ANOD_3},
   {0x03,   ANOD_4},
   {0x04,   ANOD_5},
   {0x05,   ANOD_6},
   {0x00,   ANOD_1},
};

u08 __flash table_7_segm_char [11] =
{
   ZERO,    ONE,
   TWO,     THREE,
   FOUR,    FIVE,
   SIX,     SEVEN,
   EIGHT,   NINE,
   SPACE,
};
//==================================================  ======================

//==================================================  ======================
soft_timer ST_PROC_7_SEGM_IND;
//------------------------------------------------------------------------
u08 dsp_buf [MAX_LED_INDS];
//------------------------------------------------------------------------
// Î÷èñòêà áóôåðà äèñïëåÿ.

u08 dsp_buf [MAX_LED_INDS];

void clr_dsp_buf (void)
{
   for (u08 i = 0; i ‹ MAX_LED_INDS; i++)
      dsp_buf [i] = CHAR_SPACE;
}
//==================================================  ======================

//==================================================  ======================
void _print_val_xxx (u08 x, u08 a) // Âûâîä ÷èñëà â ôîðìàòå xx,x.
{
   char *ptr = num_str_buf + 7;
 
   char_to_str (a);

   dsp_buf[x] = *ptr; // Âûâîä ñîòåí.
   dsp_buf[x++];
   ptr++;

   dsp_buf[x] = *ptr;
   dsp_buf[x++];
   ptr++;

   dsp_buf[x] = *ptr; // Âûâîä åäèíèö.
}
//==================================================  ======================

//==================================================  ======================
static u08 _proc_7_segm_ind;

void set_proc_7_segm_ind_on (void)
{
   _proc_7_segm_ind = 1;
}

void set_proc_7_segm_ind_off (void)
{
   ANODS_DDR = 0;
   ANODS_PORT = 0;
   KATODS_DDR = 0;

   _proc_7_segm_ind = 0;
}

void proc_7_segm_ind (void)
{
   static u08 cnt_7_segm_ind;

   switch (_proc_7_segm_ind)
   {
      case 0:
         break;

      case 1:
         ANODS_DDR = 0xFF;
         cnt_7_segm_ind = 0;
         set_soft_timer (ST_PROC_7_SEGM_IND, 1, 1);
         _proc_7_segm_ind = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_7_SEGM_IND))
         {
            u08 cnt = cnt_7_segm_ind;

            u08 anods;
            u08 katods;

            ANODS_PORT = 0;
            KATODS_DDR = 0;

            cnt_7_segm_ind = tab_index_anods [cnt].i;
            anods = tab_index_anods [cnt].anod;

            katods = table_7_segm_char [dsp_buf [cnt_7_segm_ind]];

            ANODS_PORT = anods;
            KATODS_DDR = katods;
         }
         break;

      default:
         break;
   }
}
//==================================================  ======================
Код:
#ifndef KBD_DRV_H

#define KBD_DRV_H

#include "kbd_drv.h"

#include ‹ioavr.h›

#include "avrlibtypes.h"
#include "macros.h"

#include "main_def_func.h"

#include "sys_timer.h"

//==================================================  ======================
#define DEBOUNCE_DELAY 20
#define HOLD_DELAY 1500
#define REPEAT_DELAY 125
//#define HOLD YES
//==================================================  ======================

//==================================================  ======================
#define TYPE_KEYS MATRIX

#define BUTTONS 0
#define MATRIX  1
//==================================================  ======================

#if (TYPE_KEYS==BUTTONS)
//==================================================  ======================
#define KEYS_PIN           PINA
#define KEYS_DDR           DDRA
#define KEYS_PORT          PORTA
//==================================================  ======================
#define KEYS_DDR_ESC       DDRA
#define KEYS_DDR_ENTER     DDRA
#define KEYS_DDR_UP        DDRA
#define KEYS_DDR_DOWN      DDRA
#define KEYS_DDR_PLUS      DDRA
#define KEYS_DDR_MINUS     DDRA
#define KEYS_DDR_6         DDRA
#define KEYS_DDR_7         DDRA
//------------------------------------------------------------------------
#define KEYS_PORT_ESC      PORTA
#define KEYS_PORT_ENTER    PORTA
#define KEYS_PORT_UP       PORTA
#define KEYS_PORT_DOWN     PORTA
#define KEYS_PORT_PLUS     PORTA
#define KEYS_PORT_MINUS    PORTA
#define KEYS_PORT_6        PORTA
#define KEYS_PORT_7        PORTA
//------------------------------------------------------------------------
#define KEYS_PIN_ESC       PINA
#define KEYS_PIN_ENTER     PINA
#define KEYS_PIN_UP        PINA
#define KEYS_PIN_DOWN      PINA
#define KEYS_PIN_PLUS      PINA
#define KEYS_PIN_MINUS     PINA
#define KEYS_PIN_6         PINA
#define KEYS_PIN_7         PINA
//------------------------------------------------------------------------
#define KEY_ESC_PIN        0
#define KEY_ENTER_PIN      1
#define KEY_UP_PIN         2
#define KEY_DOWN_PIN       3
#define KEY_PLUS_PIN       4
#define KEY_MINUS_PIN      5
//------------------------------------------------------------------------
#define KEY_ESC_BIT        1‹‹KEY_ESC_PIN
#define KEY_ENTER_BIT      1‹‹KEY_ENTER_PIN
#define KEY_UP_BIT         1‹‹KEY_UP_PIN
#define KEY_DOWN_BIT       1‹‹KEY_DOWN_PIN
#define KEY_PLUS_BIT       1‹‹KEY_PLUS_PIN
#define KEY_MINUS_BIT      1‹‹KEY_MINUS_PIN

#define KEY_ESC_COD        0
#define KEY_ENTER_COD      1
#define KEY_UP_COD         2
#define KEY_DOWN_COD       3
#define KEY_PLUS_COD       4
#define KEY_MINUS_COD      5
//==================================================  ======================

//==================================================  ======================
#define KEYS_MASK          (KEY_ESC_BIT | KEY_ENTER_BIT | KEY_UP_BIT | KEY_DOWN_BIT | KEY_PLUS_BIT | KEY_MINUS_BIT)
//==================================================  ======================

#elif (TYPE_KEYS==MATRIX)
//==================================================  ======================
#define COL_DDR            DDRC
#define ROW_DDR            DDRC

#define COL_PIN            PINC
#define ROW_PIN            PINC
//------------------------------------------------------------------------
#define COL_MASK           (1‹‹COL_1)+(1‹‹COL_2)+(1‹‹COL_3)+(1‹‹COL_4)
#define ROW_MASK           (1‹‹ROW_1)+(1‹‹ROW_2)+(1‹‹ROW_3)+(1‹‹ROW_4)
//------------------------------------------------------------------------
/*
// STK-500
#define COL_1              3
#define COL_2              2
#define COL_3              1
#define COL_4              0

#define ROW_1              7
#define ROW_2              6
#define ROW_3              5
#define ROW_4              4
*/

// Плата управления.
#define COL_1              4
#define COL_2              5
#define COL_3              6
#define COL_4              7

#define ROW_1              0
#define ROW_2              1
#define ROW_3              2
#define ROW_4              3
//------------------------------------------------------------------------
#define KEY_ONE            0xEE // 1
#define KEY_TWO            0xED // 2
#define KEY_THREE          0xEB // 3
#define KEY_FOUR           0xDE // 4
#define KEY_FIVE           0xDD // 5
#define KEY_SIX            0xDB // 6
#define KEY_SEVEN          0xBE // 7
#define KEY_EIGHT          0xBD // 8
#define KEY_NINE           0xBB // 8
#define KEY_ZERO           0x7D // 0

#define KEY_A              0xE7 // A
#define KEY_ESC            KEY_A

#define KEY_B              0xD7 // B
#define KEY_ENTER          KEY_B

#define KEY_C              0xB7 // C
#define KEY_PREV           KEY_C

#define KEY_D              0x77 // D
#define KEY_NEXT           KEY_D

#define KEY_STAR           0x7E // *
#define KEY_PLUS           KEY_STAR

#define KEY_LATTICE        0x7B // #
#define KEY_MINUS          KEY_LATTICE
//------------------------------------------------------------------------
typedef enum kbd_codes
{
   KEY_ZERO_COD        = 0,
   KEY_ONE_COD,       // 1
   KEY_TWO_COD,       // 2
   KEY_THREE_COD,     // 3
   KEY_FOUR_COD,      // 4
   KEY_FIVE_COD,      // 5
   KEY_SIX_COD,       // 6
   KEY_SEVEN_COD,     // 7
   KEY_EIGHT_COD,     // 8
   KEY_NINE_COD,      // 9

   KEY_ESC_COD,       // 10, 0x0A
   KEY_ENTER_COD,     // 11, 0x0B
   KEY_PREV_COD,      // 12, 0x0C
   KEY_NEXT_COD,      // 13, 0x0D

   KEY_PLUS_COD,      // 14, 0x0E
   KEY_MINUS_COD,     // 15, 0x0F
} kbd_codes;
//==================================================  ======================
#endif

//==================================================  ======================
//#define KEY1_PRESSED() ((KEYS1_PIN & (1‹‹BIT_KEY1) == 0)
//#define KEY1_UNPRESSED() ((KEYS1_PIN & (1‹‹BIT_KEY1) == 1)
//==================================================  ======================

//==================================================  ======================
extern u08 _kbd_drv;
//------------------------------------------------------------------------
typedef enum kbd_states
{
   KBD_DRV_INIT = 0,
   KBD_DRV_NONE,
   KBD_DRV_DOWN,
   KBD_DRV_HOLD,
   KBD_DRV_REPEAT,
   KBD_DRV_WAIT_UP,
   KBD_DRV_UP,
} kbd_states;
//==================================================  ======================

enum
{
   KEYS_PRESSED_FLG = 0,
};

//extern u08 keys_buf;

void scan_keys (void);

void kbd_drv (void);

extern struct tab_key_cod __flash tab_kbd_drv_keys_cod [];

extern u08 GetKeyCode (void);

#endif
Код:
//==================================================  ======================
#include "kbd_drv.h"
//==================================================  ======================

//==================================================  ======================
u08 _kbd_drv;

static u08 keys_flags;

static u08 keys_prev;
static u08 keys_curr;

static u08 keys_buf;
//==================================================  ======================

#if (TYPE_KEYS==BUTTONS)
//==================================================  ======================
void scan_keys (void)
{
   if (keys_flags & (1‹‹KBD_DRV_RUN_FLG))
   {
      clrb (keys_flags, KEYS_PRESSED_FLG);

      u08 a;

      a = ~KEYS_PIN;
      a &= KEYS_MASK;

      if (a != 0)
      {
         setb (keys_flags, KEYS_PRESSED_FLG);
      }

      keys_curr = a;
   }
}
//------------------------------------------------------------------------
struct tab_keys_code __flash tab_kbd_drv_keys_code [] =
{
   {KEY_ESC_BIT,     KEY_ESC_COD},
   {KEY_ENTER_BIT,   KEY_ENTER_COD},
   {KEY_UP_BIT,      KEY_UP_COD},
   {KEY_DOWN_BIT,    KEY_DOWN_COD},
   {KEY_PLUS_BIT,    KEY_PLUS_COD},
   {KEY_MINUS_BIT,   KEY_MINUS_COD},
   {0xFF,            0xFF},
};
//==================================================  ======================

#elif (TYPE_KEYS==MATRIX)
//==================================================  ======================
void scan_keys (void)
{
   if (_kbd_drv != KBD_DRV_INIT)
   {
      clr_bit (keys_flags, KEYS_PRESSED_FLG);

      u08 a = 0xFF;

      COL_DDR = COL_MASK;
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");

   	if (!(ROW_PIN & (1‹‹ROW_1)))
         a &= (~(1‹‹7));
   	if (!(ROW_PIN & (1‹‹ROW_2)))
         a &= (~(1‹‹6));
   	if (!(ROW_PIN & (1‹‹ROW_3)))
         a &= (~(1‹‹5));
   	if (!(ROW_PIN & (1‹‹ROW_4)))
         a &= (~(1‹‹4));

      ROW_DDR = ROW_MASK;
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");
   	asm("nop");

   	if (!(COL_PIN & (1‹‹COL_1)))
         a &= (~(1‹‹3));
   	if (!(COL_PIN & (1‹‹COL_2)))
         a &= (~(1‹‹2));
   	if (!(COL_PIN & (1‹‹COL_3)))
         a &= (~(1‹‹1));
   	if (!(COL_PIN & (1‹‹COL_4)))
         a &= (~(1‹‹0));

      if (a != 0xFF)
         set_bit (keys_flags, KEYS_PRESSED_FLG);

      keys_curr = a;
   }
}
//------------------------------------------------------------------------
struct tab_key_cod __flash tab_kbd_drv_keys_cod [] =
{
   {KEY_ONE,     KEY_ONE_COD},
   {KEY_TWO,     KEY_TWO_COD},
   {KEY_THREE,   KEY_THREE_COD},
   {KEY_FOUR,    KEY_FOUR_COD},
   {KEY_FIVE,    KEY_FIVE_COD},
   {KEY_SIX,     KEY_SIX_COD},
   {KEY_SEVEN,   KEY_SEVEN_COD},
   {KEY_EIGHT,   KEY_EIGHT_COD},
   {KEY_NINE,    KEY_NINE_COD},
   {KEY_ZERO,    KEY_ZERO_COD},

   {KEY_A,       KEY_ESC_COD},
   {KEY_B,       KEY_ENTER_COD},
   {KEY_C,       KEY_PREV_COD},
   {KEY_D,       KEY_NEXT_COD},

   {KEY_STAR,    KEY_MINUS_COD},
   {KEY_LATTICE, KEY_PLUS_COD},
   {0xFF,        0xFF},
};
//==================================================  ======================
#endif

//==================================================  ======================
void kbd_drv (void)
{
   scan_keys ();

   switch (_kbd_drv)
   {
      case KBD_DRV_INIT:
         #if (TYPE_KEYS==BUTTONS)
         KEYS_PIN = KEYS_MASK;
         #endif

         keys_prev = 0xFF;
//         keys_buf = 0xFF;

         _kbd_drv = KBD_DRV_NONE;
         break;

      case KBD_DRV_NONE:
         if (keys_flags & (1‹‹KEYS_PRESSED_FLG))
         {
            keys_prev = keys_curr;
            set_timer (ST_KBD_1, NO_RERUN_TIMER, DEBOUNCE_DELAY);
            _kbd_drv = KBD_DRV_DOWN;
         }
         break;

      case KBD_DRV_DOWN:
         if (wait (ST_KBD_1))
         {
            if (keys_flags & (1‹‹KEYS_PRESSED_FLG) && keys_prev == keys_curr)
            {
               if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod))
                  Set_Event (EV_ID_KEY_PRESSED, SET_CLR_EVENT);

               set_timer (ST_KBD_1, NO_RERUN_TIMER, HOLD_DELAY);
               _kbd_drv = KBD_DRV_HOLD; // KBD_DRV_WAIT_UP;
            }
            else
            _kbd_drv = KBD_DRV_NONE;
         }
         break;

      case KBD_DRV_HOLD:
      case KBD_DRV_REPEAT:
         if (!(keys_flags & (1‹‹KEYS_PRESSED_FLG)))
         {
            _kbd_drv = KBD_DRV_WAIT_UP;
            return;
         }

         if (keys_prev != keys_curr)
         {
            _kbd_drv = KBD_DRV_NONE;
            return;
         }

         if (wait (ST_KBD_1))
         {
            if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod))
               Set_Event (EV_ID_KEY_PRESSED, SET_CLR_EVENT);

            set_timer (ST_KBD_1, NO_RERUN_TIMER, REPEAT_DELAY);
            _kbd_drv = KBD_DRV_REPEAT;
         }
         break;

      case KBD_DRV_WAIT_UP:
         if (!(keys_flags & (1‹‹KEYS_PRESSED_FLG)))
         {
             set_timer (ST_KBD_1, NO_RERUN_TIMER, DEBOUNCE_DELAY);
             _kbd_drv = KBD_DRV_UP;
         }
         break;

      case KBD_DRV_UP:
         if (wait (ST_KBD_1))
         {
            if (!(keys_flags & (1‹‹KEYS_PRESSED_FLG)))
               _kbd_drv = KBD_DRV_NONE;
         else
               _kbd_drv = KBD_DRV_WAIT_UP;
         }
         break;

      default:
         break;
   }
}
//==================================================  ======================

//==================================================  ======================
/*
u08 get_key (u08 key)
{
   u08 tmp_key = keys_buf;

   if (tmp_key != 0xFF)
   {
      if (tmp_key == key)
      {
         keys_buf = 0xFF;
         return 1;
      }
   }

   return 0;
}
*/

u08 GetKeyCode (void)
{
   return keys_buf;
}
//==================================================  ======================
Insector вне форума  
Непрочитано 07.05.2016, 13:00  
omercury
Почётный гражданин KAZUS.RUN
 
Аватар для omercury
 
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
omercury на пути к лучшему
По умолчанию Re: Семисегментный индикатор и клавиатура

Сообщение от Insector Посмотреть сообщение
Код:
Эпическая сила!
Юнионы, дефайны, структуры, условная компиляция...
И всё на День Радио.


Сообщение от AlesyaS Посмотреть сообщение
Начала учить микроконтроллеры и программирование на Си совсем не давно.
Читайте по буквам - А Л Е С Я

omercury вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Индикатор для китайского приёмника radiolubitel 512 Автоматика и аппаратура связи 6 17.06.2015 13:32
Вывод числа на семисегментный индикатор lexa1424 Микроконтроллеры, АЦП, память и т.д 26 01.05.2013 08:26
Способы вывода данных на семисегментный индикатор artyomugr Микроконтроллеры, АЦП, память и т.д 44 04.08.2011 17:25
PIC16F690+семисегментный индикатор johnnyr Микроконтроллеры, АЦП, память и т.д 8 25.12.2009 21:25
Не матричная клавиатура для МП alexplev Микроконтроллеры, АЦП, память и т.д 8 22.02.2009 03:16


Часовой пояс GMT +4, время: 16:24.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.