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

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

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

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

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

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

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы
Непрочитано 12.03.2021, 18:06  
Maxsan22
Прохожий
 
Регистрация: 12.03.2021
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Maxsan22 на пути к лучшему
Печаль Матричная клавиатура-динамическая индикация

Здравствуйте. Начал изучать программирование Си AVR. Столкнулся с проблемой. Не получается вывести на 4 разрядный 7 сегментный дисплей значение из матричной клавиатуры 3х4. То есть, вывести 1,2,3.. получается. Но вывести 11,12,...111,234,...1234,7865 не получается. Может кто уже делал и посоветует как с этим справится..?
Код:
#include ‹inttypes.h›
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹avr/sleep.h›
#include ‹util/delay.h›

#define  CHISLO PORTA
#define  RAZRIAD PORTB
// Массив значений для порта вывода
int i = 0;

unsigned char key_tab[4] =
{
	0b11111110,
	0b11111101,
	0b11111011,
	0b11110111
};
// Функция опроса клавиатуры
// Функция опроса клавиатуры
int n = 0;
unsigned int razr1 = 0, razr2 = 0, razr3 = 0, razr4 = 0;
unsigned char g = 1;
unsigned int z = 0;
unsigned int chisla [10] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f};


void vse_chislo (unsigned int razbivka_chisla)
{
	razr1 = razbivka_chisla / 1000; // тысячи
	razr2 = razbivka_chisla % 1000 / 100; // сотни
	razr3 = razbivka_chisla % 100 / 10; // десятки
	razr4 = razbivka_chisla % 10; // единицы

}

