Страница 1 из 3

Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 02, 2017 17:43:30
Hiperboloyd
Здравствуйте, Уважаемые КОТЫ.
Осваиваю СИ в Atmel Studio и вот решил сразу ставить цели и добиваться. Прошу камнями не кидать, я правда старался.
Делаю игрушку для ребенка "бизиборд". Все как бы просто, но не для меня. Телефонный дисковый номеронабиратель + Семисегментник, который выводит набранную цифру.
Пытаюсь в Протеусе смоделировать нажимая кнопками, имитируя набор номера.... но не работает. Если у кого-то есть свободное время может поможете... буду безумно благодарен.

схемка:
Изображение

Код программы:
Спойлер#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>


unsigned char SEGMENTE[] =
{
0b00000000, // 0
0b00000001, // 1
0b00000010, // 2
0b00000011, // 3
0b00000100, // 4
0b00000101, // 5
0b00000110, // 6
0b00000111, // 7
0b00001000, // 8
0b00001001, // 9
};
unsigned char cifra=0;

int main(void)
{
DDRD = 0b00001111; //4 входа и 4 выхода
PORTD = 0b11100000;
while (1)
{
while (PIND & (1<<4)) //если PD4 =1 на протяжении всего набора
{
if (!(PIND & (1<<5))) // если начался набор и PD5=0
{
cifra++;
_delay_ms(2000); //задержка длинна импульса (пока для кнопки)
}
}

if (cifra>0 && cifra<10) // если цифра >0 и <10
{
PORTD = SEGMENTE[cifra]; //вывести на семисегментник
cifra=0;
}
else
{
if (cifra=10)
{
cifra=0;
PORTD = SEGMENTE[cifra];
}
}
за основу взял Скетч ардуиновский:
Спойлер#include <Bounce.h>; //так проще устранять дребезг контактов ( http://www.arduino.cc/playground/upload ... Bounce.zip )
Bounce bouncer = Bounce(2, 40);

int pulses = 0;

void setup() {
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop() {
while(digitalRead(3) == HIGH) { //пока идет набор
if (bouncer.update()) { //если произошло событие
if (bouncer.read()==0) { //если пришел сигнал с контактной группы
pulses++; //добавить 1 в переменную
bouncer.rebounce(500);
}
}
}
if(pulses > 0 && pulses < 10) { //чтобы в com порт шли только реальные цифры и ничего больше
Serial.println(pulses); //шлем в порт
pulses = 0; // обнуляем переменную
}
else if(pulses == 10) { //если с номеронабирателя пришло 10
pulses = 0; //то реальная цифра - ноль (особенности набирателя), заодно обнуляем переменную
Serial.println(pulses); //шлем в порт
}
}
подозреваю что дело в условиях, компилятор не ругается, так что хз куда копать....
остальные пины МК заняты, другой схемой.

Заранее спасибо даже за критику. Всем Котам хороший кусок Мяса)

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 02, 2017 17:55:27
Maykill
http://cxema.my1.ru/publ/principialnye_ ... 2-1-0-2514

ВОТ ТАК реализована индикация набора на жесткой логике
Может -поможет?

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 02, 2017 20:32:30
mas123
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196726#p3196726"]остальные пины МК заняты, другой схемой.[/uquote]Именно это побудило использовать семисегментный дешифратор? Нет свободных трёх выводов? А то можно было избавиться от 74hct4511.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196726#p3196726"]но не работает.[/uquote]Не понял, куда подключен правый вывод кнопки "замыкается когда идёт набор", а так же выводов 3 и 4 74hct4511.
По даташиту на 74hct4511 получается, что подключено к "1", т.е. к плюс питанию.
Тогда что ожидается на выводе PD4 при нажатии кнопки, если этот вывод скинфигурирован как вход с подтягивающие к плюсу резистором?
Там всегда будет "1". :)

Сам подсчет импульсов сделан вообще неправильно. Нужно ловить переход из "0" и "1" (или наоборот).
Это либо извращением - делать частый-частый опрос, либо как правильно - через прерывания.
Ещё проще: вход PD5 очень удачно оказался входом T1. Сконфигурировать таймер-1 на подсчет импульсов по тактам извне, пусть само и подсчитывает.

Кстати, подтяжки к плюсу у входов PD4 и PD5 - нет. В смысле, вначале есть, а потом - уже нет. :)
Первая же запись в "PORTD" затирает единички, выставленные при инициализации "PORTD = 0b11100000;"
Тут нужно либо прочитать из POTRD, обнулить младшие 4 бита, наложить по OR выводимый код и записать в PORTD.
Либо сразу выставлять нужные биты.

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

