Первые часы - очень много вопросов

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Здравствуйте уважаемые Коты! Долго думал в какую ветку форума написать и вообще стоит ли создавать новую тему, так как подобных тем ОЧЕНЬ много. Но я все же решил сделать это потому что во всех просмотренных мной темах не нашел (или не понял - в большинстве) ответов на свои вопросы. Сразу приношу извинения если тема была создана не там где надо.

Я начинающий в программировании микроконтроллеров и в электронике, но думаю, что уровень моих знаний позволит мне создать данное устройство (точнее понять Ваши советы, подсказки и объяснения).

Решил я построить часы с выводом времени в формате чч.мм.сс и даты дд.мм.гг (датой я займусь позже, как только решу все проблемы с часами). Из функций хочеться добавить только будильник. Для вывода времени будет использован 14 разрядный ВЛИ ИВ27М. Мозгом устройства будет Atmega8

На самом деле это вторые часы которые я делаю. Вот хочу, опираясь на старый исходник, построить новые.
Вопрос №1 Как организовать динамическую индикацию на 6 разрядов? (чч.мм.сс)
Вопрос №2 Можно ли для коммутации анодов сегментов использовать ULN2803A? Если да, то как?
Вопрос №3 Как организовать будильник?
Вопрос №4 Как прилепить секунды?
Для начала думаю достаточно. Привожу исходник, сразу прошу сильно не возмущаться по поводу его кривизны :)

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

#include <mega8.h>
#include <delay.h>
 static flash unsigned char display[]=    // масив для индикатора
 {
  (0b11000000), // 0
  (0b11111001), // 1
  (0b10100100), // 2
  (0b10110000), // 3
  (0b10011001), // 4
  (0b10010010), // 5
  (0b10000010), // 6
  (0b11111000), // 7
  (0b10000000), // 8
  (0b10010000), // 9  
 };
bit m;
unsigned char sek, min, hour;
     
interrupt [TIM2_COMP] void timer2_comp_isr(void)    // прерывание по таймеру 2
{
TCNT2=0x00;        // обнуляем счетный регистр
  sek++;
  if(sek==60)
 {
 sek=0;
 min++;
 }
  if(min==60)
 {
 min=0;
 hour++;
 }
  if(hour==24) hour=0;
   
 }
 
 
   
void disp(unsigned char a)          // фукция для вывода значений
 {
  unsigned char des=0;
  while(a>=10)
   {
    a-=10;
    des++;
   }
   
        
   if(m==0)                   // условия динамической индикации
   {
   PORTC.0=1;
   PORTD=display[des];
   delay_ms(2);
   PORTC.0=0;    
   PORTC.1=1;
   PORTD=display[a];   
   delay_ms(2);   
   PORTC.1=0;          
   m=1;
   }
   else
   {
   PORTC.2=1;
   PORTD=display[des];
   delay_ms(2);
   PORTC.2=0;  
   PORTC.3=1;
   PORTD=display[a];
   delay_ms(2);
   PORTC.3=0;
   m=0;   
   }  
           
 }  

void main(void)
{
PORTB=0x07;
DDRB=0x00; 
PORTC=0x00;
DDRC=0x1F;
PORTD=0x00;
DDRD=0b11111111;

ASSR=0b00001000;     // таймер в асинхронном режиме
TCCR2=0b00000110;    // делитель
TCNT2=0x00;
OCR2=127;            // регистр сравнения
TIMSK=0b10000000;
#asm("sei")           // глобально разрешаем прерывания
while (1)

      {             
        disp(hour);
        disp(sek);
         if(PINB.0==0)     //если кнопка нажата
        {
         delay_ms(50);    // ждем 50мс
         while(PINB.0==0) // ждем отпускания кнопки
         {}     
         min++;
         if(min==60)min=0;                   
        }      
        if(PINB.1==0)     //если кнопка нажата
        {
         delay_ms(50);    // ждем 50мс
         while(PINB.1==0) // ждем отпускания кнопки
         {}     
         hour++;
         if(hour==24)hour=0;
                             
        }
                          
      }
      
}
Прошу ткнуть носом во все "неровности". Заранее спасибо!
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

sanyo.95 писал(а):Вопрос №1 Как организовать динамическую индикацию на 6 разрядов?
например, так
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

