Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Готовые конструкции » Часы на атмега 8 очень простые


Часы на атмега 8 очень простые

Сообщений 1 страница 4 из 4

1

С выходом четвертой прошивки решил оформить устройства как готовую конструкцию
Прошивки, схемы, схема в протеусе  тут http://yadi.sk/d/NdL20F2HnxpnH
Плюшки 4й прошивки:
1. Поддержка общего анода и катода
2. Понижено потребление и тактовая частота меги до 1 мГц
3. Добавлен режим работы от батареи с выключенным индикатором. При нажатии на кнопку время показывается 2 секунды. Потребление в дежурном режиме составляет 10 микроампер.
4. Добавлены новые элементы схемы. Возможность подключить разряды индикации секунд.
5. Устранены все проблемы с точками. Они теперь мигают или горят там где нужно а не везде.

Схема под новую прошивку:
Все что пунктиром на схеме можно не ставить.
http://s2.uploads.ru/t/pRToM.jpg

Вот первоначальная схема:
http://s7.uploads.ru/t/ZURM2.jpg
Прошивка v.4 совместима с данной схемой. Главное чтоб 18 и 19 нога контроллера висели в воздухе.
Привожу код второй прошивки которая совместима только с первоначальной схемой т.к. считаю его самым простым и вылизанным до блеска. Код для общего минуса.

Код:
'Автор Авраменко Павел.
$regfile = "m8def.dat"                                      ' мега8
$crystal = 8000000 'частота тактирования камня.
Config Portb = Output , Portd = Output : Portc = &H30 'Конфигурируем порты на входы и выходы. Включаем внутренние подтягивающие резисторы
Dim X As Byte , Cifri(4) As Byte                            'задаем всякие переменные и масивы
Config Clock = Soft                                         ' конфигурируем совтовые часы которые будут подсчитывать колебания часового кварца и раз в секунду вызывать прерывания.
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse : Enable Timer0 : Enable Interrupts       ' конфигурируем таймер 0 чтоб потом на него повесить алгоритм отображения цифр. Назначаем подпрограмму, которая будет запускаться по переполнению 0го таймера
 Do          ' основной бесконечный цикл в котором идет опрос кнопок
If Pinc.4 = 0 Then ' Если кнопка нажата то запускаем бесконечный цикл
Do
 Incr _min : _sec = 00 : Timer2=0           ' добавляем к минутам 1. Секунды =0. Все что наклацал таймер 2 тоже обнуляем
 If _min > 59 Then : _min = 00 : Incr _hour : End If : If _hour > 23 Then _hour = 00 : Waitms 100 ' счетчик + задержка
Loop Until Pinc.4 = 1         ' если кнопку отпустили то выходим из бесконечного цикла
End If
If Pinc.5 = 0 Then 'Если кнопка "Часы" нажата то запускаем бесконечный цикл
    Do
    Incr _hour : If _hour > 23 Then _hour = 00 : Waitms 100 ' счетчик
    Loop Until Pinc.5 = 1  ' если кнопку отпустили то выходим из бесконечного цикла
End If
  Loop                                                      'конец основного цикла
Pulse:                                                      ' подпрограмма прерываний таймера0
Cifri(1) = _min Mod 10 : Cifri(2) = _min / 10 : Cifri(3) = _hour Mod 10 : Cifri(4) = _hour / 10 ' разбиваем минуты на два отдельных числа, тоже делаем и с часами. Все записываем в масив
Portb = &HFF  'гасим индикатор подав на общие выводы плюс. Для индикатора с общим плюсом нужно заменить &HFF на ноль.
Incr X : If X > 3 Then X = 0 ' переменная определяющая какой индикатор зажечь
Portd = Lookup(cifri(x + 1) , Dta) 'присваиваем индикатору с номером х (из предыдущей строки) символ из строки Dta
Reset Portb.x 'зажигаем индикатор х
Return                                                      '  возвращаемся на место откуда прервали программу
       Dta:                                                 '  таблица с данными о цифрах зажигает по порядку : 0123456789
       Data &HEF , &H8C , &HB7 , &HBE , &HDC , &H7E , &H7F , &HAC , &HFF , &HFE 'для общего плюса закомментировать
'       Data &H10 , &H73 , &H48 , &H41 , &H23 , &H81 , &H80 , &H53 , &H0 , &H1 'для общего плюса раскомментировать
Код:
'4я прошивка для очень простых часов с общим минусом и мигающей точкой после часов
'Автор Авраменко Павел.
'e-mail p-a-h-a@yandex.ru
'youtube http://www.youtube.com/c/Happinesstoom
$map
$regfile = "m8def.dat"                                      ' мега8
$crystal = 1000000                                          ' частота кристала 1 мегагерц
Ddrb = &B00111111 : Portb = &B11110000 : Ddrd = &B11111111 : Portc = &B11110011       ' конфигурируем порты на ввод и выввод(правая цифра это нулевой порт/пин к примеру PORTB.0), подтягиваем входные лапы к + питания внутренними резисторами, кроме С.3 для детектирования сетевого блока питания и С.2 для подключения туда часовой батарейки
Dim I As Byte , X As Byte , Cifri(6) As Byte , Charge As Bit , Dp As Byte       'задаем всякие переменные и масивы
Config Clock = Soft
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse : Enable Timer0 : Enable Interrupts       ' конфигурируем таймер 0 чтоб потом на него повесить алгоритм отображения цифр ' назначаем подпрограмму, которая будет запускатся по переполнению 1го таймера
Mcucr = &HB0                                                ' Разрешаем режим пониженного энергопотребления  Power Save
Homepoint:
Do                                                          'Основной бесконечный цикл опроса кнопок и настройки времени
   If Pinc.4 = 0 Then : Waitms 500                          'если нажата кнопка "Минуты" то ждем пол секунды а вдруг вторую кнопку нажмут
      If Pinc.5 = 0 Then Goto Sleeps                        'если сначала нажата кнопка "минуты" и в течении 0,5 сек "часы" то идем в режим работы от батареек с выключенным дисплеем
      Do
         Incr _min : Timer2 = 0 : _sec = 00                 ' Ну А Когда Кнопку С "часы не нажали увеличиваем минуты на 1, секунды сбрасываем на 00"
         If _min > 59 Then : _min = 00 : Incr _hour : End If       'если минуты достигли 60 то сбрасываем их на 00 и прибавляем к часам 1 час
         If _hour > 23 Then _hour = 00 : Waitms 100         ' если часы достигли 24 то сбрасываем их к 00
      Loop Until Pinc.4 = 1                                 ' повторяем добавление минут пока не отпустят кнопку "Минуты"
   End If

   If Pinc.5 = 0 Then : Waitms 500                          ' Если нажата кнопка часы то ждем а не нажмут ли кнопку "минуты"
      If Pinc.4 = 0 Then : Set Charge : Goto Battery : End If       'если сначала нажата кнопка "часыы" и в течении 0,5 сек "минуты" то выставляем или убираем флаг и идем в режим работы от батареек с выключенным дисплеем и ждем пока дадут электричество чтоб вернутся в основной цикл
      Do
         Incr _hour : If _hour > 23 Then _hour = 00 : Waitms 100       ' увеличиваем часы на 1, если часы достигли 24 то сбрасываем их на 00
      Loop Until Pinc.5 = 1
   End If

   If Pinc.3 = 0 And Charge = 1 Then Goto Battery           ' если включен режим ожидания напряжения от блока питания и часы работают от батареи то идем в режим работы от батареек с выключенным дисплеем и ждем пока дадут электричество чтоб вернутся в основной цикл
   Idle                                                     ' спим
Loop

