Часы с будильником
|
|
mikhail09p |
Дата: Пт, 15.07.2011, 20:41 | Сообщение # 16 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
Этот проэкт один из моих первых, в последующих я делал не так коррекцию. Совет: корректируйте значение переменной BIG - часы спешат - увеличивать, отстают - уменьшать. Так правильней и точней.
|
|
|
|
proton |
Дата: Пт, 15.07.2011, 23:13 | Сообщение # 17 |
Группа:
Пользователи
Ранг:
Новенький
Сообщений:
16
Замечания:
±
На сайте с 13.07.2011
Статус:
Offline
|
Quote (mikhail09p) Этот проэкт один из моих первых, в последующих я делал не так коррекцию. Совет: корректируйте значение переменной BIG - часы спешат - увеличивать, отстают - уменьшать. Так правильней и точней. Спасибо.Добавлено (15.07.2011, 23.13.12) --------------------------------------------- Device = 16F874A Declare Xtal=4 Declare Optimiser_Level =0
'-------------------------- Настройки подключения ЖКИ ------------------------ Declare LCD_Type ALPHA ' Тип ЖКИ - буквенно -цифровой Declare LCD_DTPin PORTD.4 ' Порт данных ЖКИ Declare LCD_ENPin PORTD.3 ' Управление линией E Declare LCD_RSPin PORTD.2 ' Управление линией RS Declare LCD_Interface 4 ' Разрядность шины данных LCD_CommandUs = 2000 ' Задать паузу между передачей команд на ЖКИ LCD_DataUs = 50 ' Задать паузу между передачей данных на ЖКИ Declare LCD_Lines 2 ' Количество строк ЖКИ '-------------------------- Настройки портов --------------------------------- Symbol RBIF = INTCON.0 ;RB Port Interrupt Flag Symbol INTF = INTCON.1 ; RB0 External Interrupt Flag Symbol T0IF = INTCON.2 ; TMR0 Overflow Interrupt Flag Symbol RBIE = INTCON.3 ; RB Port Change Interrupt Enable Symbol INTE = INTCON.4 ;RB0 External Interrupt Enable Symbol T0IE = INTCON.5 ; TMR0 Overflow Interrupt Enable Symbol PEIE = INTCON.6 ; Peripheral Interrupt Enable Symbol GIE = INTCON.7 ; Global Interrupt Enable Dim BIG As Dword 'переменная для счета секунд Dim BIG1 As BIG.HighWord Dim SECONDS As Byte ; переменная для счета секунд Dim MINUTES As Byte ; для счета минут ' Dim HOUR As Byte ; для счета часов ' Dim TEXT As Word Symbol VR=PORTB.0 ' Ввод времени или показ времени Symbol PLUS=PORTB.1 ' Плюс Symbol MINUS=PORTB.2 ' Минус Symbol VERH=PORTB.3 ' НИЗ Symbol NIZ=PORTB.4 ' ВВЕРХ Symbol payalo = PORTC.7 ' нагрузка
EData 5, 8, 15, 23, 0, 0, 0, 0, 18, 20, 19, 21, 17 Clear BIG = 1000000 ' Запишем в BIG 1000000 для отсчета секундных интервалов
On_Interrupt GoTo MYINT GoTo MAIN ; Переход на начало программы MYINT: ; Обработчик прерывания big1 = big1 -1 ' отнимаем единицу из старшего байта переменной BIG1 'то же самое, что и вычесть 65536 из BIG , но занимает меньше места If BIG < 0 Then 'Если BIG < 0 то значит прошла секунда BIG = BIG + 1000000 'К этому отрицательному числу прибавляем 1108292 Inc SECONDS 'Инкрементируем секунды EndIf T0IF = 0 ' сбросить флаг прерываний TOIF регистра TMRO Context Restore
MAIN: INTCON = %10100000 ; Enable global interrupts, peripheral interrupts OPTION_REG = %00000111 TRISB = %1111111 TRISC = %0011111 loop: If SECONDS =60 Then ; eie?aiaioe?oai a?aiy SECONDS=0 Inc MINUTES ; +ieioou If MINUTES=60 Then MINUTES=0 SECONDS=0 Inc HOUR ; +?ANU If HOUR=24 Then HOUR=0 EndIf EndIf EndIf If VR=0 Then VREMYA Print At 1,1,Dec2 HOUR, ":", Dec2 MINUTES, ":", Dec2 SECONDS GoTo loop VREMYA: If VERH=0 Then Inc HOUR If HOUR = 24 Then HOUR=0 EndIf ElseIf NIZ=0 Then Inc MINUTES If MINUTES =60 Then MINUTES=0 EndIf EndIf Print At 1,1,"установка часов" Print At 2,1, Dec2 HOUR, ":", Dec2 MINUTES," " DelayMS 300 Cls GoTo loop
TEXT1: CData ":", 0 TEXT2: CData ":", 0 Вот теперь есть режим установки часов, то есть кнопкой с фиксацией переключаем режим установки времени (нажали) или показ время (отпустили) Есть вопрос, как сделать что бы мигало ":" Перечитал команду print, ничего не нашел кроме мигания курсора, у меня с ним ничего не вышло.............
|
|
|
|
mikhail09p |
Дата: Сб, 16.07.2011, 07:16 | Сообщение # 18 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
Вводим битовую переменную t. В теле прерывания t = ~t - переменная каждую секунду будет изменять своё состояние 0 - 1. В теле программы IF t = 0 then TEXT = TEXT1 ELSE TEXT = TEXT2 ENDIF Print At 1,1,Dec2 HOUR, TEXT, Dec2 MINUTES, TEXT, Dec2 SECONDS ---------------------------- TEXT1: CData ":", 0 TEXT2: CData " ", 0 Как-то так Работает с 874 и т. д. с 628 не работает.
|
|
|
|
proton |
Дата: Вс, 17.07.2011, 18:38 | Сообщение # 19 |
Группа:
Пользователи
Ранг:
Новенький
Сообщений:
16
Замечания:
±
На сайте с 13.07.2011
Статус:
Offline
|
Quote (mikhail09p) mikhail09p большое спасибо Добавлено (17.07.2011, 18.38.17) --------------------------------------------- А чаще мигание ":" можно сделать.
|
|
|
|
mikhail09p |
Дата: Вс, 17.07.2011, 19:11 | Сообщение # 20 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
Можно. Есть минимум два способа: Первый. Сделать преривание не раз в секунду, а два раза в секунду, т. е. BIG = BIG + 500000 и, соответственно If SECONDS =120 Then SECONDS=0 Точки будут моргать в два раза чаще. Индикацию придётся убрать, а то 120 секунд в минуту как-то не катит Второй. В тело программы ввести дополнительную переменную, которая увеличивается на единицу каждый проход программы. Прикинуть в Протеусе время одного прохода программы и, исходя из этого, при достижении некоторого числа изменять ":" или " ". Примерно так: IF TIC > 100 THEN t = ~t: TIC = 0 ENDIF IF t = 0 then TEXT = TEXT1 ELSE TEXT = TEXT2 ENDIF Print At 1,1,Dec2 HOUR, TEXT, Dec2 MINUTES, TEXT, Dec2 SECONDS INC TIC ---------------------------- TEXT1: CData ":", 0 TEXT2: CData " ", 0
Вроде так, хотя надо пробывать Во втором случае трудновато добится моргания точек синхронно с изменением секунд, если это критично.
|
|
|
|
proton |
Дата: Вс, 17.07.2011, 20:04 | Сообщение # 21 |
Группа:
Пользователи
Ранг:
Новенький
Сообщений:
16
Замечания:
±
На сайте с 13.07.2011
Статус:
Offline
|
Спасибо. Device = 16F877A Declare Xtal=4 Declare Optimiser_Level =0
'-------------------------- Настройки подключения ЖКИ ------------------------ Declare LCD_Type ALPHA ' Тип ЖКИ - буквенно -цифровой Declare LCD_DTPin PORTD.4 ' Порт данных ЖКИ Declare LCD_ENPin PORTD.3 ' Управление линией E Declare LCD_RSPin PORTD.2 ' Управление линией RS Declare LCD_Interface 4 ' Разрядность шины данных LCD_CommandUs = 200 ' Задать паузу между передачей команд на ЖКИ LCD_DataUs = 50 ' Задать паузу между передачей данных на ЖКИ Declare LCD_Lines 2 ' Количество строк ЖКИ
'-------------------------- Настройки портов --------------------------------- Symbol RBIF = INTCON.0 ;RB Port Interrupt Flag Symbol INTF = INTCON.1 ; RB0 External Interrupt Flag Symbol T0IF = INTCON.2 ; TMR0 Overflow Interrupt Flag Symbol RBIE = INTCON.3 ; RB Port Change Interrupt Enable Symbol INTE = INTCON.4 ;RB0 External Interrupt Enable Symbol T0IE = INTCON.5 ; TMR0 Overflow Interrupt Enable Symbol PEIE = INTCON.6 ; Peripheral Interrupt Enable Symbol GIE = INTCON.7 ; Global Interrupt Enable Dim BIG As Dword 'переменная для счета секунд Dim BIG1 As BIG.HighWord Dim SECONDS As Byte ; переменная для счета секунд Dim MINUTES As Byte ; для счета минут ' Dim HOUR As Byte ; для счета часов ' Dim TEXT As Word Dim t As Bit Symbol VR=PORTB.0 ' Ввод значения Symbol PLUS=PORTB.1 ' Плюс Symbol MINUS=PORTB.2 ' Минус Symbol VERH=PORTB.3 ' НИЗ Symbol NIZ=PORTB.4 ' ВВЕРХ Symbol payalo = PORTC.7 ' нагрузка
EData 5, 8, 15, 23, 0, 0, 0, 0, 18, 20, 19, 21, 17 Clear BIG = 1000000 ' Запишем в BIG 1000000 для отсчета секундных интервалов
On_Interrupt GoTo MYINT GoTo MAIN ; Переход на начало программы
MYINT: ; Обработчик прерывания big1 = big1 -1 ' отнимаем единицу из старшего байта переменной BIG1 'то же самое, что и вычесть 65536 из BIG , но занимает меньше места If BIG < 0 Then 'Если BIG < 0 то значит прошла секунда BIG = BIG + 1000000 'К этому отрицательному числу прибавляем 1108292 Inc SECONDS 'Инкрементируем секунды
t = ~t EndIf
T0IF = 0 ' сбросить флаг прерываний TOIF регистра TMRO Context Restore
MAIN: INTCON = %10100000 ; Enable global interrupts, peripheral interrupts OPTION_REG = %00000111 TRISB = %1111111 TRISC = %0011111
loop: If SECONDS =60 Then ; eie?aiaioe?oai a?aiy SECONDS=0 Inc MINUTES ; +ieioou If MINUTES=60 Then MINUTES=0 SECONDS=0 Inc HOUR ; +?ANU If HOUR=24 Then HOUR=0 EndIf EndIf EndIf If t = 0 Then TEXT = TEXT1 Else TEXT = TEXT1 Else TEXT = TEXT2 EndIf If VR=0 Then VREMYA If MINUS=1 Then time
Print At 1,1,Dec2 HOUR, CStr TEXT, Dec2 MINUTES, CStr TEXT, Dec2 SECONDS
GoTo loop
VREMYA: If VERH=1 Then Inc HOUR
HOUR=0 EndIf If NIZ=0 Then Inc MINUTES
MINUTES=0 EndIf
Print At 1,1,"установка часов" Print At 2,1,Dec2 HOUR, CStr TEXT, Dec2 MINUTES," " DelayMS 300 Cls GoTo loop
time: If MINUS=0 Then Inc HOUR If HOUR = 24 Then HOUR=0 EndIf ElseIf NIZ=0 Then Inc MINUTES If MINUTES =60 Then MINUTES=0 EndIf EndIf Disable ' Запретить программные прерывания payalo = 0 ' Переключить светодиод в противоположное состояние INTCON.2 = 0 ' Сбросить флаг прерываний от таймера Resume Print At 1,1,"установка таймера" Print At 2,1,Dec2 HOUR, CStr TEXT, Dec2 MINUTES," " TEXT1: CData ":", 0 TEXT2: CData " ", 0 объясните пожалуйста где я неправильно написал прерывания для таймера
Сообщение отредактировал
proton - Вс, 17.07.2011, 20:05
|
|
|
|
mikhail09p |
Дата: Вс, 17.07.2011, 21:54 | Сообщение # 22 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
Зачем это в теле программы? INTCON.2 = 0 ' Сбросить флаг прерываний от таймера
И ведь есть Symbol T0IF = INTCON.2 ; флаг прерывания таймера TMR0
И вообще, зачем это? Disable ' Запретить программные прерывания payalo = 0 ' Переключить светодиод в противоположное состояние INTCON.2 = 0 ' Сбросить флаг прерываний от таймера Resume
Прерывания обрабатываются в теле обработчика прерываний, а не в теле основной программы.
Сообщение отредактировал
mikhail09p - Вс, 17.07.2011, 21:55
|
|
|
|
proton |
Дата: Вс, 17.07.2011, 23:15 | Сообщение # 23 |
Группа:
Пользователи
Ранг:
Новенький
Сообщений:
16
Замечания:
±
На сайте с 13.07.2011
Статус:
Offline
|
Объясните пожалуйста по подробней что я не так сделал. Немного сложней даются мне эти таймеры. Желательно на живом примере...........
|
|
|
|
mikhail09p |
Дата: Пн, 18.07.2011, 13:04 | Сообщение # 24 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
DAlexV писал: нужно соблюдать некоторую последовательность для обработчика прерывания. Тогда все пойдет по сценарию. Первое. Ловим в обработчике источник прерывания . В данном случае TMR1. Если произошло прерывание от TMR1, первым делом сбросили флаг прерывания, обновили значение таймера(что бы начался новый отсчет) а после уже выполнять все действия сложения(вычитания) какие требуются программе.
И прерывания обрабатываются в теле обработчика прерываний, а не в теле основной программы. А вы сбрасываете флаг прерывания в теле программы INTCON.2 = 0 ' Сбросить флаг прерываний от таймера
Команда Resume предназначена для того, чтобы вновь разрешить обработку возникающих прерываний ранее запрещенных командой Disable, поэтому она должна располагаться в конце подпрограммы обработки прерывания. http://www.terrarus.ucoz.ru/proton_....me.html Есть прекрасный учебник http://www.terrarus.ucoz.ru/proton_plus_ide/index.html
Сообщение отредактировал
mikhail09p - Пн, 18.07.2011, 13:06
|
|
|
|
proton |
Дата: Пн, 18.07.2011, 13:09 | Сообщение # 25 |
Группа:
Пользователи
Ранг:
Новенький
Сообщений:
16
Замечания:
±
На сайте с 13.07.2011
Статус:
Offline
|
Спасибо, буду разбираться. Я этот учебник изучаю.
|
|
|
|
mikhail09p |
Дата: Пн, 18.07.2011, 13:47 | Сообщение # 26 |
Группа:
Проверенные
Ранг:
Помогаю всем
Сообщений:
481
Замечания:
±
На сайте с 04.05.2010
Статус:
Offline
|
proton, Вы объясните, чего хотите сделать. Вы, как я понял, хотите изменЯть значение переменной BIG ? И выкладывайте весь Ваш проект, я же не знаю Вашу схему.
|
|
|
|