sanyo.95 писал(а):Вопрос №1 Как организовать динамическую индикацию на 6 разрядов? (чч.мм.сс)
Я например, храню в памяти 6 чисел ( десятки часов ... единицы секунд ). Это я храню в массиве. И вывожу за один такт индикации одно число.
При этом не нужно никакого BCD преобразования. Правда, несколько усложняется инкрементирование времени.
В главном цикле: 1) выводим число из массива по индексу. 2) задержка индикации. 3) опрос кнопок. 4) инкрементирование индекса (если вышли за пределы 5, то обнуляем). Когда это отладите, хорошо бы перенести процедуру индикации в обработчик прерывания.
Кстати, крайне неудачно сделан опрос кнопок (удержание кнопки влияет на индикацию). Посмотрите, как это сделано в
http://licrym.org/index.php/Простые_часы
sanyo.95 писал(а):Вопрос №2 Можно ли для коммутации анодов сегментов использовать ULN2803A? Если да, то как?
Думаю да. Поищите книжку "Сто схем с индикаторами". Там насколько я помню, есть пример управления ИВЛ через транзисторы. Через улн так же.
sanyo.95 писал(а):Вопрос №3 Как организовать будильник?
Например, выделить в памяти место для хранения времени срабатывания будильника, и например, бит его влючения. В главном цикле проверять, если совпало, яростно бибикать.
sanyo.95 писал(а):Вопрос №4 Как прилепить секунды?
См. п. 1

И еще. Работа с таймером в асинхронном режиме имеет некоторые особенности, почитайте
http://easyelectronics.ru/avr-uchebnyj- ... jmera.html
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

metan, ARV, большое спасибо за советы, буду разбираться. Уверен еще будут вопросы)))
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 44463
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

sanyo.95 писал(а): Вопрос №2 Можно ли для коммутации анодов сегментов использовать ULN2803A? Если да, то как?
Можно.. Резистор 10 - 20 кОм с анода (сетки) на источник анодного напряжения, при подаче логической "1" на вход ULN, она "сажает" анодное напряжение на "землю", сегмент или разряд "гаснет", при подаче "0", на сегмент или разряд подаётся напряжение (через резистор)

Если найдёте- можно использовать 1109КН2 (UDN6510A/R - UDN6514A/R, UDN6118A) У неё подключение- "наоборот"- она коммутирует анодное напряжение.. Преимущество- меньший потребляемый ток- в случае с ULN - несветящиеся сегменты потребляют ток через "подтягивающие" резисторы..
Реклама
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

АлександрЛ писал(а):Можно..
Спасибо за ответ! Вот набросал схему, скажите пожалуйста, это так должно выглядеть?
Вложения
ULN.jpg
(126.52 КБ) 465 скачиваний
Реклама
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

metan писал(а):BCD преобразования
поясните пожалуйста что это?
типа:

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