Pulse:                                                      ' подпрограмма прерываний таймера0 для работы с семисегментником
   Cifri(1) = _min Mod 10 : Cifri(2) = _min / 10 : Cifri(3) = _hour Mod 10 : Cifri(4) = _hour / 10 : Cifri(6) = _sec Mod 10 : Cifri(5) = _sec / 10       ' расчитываем число каждого сегмента. например сейчас 08:56 последний сегмент = остаток от деления минут на 10 (56/10=6) предпоследний сегмент = минуты разделить на 10, а поскольку переменные целые то десятые исчезают в небытиё 56/10=5. С часами тоже самое остаток от 08/10 = 8. и просто разделить 08/10=0  таким образом получаем масив из 6,5,8,0 т.е. наоборот
   Portb = &HFF                                             ' Гасим все индикаторы
   Incr X : If X > 5 Then X = 0                             ' При каждом срабатывании таймера выбираем какой сегмент будем показывать от 0,1,2,3,4,5
   Portd = Lookup(cifri(x + 1) , Dta)                       'таблица DTA начинает считатся с первой ячейки. А поскольку значение времени может быть 0 то прибавляем единицу. Х сейчас равен 1 поэтому берем масив Х+1 т.е cifri(2). Выше мы считали что Cifri(2) = _min / 10 и это = 5 а поскольку тут мы прибавили 1 то берем шестой элемент таблицы DTA который выведет на семисегментник цифру 5. (когда дойдем до часов и нужно будет отобразить 0 (Cifri(4) = _hour / 10) то выберется элемент таблицы с порядковым номером 0+1=1 т.е первый элемент &HEF.
   If X = 2 Then Set Portd.2 Else Reset Portd.2             'включаем точку на втором сегменте для моего индикатора нужно закоментировать
   Dp = _sec Mod 2 : If Dp = 1 And X = 2 Then Set Portd.2 Else Reset Portd.2       'включаем точку и мигаем ею на втором сегменте
   Reset Portb.x                                            'поскольку индикатор у меня подключен с общим минусом то выше мы его погасили подав на все общие провода плюс ( логическую единицу в строкеPortb = &HFF) теперь мы зажигаем сегмент с порядковым номером Х который сейчас равен 1
Return                                                      '  возвращаемся на место откуда прервали программу
       Dta:                                                 '  таблица с данными о цифрах зажигает по порядку : 0123456789. Порядковый номер столбцов таблицы начинается с 1... т.е 1,2,3,4,5,6,7,8,9,10
       Data &HEF , &H8C , &HB7 , &HBE , &HDC , &H7E , &H7F , &HAC , &HFF , &HFE
'             0.     1.     2.     3.     4.     5.     6.     7.      8.    9. то что отображается на семисегментнике
Sleeps:                                                     'программа режима работы от батареек
   Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : Wait 2       ' отключаем индикатор, ждем 2 секунды чтоб успеть отпустить кнопки
   Do                                                       'Начало бесконечного цикла этого режима
      If Pinc.4 = 0 Then : Start Timer0 : Wait 2 : Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : End If       ' при нажатой кнопке "минуты" включаем индикатор и отображаем текущее время
      If Pinc.5 = 0 Then : Start Timer0 : Wait 2 : Goto Homepoint : End If       ' Если Нажали Кнопку "Часы то включаем индикатор, ждем 2 секунды чтобы успеть отпустить кнопку и возвращаемся в основной цикл где индикатор всегда горит и можно настроить время."
      Power Powersave                                       ' погружаемся в сон для уменьшения энергопотребления
   Loop                                                     'конец бесконечного цикла
Return

Battery:                                                    ' программа работы при пропадании сетевого питания. В ней гасятся индикаторы и она ждет появления питания
   Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : Wait 2       ' отключаем индикатор, ждем 2 секунды чтоб успеть отпустить кнопки
   Do
      If Pinc.4 = 0 Then : Start Timer0 : Wait 2 : Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : End If       ' при нажатой кнопке "минуты" включаем индикатор и отображаем текущее время
      If Pinc.3 = 1 Then : Start Timer0 : Wait 2 : Goto Homepoint : End If ' Если появилось питание - включаем индикатор и уходим в основной цикл
      If Pinc.5 = 0 Then : Start Timer0 : Reset Charge : Wait 2 : Goto Homepoint : End If ' Если Нажали Кнопку "Часы" Или Появилось Питание На Pinc.3 То Включаем Индикатор , Ждем 2 Секунды Чтобы Успеть Отпустить Кнопку И Возвращаемся В Основной Цикл Где Индикатор Всегда Горит И Можно Настроить Время. "
      Power Powersave                                       ' погружаемся в сон для уменьшения энергопотребления
   Loop
Return

Конвертор семисигментного индикатора в HEX. Для случаев когда индикатор подключен не так как на схеме http://pichobby.lg.ua/download/program/ … ledx8.html

Отредактировано Pasha (2016-11-22 00:32:59)

+1

2

А у меня тоже на атмега, только не простые.


+2

3

Решил поделится исходником 4й прошивки для варианта с общим минусом и мигающей точкой после часов. Остальные точки не горят.

Код:
'4я прошивка для очень простых часов с общим минусом и мигающей точкой после часов
'Автор Авраменко Павел.
'e-mail p-a-h-a@yandex.ru
'youtube http://www.youtube.com/c/Happinesstoom
$map
$regfile = "m8def.dat"                                      ' мега8
$crystal = 1000000                                          ' частота кристала 1 мегагерц
Ddrb = &B00111111 : Portb = &B11110000 : Ddrd = &B11111111 : Portc = &B11110011       ' конфигурируем порты на ввод и выввод(правая цифра это нулевой порт/пин к примеру PORTB.0), подтягиваем входные лапы к + питания внутренними резисторами, кроме С.3 для детектирования сетевого блока питания и С.2 для подключения туда часовой батарейки
Dim I As Byte , X As Byte , Cifri(6) As Byte , Charge As Bit , Dp As Byte       'задаем всякие переменные и масивы
Config Clock = Soft
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse : Enable Timer0 : Enable Interrupts       ' конфигурируем таймер 0 чтоб потом на него повесить алгоритм отображения цифр ' назначаем подпрограмму, которая будет запускатся по переполнению 1го таймера
Mcucr = &HB0                                                ' Разрешаем режим пониженного энергопотребления  Power Save
Homepoint:
Do                                                          'Основной бесконечный цикл опроса кнопок и настройки времени
   If Pinc.4 = 0 Then : Waitms 500                          'если нажата кнопка "Минуты" то ждем пол секунды а вдруг вторую кнопку нажмут
      If Pinc.5 = 0 Then Goto Sleeps                        'если сначала нажата кнопка "минуты" и в течении 0,5 сек "часы" то идем в режим работы от батареек с выключенным дисплеем
      Do
         Incr _min : Timer2 = 0 : _sec = 00                 ' Ну А Когда Кнопку С "часы не нажали увеличиваем минуты на 1, секунды сбрасываем на 00"
         If _min > 59 Then : _min = 00 : Incr _hour : End If       'если минуты достигли 60 то сбрасываем их на 00 и прибавляем к часам 1 час
         If _hour > 23 Then _hour = 00 : Waitms 100         ' если часы достигли 24 то сбрасываем их к 00
      Loop Until Pinc.4 = 1                                 ' повторяем добавление минут пока не отпустят кнопку "Минуты"
   End If

   If Pinc.5 = 0 Then : Waitms 500                          ' Если нажата кнопка часы то ждем а не нажмут ли кнопку "минуты"
      If Pinc.4 = 0 Then : Set Charge : Goto Battery : End If       'если сначала нажата кнопка "часыы" и в течении 0,5 сек "минуты" то выставляем или убираем флаг и идем в режим работы от батареек с выключенным дисплеем и ждем пока дадут электричество чтоб вернутся в основной цикл
      Do
         Incr _hour : If _hour > 23 Then _hour = 00 : Waitms 100       ' увеличиваем часы на 1, если часы достигли 24 то сбрасываем их на 00
      Loop Until Pinc.5 = 1
   End If

   If Pinc.3 = 0 And Charge = 1 Then Goto Battery           ' если включен режим ожидания напряжения от блока питания и часы работают от батареи то идем в режим работы от батареек с выключенным дисплеем и ждем пока дадут электричество чтоб вернутся в основной цикл
   Idle                                                     ' спим
Loop

