Обсуждаем контроллеры компании Atmel.
Ответить

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

Пн окт 02, 2017 17:43:30

Здравствуйте, Уважаемые КОТЫ.
Осваиваю СИ в 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

http://cxema.my1.ru/publ/principialnye_ ... 2-1-0-2514

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

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

Пн окт 02, 2017 20:32:30

остальные пины МК заняты, другой схемой.
Именно это побудило использовать семисегментный дешифратор? Нет свободных трёх выводов? А то можно было избавиться от 74hct4511.
но не работает.
Не понял, куда подключен правый вывод кнопки "замыкается когда идёт набор", а так же выводов 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

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

остальные пины МК заняты, другой схемой.
Именно это побудило использовать семисегментный дешифратор? Нет свободных трёх выводов? А то можно было избавиться от 74hct4511.
но не работает.
Не понял, куда подключен правый вывод кнопки "


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

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

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

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

Добавлено after 21 minute 4 seconds:
http://cxema.my1.ru/publ/principialnye_skhemy_bytovykh_ustrojstv/telefonija/indikator_nabiraemogo_nomera/52-1-0-2514

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


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

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

Пн окт 02, 2017 23:28:12

Когда мы крутим колесо, наблюдаем картину: вывод1 (pd4) - размыкается от земли и там появляется 1(Т.к нога подмешана в мк на питание) и она там висит до окончания набора номера.
Обращаю внимание, что в номеронабирателе оба контакта замыкаются на землю, т.е. на лог. "0".
Теперь смотрим в железе (фиг с ним - в эмуляторе) - какой потенциал будет на PD5 при нажатой или отпущенной кнопке "пока набирается номер", если с обоих сторон кнопки подается питание (прямо или через резистор).
На этом и основан алгоритм " считать импульсы, прибавляя к переменной единицу, до тех пор пока на другом выводе2 (pd4) висит единица"
Ключевое слово "импульсы"! А не увидеть "0" и подождать ЫЫЫ единиц времени.
В данном случае "импульс" - это переход из одного состояния в другое.
Я исходил из того, что если у нас выставлен порт на вход, то ему уже нельзя присвоить никакое значение в процессе выполнения программы
Надо исходить не из чего-то, а из даташита - там написано.
понимает ли мк мои условия типа "if (cifra>0 && cifra<10) "
Понимает. Хоть можно было написать более компактно и красиво.
Кстати, не увидел что будет на индикаторе, если не будет выдано ни одного импульса за время сигнала "пока набирается номер". Получается, что значение не изменится - будет от предыдущего набора.
решил повыпендриваться с мк)))Здесь все реализовано по задержкам. Придётся повозиться чтоб Ее настроить под конкретный номеронабиратель.
При использовании прерываний и/или счетчика-1 в режиме внешних импульсов вообще не требуется никаких настроек задержек.

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

Вт окт 03, 2017 07:07:43

Понято. Спасибо! Буду пробовать использовать Вами предложенный алгоритм.
подождать ЫЫЫ единиц времени

Прям повеселило с утра)))))

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

Вс окт 08, 2017 22:02:35

Если немного подправить вашу схему, будет работать.
Изображение
Если хотите выложите все файлы(проект и протеус) подправлю.

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

Вместо _delay_ms сделайте проверку на отпускание кнопки.
Вложения
1e5y98qmqe (1).jpg
(126.13 KiB) Скачиваний: 1363

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

Вс окт 15, 2017 18:13:33

Обращаю внимание, что в номеронабирателе оба контакта замыкаются на землю, т.е. на лог. "0".

Прошу прощения, не было возможности заниматься.
по Вашему совету переделал программу, ну и немного схему. теперь все встало на свои места. в принципе функции программа выполняет. Косяк, то что цифры будут бежать во время набора, но как с этим бороться опять же кроме задержки я не могу додуматься.
Схема:
СпойлерИзображение

Программа:
Спойлер#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 нажимается --> выводится цифра на семисегментник.

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

Если немного подправить вашу схему, будет работать.
.
что-то не вышло по моему алгоритму и с Вашей схемой, но все равно большое спасибо!!

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

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

Вс окт 15, 2017 21:16:23