cifra |= 0b11100000;
PORTD = cifra;
Кстати, массив "SEGMENTE" не нужен - посмотри что у него на входе и на выходе.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 02, 2017 21:38:40
Hiperboloyd
Большое спасибо, за то что откликнулись так скоро.
Простите,с компа не могу зайти и красиво ответить на все вопросы. Утром попробую подумать над счетчиком о котором вы написали.
Свободных выводов действительно нет))))
Вывод на семисегментник полностью рабочий, я делал промежуточные тесты. Прежде чем считать импульсы

[uquote="mas123",url="/forum/viewtopic.php?p=3196878#p3196878"][uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196726#p3196726"]остальные пины МК заняты, другой схемой.[/uquote]Именно это побудило использовать семисегментный дешифратор? Нет свободных трёх выводов? А то можно было избавиться от 74hct4511.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196726#p3196726"]но не работает.[/uquote]Не понял, куда подключен правый вывод кнопки "[/uquote]

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

Когда писал прогу я не заострял внимание и просто одной кнопкой подавал 1 на мк а другой 0. В протеусе одну кнопку зажимал, а другой изображал импульсы, потом отпускал первую. И в этот момент на семисегментнике должна показаться цифра.

А вот про подтяжки выводов, возможно вы и правы. Я исходил из того, что если у нас выставлен порт на вход, то ему уже нельзя присвоить никакое значение в процессе выполнения программы, т.е подтяжка не нарушается. - это первый вопрос с которым нужно мне разобраться

И второй : понимает ли мк мои условия типа "if (cifra>0 && cifra<10) " а то я в основном руководствуюсь, пока что конструкциями из языка pascal.

Добавлено after 21 minute 4 seconds:
[uquote="Maykill",url="/forum/viewtopic.php?p=3196735#p3196735"]http://cxema.my1.ru/publ/principialnye_skhemy_bytovykh_ustrojstv/telefonija/indikator_nabiraemogo_nomera/52-1-0-2514

ВОТ ТАК реализована индикация набора на жесткой логике
Может -поможет?[/uquote]

Спасибо. Я сначала рассматривал эту схему, но решил повыпендриваться с мк)))Здесь все реализовано по задержкам. Придётся повозиться чтоб Ее настроить под конкретный номеронабиратель.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 02, 2017 23:28:12
mas123
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196905#p3196905"]Когда мы крутим колесо, наблюдаем картину: вывод1 (pd4) - размыкается от земли и там появляется 1(Т.к нога подмешана в мк на питание) и она там висит до окончания набора номера.[/uquote]Обращаю внимание, что в номеронабирателе оба контакта замыкаются на землю, т.е. на лог. "0".
Теперь смотрим в железе (фиг с ним - в эмуляторе) - какой потенциал будет на PD5 при нажатой или отпущенной кнопке "пока набирается номер", если с обоих сторон кнопки подается питание (прямо или через резистор).
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196905#p3196905"]На этом и основан алгоритм " считать импульсы, прибавляя к переменной единицу, до тех пор пока на другом выводе2 (pd4) висит единица"[/uquote]Ключевое слово "импульсы"! А не увидеть "0" и подождать ЫЫЫ единиц времени.
В данном случае "импульс" - это переход из одного состояния в другое.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196905#p3196905"]Я исходил из того, что если у нас выставлен порт на вход, то ему уже нельзя присвоить никакое значение в процессе выполнения программы[/uquote]Надо исходить не из чего-то, а из даташита - там написано.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196905#p3196905"]понимает ли мк мои условия типа "if (cifra>0 && cifra<10) "[/uquote]Понимает. Хоть можно было написать более компактно и красиво.
Кстати, не увидел что будет на индикаторе, если не будет выдано ни одного импульса за время сигнала "пока набирается номер". Получается, что значение не изменится - будет от предыдущего набора.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3196905#p3196905"]решил повыпендриваться с мк)))Здесь все реализовано по задержкам. Придётся повозиться чтоб Ее настроить под конкретный номеронабиратель.[/uquote]При использовании прерываний и/или счетчика-1 в режиме внешних импульсов вообще не требуется никаких настроек задержек.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вт окт 03, 2017 07:07:43
Hiperboloyd
Понято. Спасибо! Буду пробовать использовать Вами предложенный алгоритм.
подождать ЫЫЫ единиц времени
Прям повеселило с утра)))))

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вс окт 08, 2017 22:02:35
codenamehawk
Если немного подправить вашу схему, будет работать.
Изображение
Если хотите выложите все файлы(проект и протеус) подправлю.

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