if(m==0)                   
   {
   PORTC.0=1;
   PORTD=display[des];
   delay_ms(2);
   PORTC.0=0;    
   PORTC.1=1;
   PORTD=display[a];   
   delay_ms(2);   
   PORTC.1=0;          
   m=1;
???
metan писал(а):если вышли за пределы 5, то обнуляем
за пределы 5 потому, что 6 разрядный индикатор?
Друг Кота
Аватара пользователя
Сообщения: 44463
Зарегистрирован: Пн ноя 30, 2009 03:00:01
Откуда: Нерезиновая

Сообщение АлександрЛ »

sanyo.95 писал(а): Вот набросал схему, скажите пожалуйста, это так должно выглядеть?
В общем, так.. Только я бы резисторы поставил по 22 - 24 кОм.. (попробовать), реально- там чем больше, тем лучше- меньше будет ток через резистор у "несветящегося" элемента.. В общем- то надо подбирать, "максимальное сопротивление", чтобы при этом анод нормально светился
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

АлександрЛ писал(а):я бы резисторы поставил по 22 - 24 кОм..
ставил подстроечный - яркость уменшается при 30к. Такие и поставлю. Большое спасибо!
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

sanyo.95 писал(а):поясните пожалуйста что это?
BCD преобразование - это типа:
while(a>=10)
{
a-=10;
des++;
}
т.е. из одного байта можно получить 3 десятичные цифры.
А если хранить их по отдельности, то такое преобразование не понадобится
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

metan писал(а):BCD преобразование - это типа:
спасибо, понял.
Собрал часы, пока без кнопок и прочего. Загорелись 6 нулей... и всё... Часы не идут, подскажите чем может быть вызвана эта проблема?
Исходник:

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

#include <mega8.h>
#include <delay.h>
 static flash unsigned char display[]=    // масив для индикатора
 {
  (0b11000000), // 0
  (0b11111001), // 1
  (0b10100100), // 2
  (0b10110000), // 3
  (0b10011001), // 4
  (0b10010010), // 5
  (0b10000010), // 6
  (0b11111000), // 7
  (0b10000000), // 8
  (0b10010000), // 9  
 };
unsigned char seconds, ten_seconds, minutes, ten_minutes, hours, ten_hours;
     
interrupt [TIM2_COMP] void timer2_comp_isr(void)    // прерывание по таймеру 2
 {
  TCNT2=0x00;        // обнуляем счетный регистр
  seconds++;         // условия работы часов
   if(seconds>=10)
  {
   seconds=0;
   ten_seconds++;
  }
  if(ten_seconds>=6)
  {
  ten_seconds=0;
  minutes++;
  }
  if(minutes>=10)
  {
  minutes=0;
  ten_minutes++;
  }
   if(ten_minutes>=6)
  {
  ten_minutes=0;
  hours++;
  }
  if(hours>=10)
  {
  hours=0;
  ten_hours++;
  }
  if(ten_hours>=2&&hours==4)
  {
  ten_hours=0;
  hours=0; 
  } 
 }


void main(void)
{
PORTB=0x07;
DDRB=0x00; 
PORTC=0x00;
DDRC=0x1F;
PORTD=0x00;
DDRD=0b11111111;

ASSR=0b00001000;      // таймер в асинхронном режиме
TCCR2=0b00000110;     // делитель
TCNT2=0x00;
OCR2=127;             // регистр сравнения
TIMSK=0b10000000;
#asm("sei")           // глобально разрешаем прерывания


while (1)
{
 //динамическая индикация             
 PORTC.0=1;                  // первый разряд, десятки часов
 PORTD=display[ten_hours];
 delay_ms(1);
 PORTC.0=0;
 
 PORTC.1=1;                  // второй разряд, единици часов
 PORTD=display[hours];
 delay_ms(1);
 PORTC.1=0;
 
 PORTC.2=1;                     //третий разряд, десятки минут
 PORTD=display[ten_minutes];
 delay_ms(1);
 PORTC.2=0;
 
 PORTC.3=1;                   // четвертый разряд, единици минут
 PORTD=display[minutes];
 delay_ms(1);
 PORTC.3=0;
 
 PORTC.4=1;                    // пятый разряд, десятки секунд
 PORTD=display[ten_seconds];
 delay_ms(1);
 PORTC.4=0;
 
 PORTC.5=1;                    //шестой разряд, единици секунд
 PORTD=display[seconds];
 delay_ms(1);
 PORTC.5=0;       
                            
}
}
Цепляю схему по которой собирал
Кст. на схеме резисторы по 20к
Вложения
1.jpg
Схема
(208.17 КБ) 433 скачивания
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

sanyo.95 писал(а):Часы не идут
Вроде как на первый взгляд, все почти верно, должны тикать (правда мне кажется, 2 раза в секунду при выбранном делителе)
Я использую прерывание по переполнению, т.е. предделитель на 128 на 32768 даст 256 тиков в секунду, что даст 1 прерывание по переполнению в секунду.
Вот код, который я использую:

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

TIMSK &=~(1<<OCIE2 | 1<< TOIE2);	// Запрещаем прерывания таймера 2
ASSR  = 1<<AS2;				// Включаем асинхронный режим
TCNT2 = 0;
TCCR2 = 5<<CS20; 			// Предделитель на 128 на 32768 даст 256 тиков в секунду
					// Что даст 1 прерывание по переполнению в секунду.

while(ASSR & (1<<TCN2UB | 1<<OCR2UB | TCR2UB));

TIFR  |= 1<<OCF2 | 1<< TOV2;		// Сбрасываем флаги прерываний, на всякий случай.

TIMSK |= 1<< TOIE2 | 1<<TOIE0;	// Нулевой таймер для индикации

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

// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void) {
  seconds++; normalize();  
}

Конденсаторы у кварца в наличии? Сам кварц заземлен?
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Спасибо за наводящие кусочки кода, я так понимаю эта строка

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

while(ASSR & (1<<TCN2UB | 1<<OCR2UB | TCR2UB));
и есть та самая буферизация. Это все (кроме прерывания) пихать в основную функцию? Код написан не в CVAVR? Первый раз вижу

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

normalize();
metan писал(а):Конденсаторы у кварца в наличии? Сам кварц заземлен?
Нет, ничего этого не делал. Прочитал где-то, что к часовому кварцу конденсаторы не нужны, видимо не хорошие люди написали... А что, из за того что корпус не на земле, часы могут не работать? :oops:

Еще, перепутал я резисторы на питание сеток - поставил по 500 ом, может ли в этом быть причина?

Сейчас нет возможности проверить все подозрения переношу на завтра.
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

sanyo.95 писал(а):и есть та самая буферизация
Нет, это проверка на то, что кварцевый генератор запустился.
Ссылку на необходимость такого шага я давал выше (статья DI HALT)

normalize(); - это я выделил в функцию вот это:

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

   if(seconds>=10)
  {
   seconds=0;
   ten_seconds++;
  }
  if(ten_seconds>=6)
  {
  ten_seconds=0;
  minutes++;
  }
  if(minutes>=10)
  {
  minutes=0;
  ten_minutes++;
  }
   if(ten_minutes>=6)
  {
  ten_minutes=0;
  hours++;
  }
  if(hours>=10)
  {
  hours=0;
  ten_hours++;
  }
  if(ten_hours>=2&&hours==4)
  {
  ten_hours=0;
  hours=0;
sanyo.95 писал(а):Это все (кроме прерывания) пихать в основную функцию?
Да. Перед главным циклом
sanyo.95 писал(а): Код написан не в CVAVR?
Да. Это не относится к среде. Это просто язык Си.
TCN2UB, OCR2UB и TCR2UB - это макроопределения, т.е. просто числа - соответствующие номерам битов, взятые из даташита. Это не обязательно, просто сильно упрощает понимание и читабельность кода.
Эти 2 записи эквивалентны:
TCCR2 = 5<<CS20;
и
TCCR2 = 0b00000110;

Насчет кварцев, такое мутное дело. Теоретически, если запрограммировать фьюз CKOPT, они как бы не нужны. Но иногда фигвам (См. Errata)
Я всегда ставлю.
Вот еще статейка
http://www.getchip.net/posts/052-kak-za ... -32768-gc/
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

metan, большое спасибо за столь понятный ответ! Заземлил кварц, впаял конденсаторы, заменил резисторы и ничего не изменилось :( Переписал программу, просто для вывода на индикатор циферок - увидел те же ноли! Похоже что-то с монтажом... или может ULN2803?
Вымогатель припоя
Сообщения: 602
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

sanyo.95 писал(а):Похоже что-то с монтажом... или может ULN2803?
Если бы с ULN2803 что-то было, тогда бы не нолики были, а восьмерки :)
Для проверки, как работает ULN2803 и индикатор, попробуйте просто включить 1 разряд и один сегмент (вовсе без динамической индикации), и зациклиться.
Хотя бы можно после этого тестером полазить.
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

metan писал(а):попробуйте просто включить 1 разряд и один сегмент (вовсе без динамической индикации), и зациклиться
Большое спасибо за совет, завтра попробую и отпишусь...
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

Пробовал выводить просто цифры в определенный разряд - удачно. Также инкремент переменной по прерыванию от ТС2 выводил - тоже удачно. Только вот почему-то засвечиваються соседние сегменты, очень плохо видно цифры.
Часы все равно не идут. В чем тут может быть проблема?
afz
Опытный кот
Аватара пользователя
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

Сообщение afz »

Вообще-то этими ИВЛ-ками надо управлять посредством p-канальных полевичков. Есть у IR, допустим, сборки из двух P-канальных полевичков в SO8, вот их - в самый раз. Истоки полевиков цепляем к +5 В, затворы - к выходам МК, а стоки - к анодам и сеткам. Катод/подогреватель надо кормить ВЧ напряжением с отдельной обмоточки трансика, на ее среднюю точку подать минус столько вольт, сколько нужно - чтобы яркость была подходящей. Этот минус можно получить, выпрямив напряжение с другой обмоточки того же трансика. Всего надо 7+6+(сколько-то на точки/двоеточия и т.п) транзисторов, т.е. 7-8 шт. сборок.

У нас когда-то выпускались м/с К161КН2 - это специальный набор ключейдля управления ИВЛ, но, во-первых, их сейчас уже не найдешь, а если и найдешь, так у них управление минимум 9В, лучше 12В.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Нашел транзистор. Понюхал.
Сообщения: 170
Зарегистрирован: Вс мар 30, 2014 21:41:24
Откуда: Украина

Сообщение sanyo.95 »

afz писал(а):Вообще-то этими ИВЛ-ками надо управлять посредством p-канальных полевичков.
Спасибо за ответ. Вы хотите сказать что нету другого работоспособного выхода?
Ответить

Вернуться в «AVR»