Косяк, то что цифры будут бежать во время набора, но как с этим бороться опять же кроме задержки я не могу додуматься.
Динамическая индикация на прерываниях - всего делов-то.
Схема:
А вот индикатор есть смысл взять другой, с общим анодом.
У AVR "нагрузочная способность" низкого уровня гораздо выше - посмотри схему в даташите, стр. 50 "Ports as General Digital I/O".
Более часто принято "зажигать" светодиоды, устанавливая логический "0" на выходе.
Подскажите пожалуйста, а как лучше сделать защиту от дребезга, находил самое простое по задержкам, подойдет ли сюда?
Нажатие кнопки обрабатывать по прерыванию. После срабатывания прерывания запустить таймер на время Ы, при срабатывании прерывания по таймеру проверить состояние кнопки.
Да, можно сказать что "на задержках". :))
нужны ли теперь, в данном случае, подтяжки (если они зашиты програмно) и кондеры?
Смысла кондёров я тоже не понял, никогда не ставлю.
А резисторные подтяжки есть смысл поставить, т.к. встроенные в контроллер - слишком высокоомны (кажется, сотни КОм?). Я обычно ставлю 5...10 К.

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

Вс окт 15, 2017 23:08:40

mas123 писал(а):резисторные подтяжки есть смысл поставить, т.к. встроенные в контроллер - слишком высокоомны (кажется, сотни КОм?)

Открыть даташит... не судьба))
1.jpg
(32.02 KiB) Скачиваний: 637

А кому лень открывать даташит, могут взять тестер и измерить точно))
2.jpg
(147.76 KiB) Скачиваний: 623

mas123 писал(а):Я обычно ставлю 5...10 К.

Внешнии резисторы и конденсаторы в этой схеме нафиг не нужны)) Достаточно внутренних.
mas123 писал(а):Динамическая индикация...

Динамическая индикация - это когда выводом у МК мало. В той схеме вроде хватает.))
mas123 писал(а):Нажатие кнопки обрабатывать по прерыванию. После срабатывания прерывания запустить таймер на время Ы, при срабатывании прерывания по таймеру проверить состояние кнопки.

:roll: Ну... это по желанию)) Хотя может проще будет в основном цикле тупо проверять много раз... Повторяю - это по желанию))

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

Вт окт 17, 2017 13:57:47

Ну и чем дело кончилось?
8)

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

Ср окт 18, 2017 13:29:22

[uquote="mas123",url="/forum/viewtopic.php?p=3196950#p3196950"]
нужны ли теперь, в данном случае, подтяжки (если они зашиты програмно) и кондеры?

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

что-то не вышло по моему алгоритму и с Вашей схемой, но все равно большое спасибо!!

Выложите проект для протеуса, поправлю то, что не работает.

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

Ср окт 18, 2017 13:42:27

вообщето не надо забыват что НН хоть простой мех хоть кнопочный цифповой выдает 10 импулсов на 0 цифру...

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

Ср окт 18, 2017 15:46:13

mas123 писал(а):
У AVR "нагрузочная способность" низкого уровня гораздо выше - посмотри схему в даташите, стр. 50 "Ports as General Digital I/O".

Часом не путаете с ТТЛ? У AVR - моно-хренственно. В доке doc2486.pdf по Меге8 на стр.50 совсем про другое.

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

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

Чт окт 19, 2017 18:11:15

codenamehawk писал(а):Конденсаторы в этой схеме убирают дребезг кнопок. Если их поставить, то в программе не надо никаких таймеров - задержек, которые борются с дребезгом.

Вот сразу видно что Вы никогда не работали в связи)) :)))

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

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

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

Чт окт 19, 2017 19:34:58

Тут никакие кондёры не спасут))

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

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

Пт окт 20, 2017 15:23:51

Часом не путаете с ТТЛ? У AVR - моно-хренственно.
Возможно путаю. Только не с TTL, а со старыми контроллерами.
Внешние резисторы нужны для того, что бы проц не реагировал на внешние помехи.
Т.е. тоже не доверяешь внутренним резисторам подтяжки? :)
Конденсаторы в этой схеме убирают дребезг кнопок.
Программно легко убрать дребезг. Поэтому и сомневаюсь в необходимости ёмкостей.

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

Сб окт 21, 2017 17:41:15

Т.е. тоже не доверяешь внутренним резисторам подтяжки?

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

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

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

Вс окт 22, 2017 18:23:17

Если кто ставил авр в реальное железо, сразу ловил срабатывание кнопки, без резистора подтяжки.
Никогда не ставил контроллеры и процессоры в "виртуальное железо". :sleep:
Лично я не вижу смысла играться в симуляторе, и на работе тоже не применяется такое.
Собственно, я спрашивал не о нужности резисторов подтяжки "вообще", а об использовании или "недоверии" к внутренним резисторам подтяжки в AVR. :))

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

Пн окт 23, 2017 08:20:23

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