ISR (TIMER0_OVF_vect)
{
	if (g == 1) {RAZRIAD = (1 ‹‹ 0); CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
	if (g == 2) {RAZRIAD = (1 ‹‹ 1); CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
	if (g == 3) {RAZRIAD = (1 ‹‹ 2); CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
	if (g == 4) {RAZRIAD = (1 ‹‹ 3); CHISLO = chisla[razr4];} //включаем 4-й разряд, остальные выключаем
	g++; // добавляем к переменной g единицу
	if (g › 4) g = 1; // отслеживаем переменную g, чтобы она не превысила значение 4

}

unsigned char scan_key(void)
{
	unsigned char key_value = 0;
	unsigned char i;
	for(i = 0; i ‹ 5; i++)
		{
		PORTC = key_tab[i]; // выводим лог. 0 в порт вывода
		_delay_us(10);

		switch (PINC & 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);
}
int main(void)
{


	DDRC |= (1 ‹‹ PC3) | (1 ‹‹ PC2) | (1 ‹‹ PC1) | (1 ‹‹ PC0); // Порт вывода
	DDRC &= ~(1 ‹‹ PC7) | (1 ‹‹ PC6) | (1 ‹‹ PC5) | (1 ‹‹ PC4); // Порт ввода
	PORTC = 0xF0; // Устанавливаем лог. 1 в порт ввода
	DDRA = 0b11111111;
	DDRB = 0x0F;
	PORTB |= (1 ‹‹ 4) | (1 ‹‹ 5);
	_delay_ms(10);

	RAZRIAD = (1 ‹‹ 0);
	CHISLO = 0x3f;

	// Настройка 0-го таймер счетчика на прерывание по переполнению

	TCCR0 |= (1 ‹‹ 1); TCCR0 &= ~((1 ‹‹ 0) | (1 ‹‹ 2)); // f/8
	TIMSK |= (1 ‹‹ 0);
	TCNT0 = 0;
	sei ();
	while(1)
		{
		// Выводим значение нажатой кнопки на индикатор
		z = scan_key();


		if(scan_key() › 0 )
			{
			if(scan_key ‹ 9)
				vse_chislo(z);else if(scan_key › 9)
				{
				z = z * 10 + z;
				vse_chislo(z);
				}
			}


		}
}
Реклама:

Последний раз редактировалось Maxsan22; 12.03.2021 в 18:11. Причина: удалил спойлер так как он не открывался
Maxsan22 вне форума  
Непрочитано 12.03.2021, 18:19  
baiderin
Почётный гражданин KAZUS.RU
 
Аватар для baiderin
 
Регистрация: 10.12.2007
Адрес: Екатеринбург
Сообщений: 2,727
Сказал спасибо: 2,418
Сказали Спасибо 894 раз(а) в 581 сообщении(ях)
baiderin на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Сообщение от Maxsan22 Посмотреть сообщение
razr3 = razbivka_chisla % 100 / 10; // десятки
razr4 = razbivka_chisla % 10; // единицы
razr3 = razbivka_chisla %1000% 100 / 10; // десятки
razr4 = razbivka_chisla %1000% 100% 10; // единицы
Для начала
baiderin вне форума  
Непрочитано 12.03.2021, 19:53  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,505
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Полагаю, надо начать с изучения английского языка хотябы в объеме гугл-переводчика.
RAZRIAD = DIGIT
CHISLO = NUMBER
razbivka_chisla = bcd (от binary-coded decimal, двоично-десятичное представление числа)
vse_chislo = value

Затем нужно почитать про BCD-преобразования на Си.
NewWriter вне форума  
Непрочитано 12.03.2021, 21:22  
Maxsan22
Прохожий
 
Регистрация: 12.03.2021
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Maxsan22 на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Похоже тут решили что спросил о грамматике?
С отображением числа 1234 если он в переменной z проблем нет.
Мне нужно при последовательном нажатии кнопок 1.2.3.4 на матричной клавиатуре в переменную z нужно записать 1234. Но пока получается вывести только один символ. ТО есть поочередно 1.2.3.4.
Как я понял, нужно создать некую переменную куда при нажатии 1 запишется 1, затем при нажатии 2, единица сдвинется в лево и запишется 2 и тд, но как это осуществить на практике???
Миниатюры:
Нажмите на изображение для увеличения
Название: 2021-03-14_17-39-21.png
Просмотров: 0
Размер:	22.8 Кб
ID:	161306  

Последний раз редактировалось Maxsan22; 14.03.2021 в 16:42.
Maxsan22 вне форума  
Непрочитано 13.03.2021, 01:02  
DanilinSA
Почётный гражданин KAZUS.RU
 
Регистрация: 25.11.2010
Адрес: г. Дзержинск Нижегородская обл.
Сообщений: 1,672
Сказал спасибо: 130
Сказали Спасибо 1,074 раз(а) в 517 сообщении(ях)
DanilinSA на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Сообщение от Maxsan22 Посмотреть сообщение
переменную куда при нажатии 1 запишется 1, затем при нажатии 2, единица сдвинется в лево и запишется 2 и тд, но как это осуществить на практике???
Число в аккумуляторе умножать на 10 и суммировать с введенным числом.
DanilinSA вне форума  
Непрочитано 13.03.2021, 15:53  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,505
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

В правильной грамматике лежит половина решения задачи.

Код:
#define MAX_DIGITS 4
#define ENTER      10
#define BACKSPACE  11

uint8_t key;          // код кнопки
uint8_t n = 0;        // число введенных цифр
uint16_t value = 0;   // это ваше "всё число"

do{
	key = ReadKeyboard();

	switch(key)
	{
	case 0 ... 9:
		value = value * 10 + key;
		Print(value);
		n++;
		break;
		
	case ENTER:

		break;
		
	case BACKSPACE:
		value /= 10;
		Print(value);
		n--;
		break;
	}
}while((n › 0) && (n ‹ MAX_DIGITS) && (key != ENTER));

Последний раз редактировалось NewWriter; 13.03.2021 в 16:34.
NewWriter вне форума  
Эти 2 пользователя(ей) сказали Спасибо NewWriter за это сообщение:
makakus (15.01.2022), mtit (14.03.2021)
Непрочитано 14.03.2021, 16:51  
Maxsan22
Прохожий
 
Регистрация: 12.03.2021
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Maxsan22 на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Сообщение от NewWriter Посмотреть сообщение
key = ReadKeyboard();
я новичок и не совсем понял, откуда функция ReadKeyboard()?
так же, впервые вижу конструкцию
Сообщение от NewWriter Посмотреть сообщение
case 0 ... 9:
можно подробнее..?
Сообщение от NewWriter Посмотреть сообщение
Print(value);
Это вывод на LCD дисплей?
Maxsan22 вне форума  
Непрочитано 14.03.2021, 17:38  
baiderin
Почётный гражданин KAZUS.RU
 
Аватар для baiderin
 
Регистрация: 10.12.2007
Адрес: Екатеринбург
Сообщений: 2,727
Сказал спасибо: 2,418
Сказали Спасибо 894 раз(а) в 581 сообщении(ях)
baiderin на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

тоже самое

case 0:
case 1:

. . . .

case 9:
для любой цифры от 0 до 9
baiderin вне форума  
Непрочитано 15.03.2021, 19:14  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,505
Сказал спасибо: 401
Сказали Спасибо 2,218 раз(а) в 1,316 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Матричная клавиатура-динамическая индикация

Сообщение от Maxsan22 Посмотреть сообщение
я новичок и не совсем понял
ммм... Тогда тут есть два важных момента.
Во-первых, любая клавиатура ввода должна работать по принципу триггера, то есть различать момент, когда кнопку только что нажали, и момент, когда кнопку только что отпустили. Опрос клавиатуры происходит довольно часто, 50-200 раз в секунду. И если при следующем опросе кнопка не будет отпущена, а она не будет отпущена - среднее время удержания кнопки пальцем 20 - 60 мс, произойдет повторный ввод той же цифры. Если клавиатуру реже опрашивать, например 10 раз в секунду (100 мс), то такая клавиатура будет восприниматься тормознутой.
Второй момент - возвращаемые коды кнопок, то есть коды событий срабатывания клавиатуры. Для удобства дальнейшего применения коды нажатых кнопок с цифрами будут в диапазоне от 0 до 9. Код кнопки Enter (ввод) = 10, код кнопки Backspace (или отмена) = 11. Хотя тут нет ограничений.

Соответственно, по второму моменту:
функция ReadKeyboard() может выглядеть вот так:
Код:
/** -------------------------------------------------------
 * @brief    Чтение матричной клавиатуры.
 * Последовательно активируются столбцы клавиатуры и считываются строки,
 * определяется нажатая кнопка. Код события (нажатой кнопки) возвращается
 * функцией.
 * Если ни одна кнопка не была нажата, возвращается 0xFF.
 * @return   Код события (кнопки).
 */
uint8_t ReadKeyboard(void)
{
	uint8_t rows = 0;        // переменная для чтения входов строк
	uint8_t keycode = 0xFF;  // переменная для кода кнопки

	/* Активация столбца 1, считывание строк */
	ACTIVATE_COL1            // COL1 = Low, COL2 = Hi-Z, COL3 = Hi-Z
	sDelay(1000);            // выдержка времени для стабилизации уровней
	rows = READ_ROWS;        // чтение входов строк

	/* Определение строки, на которой вх.уровень = Low */
	if((rows & (1 ‹‹ R1_bit)) == 0) keycode = 1;  // нажата кнопка 1
	if((rows & (1 ‹‹ R2_bit)) == 0) keycode = 4;  // нажата кнопка 4
	if((rows & (1 ‹‹ R3_bit)) == 0) keycode = 7;  // нажата кнопка 7
	if((rows & (1 ‹‹ R4_bit)) == 0) keycode = 11; // нажата кнопка BKSP

	/* Активация столбца 2, считывание строк */
	ACTIVATE_COL2            // COL1 = Hi-Z, COL2 = Low, COL3 = Hi-Z
	sDelay(1000);            // выдержка времени для стабилизации уровней
	rows = READ_ROWS;        // чтение входов строк

	/* Определение строки, на которой вх.уровень = Low */
	if((rows & (1 ‹‹ R1_bit)) == 0) keycode = 2;  // нажата кнопка 2
	if((rows & (1 ‹‹ R2_bit)) == 0) keycode = 5;  // нажата кнопка 5
	if((rows & (1 ‹‹ R3_bit)) == 0) keycode = 8;  // нажата кнопка 8
	if((rows & (1 ‹‹ R4_bit)) == 0) keycode = 0;  // нажата кнопка 0

	/* Активация столбца 3, считывание строк */
	ACTIVATE_COL3            // COL1 = Hi-Z, COL2 = Hi-Z, COL3 = Low
	sDelay(1000);            // выдержка времени для стабилизации уровней
	rows = READ_ROWS;        // чтение входов строк

	/* Определение строки, на которой вх.уровень = Low */
	if((rows & (1 ‹‹ R1_bit)) == 0) keycode = 3;  // нажата кнопка 3
	if((rows & (1 ‹‹ R2_bit)) == 0) keycode = 6;  // нажата кнопка 6
	if((rows & (1 ‹‹ R3_bit)) == 0) keycode = 9;  // нажата кнопка 9
	if((rows & (1 ‹‹ R4_bit)) == 0) keycode = 10; // нажата кнопка ENTER

	/* Возвращается код события */
	return keycode;
}//--------------------------------------------------------
Макросы ACTIVATE_COL1, ACTIVATE_COL2, ACTIVATE_COL3 представляют собой команды установки выходных уровней на пинах столбцов клавиатуры - то есть активируемый столбец переводится в лог.0, а неактивные столбцы переводятся в высокоимпедансное (Hi-Z) состояние. Не в лог.1, а именно в Hi-Z. Почему? А для того, что если вдруг будут нажаты одновременно две и более кнопки из разных столбцов, не получилось КЗ.
В качестве Hi-Z состояния может быть на это время включен либо режим входа, либо выход постоянно настраивается на Open Drain.

Макрос READ_ROWS - это команда чтения входного порта, на который приходят строки клавиатуры.
R1_bit, R2_bit, R3_bit, R4_bit - это номер входного пина строк.

Выдержка времени между активацией столбца и считыванием входов строк нужна для завершения переходных процессов от ёмкости монтажа (кнопок, дорожек) клавиатуры. Выдержка времени небольшая, десятки микросекунд, подбирается экспериментально по надежности определения кнопок.


С этим разобрались. Окей.
Теперь по первому моменту, по триггированию клавиатуры.
За время "тычка" пальцем в кнопку клавиатура будет опрошена несколько раз, и каждый раз функция ReadKeyboard() будет возвращать код нажатой кнопки. И вместо ввода одной цифры получится несколько одинаковых. А значит, нужно фиксировать только первый переход от состояния "нет нажатых кнопок" к состоянию "кнопка нажата", а все последующие события, кроме события "нет нажатых кнопок", игнорировать.
Когда первое нажатие фиксируется, клавиатура выставляет флаг. Этот флаг в дальнейшем, вместе с кодом нажатой кнопки, будет использован для выполнения действий по нажатию кнопки.
Код:
/* По флагу таймера интервалов опроса клавиатуры
 * опрашивается клавиатура, определяется код события
 * клавиатуры.
 * Если код соответствует нажатой кнопке, и кнопка
 * нажата только что, устанавливается флаг клавиатуры,
 * а состояние клавиатуры = KEYPRESS.
 * Если код события клавиатуры = 0xFF, это значит, что
 * все кнопки отпущены, а значит, состояние клав.= KEYFREE
 */
#define KEYFREE    0
#define KEYPRESS   1

if(kbdtimer_flag)
{
	keycode = ReadKeyboard();
	if(keycode == 0xFF)
		kbdstate = KEYFREE;
	else if(kbdstate == KEYPRESS)
	{
		kbdstate = KEYPRESS;
		kbdflag = 1;
	}
}


/* По флагу клавиатуры (зафиксировано нажатие кнопки)
 * выполняется действие.
 * Флаг клавиатуры сбрасывается перед (или после)
 * выполнением действия
 */
if(kbdflag)
{
	kbdflag = 0;
	KeyAction(keycode);
}
NewWriter вне форума  
Непрочитано 09.01.2022, 13:56  
SvetlanaG
Прохожий
 
Регистрация: 09.01.2022
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SvetlanaG на пути к лучшему
По умолчанию

Здравствуйте, а как в этом коде указываются пины контроллера?

Получила кучу ошибок:
Код:
../main.c: In function 'ReadKeyboard':
../main.c:16: error: 'ACTIVATE_COL1' undeclared (first use in this function)
../main.c:16: error: (Each undeclared identifier is reported only once
../main.c:16: error: for each function it appears in.)
../main.c:17: error: expected ';' before '_delay_ms'
../main.c:18: error: 'READ_ROWS' undeclared (first use in this function)
../main.c:21: error: 'R1_bit' undeclared (first use in this function)
../main.c:22: error: 'R2_bit' undeclared (first use in this function)
../main.c:23: error: 'R3_bit' undeclared (first use in this function)
../main.c:24: error: 'R4_bit' undeclared (first use in this function)
../main.c:27: error: 'ACTIVATE_COL2' undeclared (first use in this function)
../main.c:28: error: expected ';' before '_delay_ms'
../main.c:38: error: 'ACTIVATE_COL3' undeclared (first use in this function)
../main.c:39: error: expected ';' before '_delay_ms'

Последний раз редактировалось mike-y-k; 12.01.2022 в 19:24. Причина: 6.6, 7.15
SvetlanaG вне форума  
 

Закладки
Опции темы

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Посегментная динамическая индикация 3ann Микроконтроллеры, АЦП, память и т.д 39 22.10.2012 13:49
Динамическая индикация 16/1 - увеличить яркость whoim Электроника - это просто 29 30.01.2012 02:25
Динамическая индикация EKuzmich TTL и CMOS логика 16 05.08.2011 08:18
Не матричная клавиатура для МП alexplev Микроконтроллеры, АЦП, память и т.д 8 22.02.2009 03:16
Динамическая индикация ПОМОГИТЕ 7Fantomas7 Микроконтроллеры, АЦП, память и т.д 2 27.03.2008 23:53


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


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot