Перейти к содержанию

Управление Семисегментным Индикаторм С Помощью Мк


Рекомендуемые сообщения

один фиг при вашем коде получается вот что:

#include <avr/io.h>

#define Bit(n) (1 << (n))

#define COUNT_ON_KEY 20
#define MAX_VALUE_VIRTUAL_TIMER 1000000

unsigned char mydata[] = {0x00,0x10,0x08,0x18,0x04,0x14,0x0C,0x1C,0x02,0x12};
unsigned int virtual_timer;
unsigned char value_current_led;
unsigned char key_code;

void KeyInput()
{
 static unsigned char tmp_key_count = 0;
 static unsigned char tmp_key_code = 0;

 if((PINB & Bit(PINB1))==0)
  {
               tmp_key_code = 1;
               tmp_key_count++;
  }
  else
       {
               tmp_key_code = 0;
               tmp_key_count = 0;
       }

 if((PINB & Bit(PINB2))==0)
  {
               tmp_key_code = 2;
               tmp_key_count++;
  }
  else
       {
               tmp_key_code = 0;
               tmp_key_count = 0;
       }

  if(tmp_key_count > COUNT_ON_KEY)
       {
               key_code = tmp_key_code;
               tmp_key_code = 0;
               tmp_key_count = 0; 
       }       
}

void IncrementValueLed()
{
if (value_current_led <= 9)
 {
       value_current_led++;
       key_code = 0;
 }
}

void DecrementumValueLed()
{
if(value_current_led >= 0)
 {
  value_current_led--;
  key_code = 0;
 }
}


int main()
{
DDRB = 0x00;
PORTB = 0xff;
DDRC = 0xff;

value_current_led = 0;
virtual_timer = 0;
do
{
switch(key_code)
{
 case 1:{ IncrementValueLed() ; break;} 
 case 2:{ DecrementumValueLed();break;}
}

PORTC = mydata[ value_current_led];
virtual_timer++;
if(virtual_timer >= MAX_VALUE_VIRTUAL_TIMER)
{
  KeyInput();
  virtual_timer = 0;
}

}while(1);
}

post-131485-0-58256100-1293466572_thumb.jpg

Изменено пользователем roninen
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 92
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

>>unsigned char mydata[] = {0x00,0x10,0x08,0x18,0x04,0x14,0x0C,0x1C,0x02,0x12};

Не знаю что у Вас за индикатор. И если предположить, что со встроенным дешифратором, то массив заполнен не правильно.

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

за материальный, либо моральный ущерб причиненный данным сообщением напрямую или косвенно.

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Все правильно, только там выходы перепутаны 1-2-4-8 идут не по порядку.

0x01 - это x1 индикатора

0x08 - это x2 индикатора

0x04 - это x4 индикатора

0x02 - это x8 индикатора

Учение - изучение правил. Опыт - изучение исключений.

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

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Я изменил массив и поминял порты для индикатора с общим анодом (без дешифратора) но программа всё равно не пашет:

#include <avr/io.h>

#define Bit(n) (1 << (n))

#define COUNT_ON_KEY 20
#define MAX_VALUE_VIRTUAL_TIMER 1000000

unsigned char mydata[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //другой массив для индикатора с общим анодом
unsigned int virtual_timer;
unsigned char value_current_led;
unsigned char key_code;

void KeyInput()
{
 static unsigned char tmp_key_count = 0;
 static unsigned char tmp_key_code = 0;

 if((PINB & Bit(PINB1))==0)
  {
               tmp_key_code = 1;
               tmp_key_count++;
  }
  else
       {
               tmp_key_code = 0;
               tmp_key_count = 0;
       }

 if((PINB & Bit(PINB2))==0)
  {
               tmp_key_code = 2;
               tmp_key_count++;
  }
  else
       {
               tmp_key_code = 0;
               tmp_key_count = 0;
       }

  if(tmp_key_count > COUNT_ON_KEY)
       {
               key_code = tmp_key_code;
               tmp_key_code = 0;
               tmp_key_count = 0; 
       }       
}

void IncrementValueLed()
{
if (value_current_led <= 9)
 {
       value_current_led++;
       key_code = 0;
 }
}

void DecrementumValueLed()
{
if(value_current_led >= 0)
 {
  value_current_led--;
  key_code = 0;
 }
}


int main()
{
DDRB = 0x00;
PORTB = 0xff;
DDRD = 0xff;  //другой порт вывода (порт D)

value_current_led = 0;
virtual_timer = 0;
do
{
switch(key_code)
{
 case 1:{ IncrementValueLed() ; break;} 
 case 2:{ DecrementumValueLed();break;}
}

PORTD = mydata[ value_current_led];
virtual_timer++;
if(virtual_timer >= MAX_VALUE_VIRTUAL_TIMER)
{
  KeyInput();
  virtual_timer = 0;
}

}while(1);
}

post-131485-0-18210300-1293486491_thumb.jpg

Изменено пользователем roninen
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Думаешь в этом была проблема?

Скажи, а ты знаком с таким методом определения неисправности как покаскадная проверка? К программам можно применять точно такие же методы. и в MPLab-е прекрасный симулятор есть, где можно пошагово прокручивать программу и выяснить что именно происходит. При этом не забыв "обнулить" все задержки - для симулятора они не важны и будут только задерживать.

Для эмуляции нажатия кнопки можно использовать "стимулы" а для отслеживания действия - просматривать содержимое какого-нибудь регистра.

И вообще, стоило бы начать знакомство с контроллером с ассемблера. Может тогда многие глупости и не возникали бы.

Милиончик для вирттаймера все же многовато, так не считаешь? между инкрементами так навскидку пройдет около 100 тактов осцилятора... помножим их на миллион что же у нас получится в итоге? при тактовой частоте в 4Мгц, 1 машцикл составляет 1мкс. 100милионов таких циклов - это около 100 секунд. Вот с таким интервалом у тебя будет происходить считывание состояния кнопки. Где ты был когда ставил туда такую цифру? Это собственно наглядный пример того что бывает когда копируешь чужой код не понимая как он работает.

Учение - изучение правил. Опыт - изучение исключений.

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

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

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

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

Говорят под линукс есть замечательная среда под атмеловские контроллеры, но ... не ставить же из-за этого линукс? И тем более нужна поддержка ассемблера, а современные среды почему-то больше заточены под "С".

Учение - изучение правил. Опыт - изучение исключений.

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

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

замечательной в сравнении с edlin? ^)

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

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

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

Так что, досихпор еще в поисках среды для АТМЕЛа которая способна работать с ассемблером и имеет встроенный отладчик.

Учение - изучение правил. Опыт - изучение исключений.

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

Я не очень понимаю :

#define COUNT_ON_KEY 20
if(tmp_key_count > COUNT_ON_KEY)
       {
               key_code = tmp_key_code;
               tmp_key_code = 0;
               tmp_key_count = 0; 
       }       

Почему COUNT_ON_KEY присваивают значение 20 (на что оно влияет???)

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

Это не присвоение, а макроопределение. После него, весь текст COUNT_ON_KEY в программе будет заменен на 20.

А влиять будет на условие

if(tmp_key_count > COUNT_ON_KEY)

В процессе компиляции будет создана такая строка

if(tmp_key_count > 20)

.

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

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

Интересно это в мой огород :D :D :D

>>Так почему именно 20 (а не другое число)???

я писал об этом несколько раз, но Вы меня не понимаете. Отвечу еще раз: "цифры для примеров взяты с потолка":D

void KeyInput()эта функция простой пример опроса кнопок с защитой от дребезга.

COUNT_ON_KEY этот параметр показывает сколько раз подряд должно быть считано значение порта "0" что бы

программа приняла решения что нажата кнопка. Значение рассчитываться исходя из тактовой частоты,

времени выполнения основного цикла и значения MAX_VALUE_VIRTUAL_TIMER.

Я об этом уже писал, но Вы не указали частоту ядра, а протеуса у меня нет и я не телепат.:rolleyes:

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

за материальный, либо моральный ущерб причиненный данным сообщением напрямую или косвенно.

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

а зачем считывать двадцать раз состояние порта, если нас в конечном счете интересует фронт или спад?

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

таким образом мы избавимся от дребезга, дождемся отпускания кнопки, после чего можно реагировать на нажатие.

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

а проще конденсатор поставить в параллель.

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

а зачем считывать двадцать раз состояние порта, если нас в конечном счете интересует фронт или спад?

И что Вам далось это число, написал же, что с потолка взял :D

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

таким образом мы избавимся от дребезга, дождемся отпускания кнопки, после чего можно реагировать на нажатие.

Человек не может понять простейший вариант реализации, а Вы о ...

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

Да исправные и дают на одно нажатие пачку импульсов.

а проще конденсатор поставить в параллель.

ИМХО:Избыточно

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

за материальный, либо моральный ущерб причиненный данным сообщением напрямую или косвенно.

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

лет дцать назад была популярна микроэвм БК0010, а я для нее писал и продавал программы, в основном на ассемблере т.к. си кажется не было просто.

ее клавиатура была образцом дребезга и других подобных несчастий для программера, оттуда и пошла привычка замыкание кнопки обсасывать всесторонне как куриную косточку :)

насчет избыточности, если например МК управляет чем-то критичным, типа запуска фрезы или микроволновки, то имхо дешевле поставить конденсатор и вовсе забыть про дребезг, практически с любой степенью сырости прошивки (сырости с точки зрения подавления дребезга программно), чем время от времени чесать репу, что эт она так вдруг резко отпилила или сварила ;)

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

тактовая частота процессора 1MHz

Наверно нашёл ошибку в вашем коде: не надо было обнулять при "отжатой кнопке"

  else
       {
               tmp_key_code = 0;
               tmp_key_count = 0;
       }

исправил в коде, в протеусе заработало(урррааа) :D:P

Изменено пользователем roninen
Ссылка на комментарий
Поделиться на другие сайты

Интересно это в мой огород :D :D :D
Незнаю незнаю, профессионалу с опытом это простительно ...
а проще конденсатор поставить в параллель.

Конденсатор НЕ ПОМОГАЕТ а только скрывает проблему - вроде бы и работает но нет-нет а проскакивает дребезг.

Я уже много-много раз говорил, чтобы избавится от дребезга достаточно считывать состояние кнопки не чаще чем каждые 10..20мс(можно и больше, но будет заметно "торможение"). Это достаточно просто делается параллельно с динамической индикацией.

При таком подходе главное и достаточное условие устранения дребезга - период опроса должен быть как минимум в 2 раза больше длительности дребезга. Для герконов например можно вообще уменьшить период опроса до 2..5мс

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

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

Во времена Z80 именно так и делал, однако примерно на 100 нажатий кнопки проскакивал "дребезг" и это на герконовых кнопках.

На остальных устройствах работающих от сети привязываю считывание кнопок с частотой 50Гц и никаких "дребезгов" не наблюдается. Для обычной логики - достаточно кнопку пропустить через DC-триггер который запоминает состояние кнопки с частотой 50гц и никаких проблем.

Учение - изучение правил. Опыт - изучение исключений.

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

а триггер шмидта на входе не является гарантией преобразования аналогового сигнала в цифровой
Алексей, осмелюсь с Вами не согласиться. ТШ для этого и предназначен, чтобы из плавно нарастающего/спадающего на входе сигнала формировать на выходе чёткие логические уровни.
когда напряжение находится на границе срабатывания
Нет у ТШ такой границы. Он имеет гистерезис на входе. Это своего рода защёлка, срабатывающая по 2-ум разным уровням на входе.
Ссылка на комментарий
Поделиться на другие сайты

чтобы из плавно нарастающего/спадающего на входе сигнала формировать на выходе чёткие логические уровни.

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

Нет у ТШ такой границы. Он имеет гистерезис на входе.

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

Учение - изучение правил. Опыт - изучение исключений.

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

но это напряжение из-за самого эффекта дребезга может проходить границы гистерезиса несколько раз
Чтобы этого не происходило нужно ёмкость увеличить, т.е. устранить калебания выходимые за пределы гистерезиса. :)
Ссылка на комментарий
Поделиться на другие сайты

Можно посчитать исходя из условия чтобы импульсы замыкания-размыкания кнопки(надо задаться определенными характеристиками этих импульсов - их возможной длительностью)

не приводили к изменению напряжения на конденсаторе больше чем на половину величины гистерезиса. Только может выйти так что реакция на кнопку будет слишком долгой... больше 100мс например.

Впрочем, недавно разбирал советскую EC-ЭВМ там многие кнопки зашунтированы К53-14 конденсаторами величиной 1мкф. довольно дорогое удовольствие.

Изменено пользователем Alexeyslav

Учение - изучение правил. Опыт - изучение исключений.

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

1 мкф это скорее всего какой-нибудь reset - т.е. редко нажимаемые.

от конденсатора эффект есть, и поэтому чаще конденсатор используется, чем не.

эффект как раз и заключается в том, что конденсатор не может мгновенно зарядиться до логической единицы или выше порога ТШ, через подтягивающий резистор, за время между соседними замыканиями-размыканиями кнопки в процессе установления контакта (т.е. дребезга)

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

по сравнению с RS или D-триггерами вариант с конденсатором не сильно хуже, но зато не требует лишних корпусов на плате и питания :)

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

Но такой метод не подходит к матричным клавиатурам, и даже наличие конденсатора не гарантирует отсутствие дребезга - т.к. у конденсатора есть свое активное сопротивление, и даже индуктивную составляющую. Ну и не забывать надо про скорость реакции на нажатие ведь конденсатор выбранной емкости должен успевать заряжаться/разряжаться до половины питания(или логического уровня).

В условиях когда реализация триггера не требует лишних корпусов ... стоит ли заморачиваться с конденсаторами?

Учение - изучение правил. Опыт - изучение исключений.

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

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...