if (!(PIND & (1<<5))) // если начался набор и PD5=0
{
cifra++;
_delay_ms(2000); //задержка длинна импульса (пока для кнопки)
}
Вместо _delay_ms сделайте проверку на отпускание кнопки.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вс окт 15, 2017 18:13:33
Hiperboloyd
[uquote="mas123",url="/forum/viewtopic.php?p=3196950#p3196950"]Обращаю внимание, что в номеронабирателе оба контакта замыкаются на землю, т.е. на лог. "0".[/uquote]
Прошу прощения, не было возможности заниматься.
по Вашему совету переделал программу, ну и немного схему. теперь все встало на свои места. в принципе функции программа выполняет. Косяк, то что цифры будут бежать во время набора, но как с этим бороться опять же кроме задержки я не могу додуматься.
Схема:
СпойлерИзображение
Программа:
Спойлер#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>


unsigned char cifra=0;
unsigned char SEGMENTE[] =
{// gfedcba
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
};

int main(void)
{
DDRD = 0b00000000; //поры на вход
PORTD = 0b11111111; //подтягивем к 1

DDRB = 0b11111111; // порты на выход
PORTB = 0b00000000; // подтягиваем к 0

TCNT0 = 0; //установка таймера в ноль
TCCR0 = 0b00000111 ; //таймер от внеш. источника по переднему фронту

while (1)
{
if (PIND & (1<<3)) //если PD3=1 (кнопка отжата)
{

cifra = TCNT0; //переменной присвоить значение счетчика

if (cifra>0 && cifra<10) // если цифра >0 и <10
{
PORTB = SEGMENTE[cifra]; //вывести на семисегментник цифру
cifra=0; //обнулить переменную

}
else
{
if (cifra=10) //если переменная равна 10
{
cifra=0; //обнулить переменную
PORTB = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
}
}
}
else
{
TCNT0 = 0;
}
}
}
Вовремя набора Кнопка 1 отжимается --> идет счет импульсов (Кнопка2) --> кнопка 1 нажимается --> выводится цифра на семисегментник.

Подскажите пожалуйста, а как лучше сделать защиту от дребезга, находил самое простое по задержкам, подойдет ли сюда?
Буду рад любому совету. Спасибо!

[uquote="codenamehawk",url="/forum/viewtopic.php?p=3201583#p3201583"]Если немного подправить вашу схему, будет работать.
.[/uquote] что-то не вышло по моему алгоритму и с Вашей схемой, но все равно большое спасибо!!