Pulse:                                                      ' подпрограмма прерываний таймера0 для работы с семисегментником
   Cifri(1) = _min Mod 10 : Cifri(2) = _min / 10 : Cifri(3) = _hour Mod 10 : Cifri(4) = _hour / 10 : Cifri(6) = _sec Mod 10 : Cifri(5) = _sec / 10       ' расчитываем число каждого сегмента. например сейчас 08:56 последний сегмент = остаток от деления минут на 10 (56/10=6) предпоследний сегмент = минуты разделить на 10, а поскольку переменные целые то десятые исчезают в небытиё 56/10=5. С часами тоже самое остаток от 08/10 = 8. и просто разделить 08/10=0  таким образом получаем масив из 6,5,8,0 т.е. наоборот
   Portb = &HFF                                             ' Гасим все индикаторы
   Incr X : If X > 5 Then X = 0                             ' При каждом срабатывании таймера выбираем какой сегмент будем показывать от 0,1,2,3,4,5
   Portd = Lookup(cifri(x + 1) , Dta)                       'таблица DTA начинает считатся с первой ячейки. А поскольку значение времени может быть 0 то прибавляем единицу. Х сейчас равен 1 поэтому берем масив Х+1 т.е cifri(2). Выше мы считали что Cifri(2) = _min / 10 и это = 5 а поскольку тут мы прибавили 1 то берем шестой элемент таблицы DTA который выведет на семисегментник цифру 5. (когда дойдем до часов и нужно будет отобразить 0 (Cifri(4) = _hour / 10) то выберется элемент таблицы с порядковым номером 0+1=1 т.е первый элемент &HEF.
   If X = 2 Then Set Portd.2 Else Reset Portd.2             'включаем точку на втором сегменте для моего индикатора нужно закоментировать
   Dp = _sec Mod 2 : If Dp = 1 And X = 2 Then Set Portd.2 Else Reset Portd.2       'включаем точку и мигаем ею на втором сегменте
   Reset Portb.x                                            'поскольку индикатор у меня подключен с общим минусом то выше мы его погасили подав на все общие провода плюс ( логическую единицу в строкеPortb = &HFF) теперь мы зажигаем сегмент с порядковым номером Х который сейчас равен 1
Return                                                      '  возвращаемся на место откуда прервали программу
       Dta:                                                 '  таблица с данными о цифрах зажигает по порядку : 0123456789. Порядковый номер столбцов таблицы начинается с 1... т.е 1,2,3,4,5,6,7,8,9,10
       Data &HEF , &H8C , &HB7 , &HBE , &HDC , &H7E , &H7F , &HAC , &HFF , &HFE
'             0.     1.     2.     3.     4.     5.     6.     7.      8.    9. то что отображается на семисегментнике
Sleeps:                                                     'программа режима работы от батареек
   Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : Wait 2       ' отключаем индикатор, ждем 2 секунды чтоб успеть отпустить кнопки
   Do                                                       'Начало бесконечного цикла этого режима
      If Pinc.4 = 0 Then : Start Timer0 : Wait 2 : Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : End If       ' при нажатой кнопке "минуты" включаем индикатор и отображаем текущее время
      If Pinc.5 = 0 Then : Start Timer0 : Wait 2 : Goto Homepoint : End If       ' Если Нажали Кнопку "Часы то включаем индикатор, ждем 2 секунды чтобы успеть отпустить кнопку и возвращаемся в основной цикл где индикатор всегда горит и можно настроить время."
      Power Powersave                                       ' погружаемся в сон для уменьшения энергопотребления
   Loop                                                     'конец бесконечного цикла
Return

Battery:                                                    ' программа работы при пропадании сетевого питания. В ней гасятся индикаторы и она ждет появления питания
   Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : Wait 2       ' отключаем индикатор, ждем 2 секунды чтоб успеть отпустить кнопки
   Do
      If Pinc.4 = 0 Then : Start Timer0 : Wait 2 : Stop Timer0 : Timer0 = 0 : Portb = 0 : Portd = 0 : End If       ' при нажатой кнопке "минуты" включаем индикатор и отображаем текущее время
      If Pinc.3 = 1 Then : Start Timer0 : Wait 2 : Goto Homepoint : End If ' Если появилось питание - включаем индикатор и уходим в основной цикл
      If Pinc.5 = 0 Then : Start Timer0 : Reset Charge : Wait 2 : Goto Homepoint : End If ' Если Нажали Кнопку "Часы" Или Появилось Питание На Pinc.3 То Включаем Индикатор , Ждем 2 Секунды Чтобы Успеть Отпустить Кнопку И Возвращаемся В Основной Цикл Где Индикатор Всегда Горит И Можно Настроить Время. "
      Power Powersave                                       ' погружаемся в сон для уменьшения энергопотребления
   Loop
Return

+1

4

Pasha
Спасибо за часы. Собрал, работают нормально. Захотелось чуть изменить 4 прошивку. Но не осилил конвертор семисигментного индикатора в HEX, хотя вроде там нет ничего сложного. Если не сложно, выложи пожалуйста исходник 4 прошивки с общим анодом (общий плюс). Заранее тебе спасибо!

0


Вы здесь » Программирование ATMEL в BASCOM. » Готовые конструкции » Часы на атмега 8 очень простые