нужны ли теперь, в данном случае, подтяжки (если они зашиты програмно) и кондеры?

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вс окт 15, 2017 21:16:23
mas123
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3207542#p3207542"]Косяк, то что цифры будут бежать во время набора, но как с этим бороться опять же кроме задержки я не могу додуматься.[/uquote]Динамическая индикация на прерываниях - всего делов-то.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3207542#p3207542"]Схема:[/uquote]А вот индикатор есть смысл взять другой, с общим анодом.
У AVR "нагрузочная способность" низкого уровня гораздо выше - посмотри схему в даташите, стр. 50 "Ports as General Digital I/O".
Более часто принято "зажигать" светодиоды, устанавливая логический "0" на выходе.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3207542#p3207542"]Подскажите пожалуйста, а как лучше сделать защиту от дребезга, находил самое простое по задержкам, подойдет ли сюда?[/uquote]Нажатие кнопки обрабатывать по прерыванию. После срабатывания прерывания запустить таймер на время Ы, при срабатывании прерывания по таймеру проверить состояние кнопки.
Да, можно сказать что "на задержках". :))
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3207542#p3207542"]нужны ли теперь, в данном случае, подтяжки (если они зашиты програмно) и кондеры?[/uquote]Смысла кондёров я тоже не понял, никогда не ставлю.
А резисторные подтяжки есть смысл поставить, т.к. встроенные в контроллер - слишком высокоомны (кажется, сотни КОм?). Я обычно ставлю 5...10 К.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вс окт 15, 2017 23:08:40
roman.com
mas123 писал(а):резисторные подтяжки есть смысл поставить, т.к. встроенные в контроллер - слишком высокоомны (кажется, сотни КОм?)
Открыть даташит... не судьба))
1.jpg
(32.02 КБ) 655 скачиваний
А кому лень открывать даташит, могут взять тестер и измерить точно))
2.jpg
(147.76 КБ) 645 скачиваний
mas123 писал(а):Я обычно ставлю 5...10 К.
Внешнии резисторы и конденсаторы в этой схеме нафиг не нужны)) Достаточно внутренних.
mas123 писал(а):Динамическая индикация...
Динамическая индикация - это когда выводом у МК мало. В той схеме вроде хватает.))
mas123 писал(а):Нажатие кнопки обрабатывать по прерыванию. После срабатывания прерывания запустить таймер на время Ы, при срабатывании прерывания по таймеру проверить состояние кнопки.
:roll: Ну... это по желанию)) Хотя может проще будет в основном цикле тупо проверять много раз... Повторяю - это по желанию))

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вт окт 17, 2017 13:57:47
BOB51
Ну и чем дело кончилось?
8)

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Ср окт 18, 2017 13:29:22
codenamehawk
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3207542#p3207542"][uquote="mas123",url="/forum/viewtopic.php?p=3196950#p3196950"]
нужны ли теперь, в данном случае, подтяжки (если они зашиты програмно) и кондеры?[/uquote]
Внешние резисторы нужны для того, что бы проц не реагировал на внешние помехи. Если рядом включили лампочку уже возможна помеха и ложное срабатывание.
Конденсаторы в этой схеме убирают дребезг кнопок. Если их поставить, то в программе не надо никаких таймеров - задержек, которые борются с дребезгом.
что-то не вышло по моему алгоритму и с Вашей схемой, но все равно большое спасибо!!
Выложите проект для протеуса, поправлю то, что не работает.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Ср окт 18, 2017 13:42:27
musor
вообщето не надо забыват что НН хоть простой мех хоть кнопочный цифповой выдает 10 импулсов на 0 цифру...

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Ср окт 18, 2017 15:46:13
Jack_A
mas123 писал(а):
У AVR "нагрузочная способность" низкого уровня гораздо выше - посмотри схему в даташите, стр. 50 "Ports as General Digital I/O".
Часом не путаете с ТТЛ? У AVR - моно-хренственно. В доке doc2486.pdf по Меге8 на стр.50 совсем про другое.

А по теме - напрасно ТС связался с раритетом из прошлого тысячеления, матричный кнопочный НН дал бы, думаю, больше полезных навыков, применимых и в дальнейшем.
musor правильно заметил насчет 10-го импульса. Когда мне довелось делать на такой х.не что-то для военкомата, пришлось схемно мудрить ( на 511 серии ) с откусыванием лишних импульсов; подробности стерлись.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Чт окт 19, 2017 18:11:15
roman.com
codenamehawk писал(а):Конденсаторы в этой схеме убирают дребезг кнопок. Если их поставить, то в программе не надо никаких таймеров - задержек, которые борются с дребезгом.
Вот сразу видно что Вы никогда не работали в связи)) :)))

Старый дисковый номеронабиратель "рвёт" линию как придётся)) Зависит от "старости" номеронабирателя... Тут никакие кондёры не спасут)) Только программное выделение импульсов... и т.д. и т.п.
:tea:

И т.д. и .т.п.))

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Чт окт 19, 2017 19:34:58
codenamehawk
[uquote="roman.com",url="/forum/viewtopic.php?p=3210628#p3210628"]Тут никакие кондёры не спасут))[/uquote]
Если бы вы немного разбирались в электронике, такого бы не написали.
Одно дело шаговики переключать по длинной линии, другое вход проца.
С такими кондерами не только все импульсы сосчитает, но и их длительность заодно, ясное дело если надо.
(По такой схеме часто делают опрос энкодера, когда процу есть чем другим заняться, а не тупо запускать задержки)

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пт окт 20, 2017 15:23:51
mas123
[uquote="Jack_A",url="/forum/viewtopic.php?p=3209630#p3209630"]Часом не путаете с ТТЛ? У AVR - моно-хренственно.[/uquote]Возможно путаю. Только не с TTL, а со старыми контроллерами.
[uquote="codenamehawk",url="/forum/viewtopic.php?p=3209482#p3209482"]Внешние резисторы нужны для того, что бы проц не реагировал на внешние помехи.[/uquote]Т.е. тоже не доверяешь внутренним резисторам подтяжки? :)
[uquote="codenamehawk",url="/forum/viewtopic.php?p=3209482#p3209482"]Конденсаторы в этой схеме убирают дребезг кнопок.[/uquote]Программно легко убрать дребезг. Поэтому и сомневаюсь в необходимости ёмкостей.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Сб окт 21, 2017 17:41:15
codenamehawk
[uquote="mas123",url="/forum/viewtopic.php?p=3211444#p3211444"]Т.е. тоже не доверяешь внутренним резисторам подтяжки?[/uquote]
Если кто ставил авр в реальное железо, сразу ловил срабатывание кнопки, без резистора подтяжки.
Поэтому и сомневаюсь в необходимости ёмкостей.
В этой схеме такое включение конденсаторов даже имеет большой недостаток, разряд емкости на кнопку, но в этой схеме не смертельно, ну или если хотите позволительно.

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Вс окт 22, 2017 18:23:17
mas123
[uquote="codenamehawk",url="/forum/viewtopic.php?p=3212350#p3212350"]Если кто ставил авр в реальное железо, сразу ловил срабатывание кнопки, без резистора подтяжки.[/uquote]Никогда не ставил контроллеры и процессоры в "виртуальное железо". :sleep:
Лично я не вижу смысла играться в симуляторе, и на работе тоже не применяется такое.
Собственно, я спрашивал не о нужности резисторов подтяжки "вообще", а об использовании или "недоверии" к внутренним резисторам подтяжки в AVR. :))

Re: Дисковый номеронабиратель и семисегментник

Добавлено: Пн окт 23, 2017 08:20:23
BOB51
Зависит от схемотехники исполнения тех "внутренних подтяжек".
В некоторых ситуациях может стать причиной "триггерной защелки в 0"...
За многие годы работ с mcs51 (где такой эффект иногда имел место) нашел объяснение только в даташитах от STмикроэлектроникс для МК серий STC.
:roll:
Возможно и в других семействах что-то подобное можно встретить...
:dont_know: