Device = 16F628A Declare Xtal=4 ;Declare Optimiser_Level =1 TRISB = %00000000 TRISA = %00000000 Config XT_OSC , WDT_OFF , PWRTE_ON , BODEN_OFF , LVP_OFF , CP_OFF , MCLRE_OFF 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 BIG2 As Dword Dim Kor_Clock As Word Dim BIG1 As BIG.HighWord Dim bres_hi As Byte ; Старший байт нашей 24-битной переменной Dim bres_mid As Byte ; Средний байт Dim bres_lo As Byte ; Младший байт Dim TimeDelCount As Byte ; переменная для цикла отображения времени Dim DigitDisp As Byte ; Для результата табличного преобразования Dim SECONDS As Byte ; переменная для счета секунд Dim SECOND As Byte Dim MINUTES As Byte ; для счета минут Dim HOUR As Byte ; для счета часов Dim SETMINUTES As Byte ; для установки минут Dim SETHOUR As Byte ;для установки часов Dim t As Bit Dim SEC As Bit Dim A As Word Dim BitKorr As Bit Symbol ButtHour = PORTA.3 'кнопка установки часов Symbol ButtMin = PORTA.2 'кнопка установки минут Symbol ButtSec = PORTA.1 'кнопка установки секунд All_Digital=1 TimeDelCount = ERead 0 If TimeDelCount = 1 Then Kor_Clock = ERead 1 Else Kor_Clock = 4000 EWrite 1, [Kor_Clock] ' ii oiie?aie? eee a?oaia ?enei!!!! EWrite 0, [1] EndIf BIG2 = 996000 + Kor_Clock ' Caieoai a BIG 1000000 aey ion?aoa naeoiaiuo eioa?aaeia BIG = BIG2 TimeDelCount = 0 On_Interrupt GoTo MYINT GoTo MAIN ; Переход на начало программы MYINT: ; Обработчик прерывания big1 = big1 -1 ' отнимаем единицу из старшего байта переменной BIG1 'то же самое, что и вычесть 65536 из BIG , но занимает меньше места If BIG < 0 Then BIG = BIG + BIG2 : Inc SECONDS T0IF = 0 ' сбросить флаг прерываний TOIF регистра TMRO Context Restore MAIN: HOUR = 0 MINUTES = 0 ; Clear time SECONDS = 0 INTCON = %10100000 ; Enable global interrupts, peripheral interrupts PORTB = %00000000 PORTA = %00000000 OPTION_REG = %10000111 SECOND=SECONDS loop: TRISA = %00001110 If ButtMin =1 Or ButtHour = 1 Then IfPressButt 'если нажата какая-то кнопка, If ButtSec = 1 Then Secund loop2: TRISA = %00000000 If SECOND <> SECONDS Then If SEC=1 Then SEC=0 Else SEC=1 EndIf GoSub Clock EndIf GoSub DisplayTime ; то отображение времени GoTo loop ; начинаем сначала Secund: A=0 Secund1: DelayMS 200 While A<200 If ButtSec = 0 Then Secund2 Inc A Wend BitKorr = 1 GoTo Korr Secund2: PORTA=0 PORTB=0 A=0 While A <= 6500 TRISA=%00001110 If ButtSec = 1 Then lop: If ButtSec = 1 Then lop GoTo loop2 EndIf If ButtMin = 1 Or ButtHour = 1 Then If SECOND>30 Then Inc MINUTES SECONDS = 0 A=0 GoTo Secund EndIf Inc A TRISA = $00 PORTA = %00001000 PORTB = 146 ' "S" OR "c" PORTB = %10100111 DelayMS 4 PORTA = %00000100 PORTB = %10111111 GoSub Clock TRISA=0 DigitDisp = SECONDS Dig 1 PORTA = %00000010 GoSub LOOK DigitDisp = SECONDS Dig 0 PORTA = %00000001 GoSub LOOK Wend GoTo loop Korr: A=0 While A <= 6500 TRISA = %00001110 : PORTA = $00 If ButtSec = 0 Then BitKorr = 0 If ButtMin = 1 Then DelayMS 200 Inc Kor_Clock A = 0 EndIf If ButtHour = 1 Then DelayMS 200 Dec Kor_Clock A = 0 EndIf If ButtSec = 1 And BitKorr = 0 Then GoTo Ext Inc A TRISA = $00 : PORTA = $00 DigitDisp = Kor_Clock Dig 0 PORTA = %00000001 GoSub LOOK DigitDisp = Kor_Clock Dig 1 PORTA = %00000010 GoSub LOOK DigitDisp = Kor_Clock Dig 2 PORTA = %00000100 GoSub LOOK DigitDisp = Kor_Clock Dig 3 PORTA = %00001000 GoSub LOOK Wend Ext: EWrite 1, [Kor_Clock] ' ii oiie?aie? eee a?oaia ?enei!!!! EWrite 0, [1] BIG2 = 996000 + Kor_Clock ' Caieoai a BIG 1000000 aey ion?aoa naeoiaiuo eioa?aaeia GoTo loop Clock: SECOND=SECONDS If SECONDS=60 Then SECONDS=0 Inc MINUTES ; минуты If MINUTES=60 Then MINUTES=0 Inc HOUR ; ЧАСЫ If HOUR = 24 Then HOUR=0 EndIf EndIf EndIf Return IfPressButt: If ButtHour=1 Then SETHOUR=HOUR TRISA=00000000 Inc SETHOUR If SETHOUR > 23 Then SETHOUR=0 EndIf HOUR = SETHOUR ElseIf ButtMin=1 Then SETMINUTES=MINUTES TRISA=00000000 Inc SETMINUTES If SETMINUTES>59 Then SETMINUTES=0 EndIf MINUTES = SETMINUTES EndIf For TimeDelCount = 1 To 5 GoSub DispLoop ; медленное увеличение или уменьшение времени Next If ButtHour = 0 And ButtMin = 0 Then For TimeDelCount = 1 To 40 GoSub DispLoop ; задержка после окончания установки Next Else GoTo IfPressButt EndIf GoTo loop ; на начало DispLoop: ; П/П отображения установленного времени DigitDisp = SETHOUR Dig 1 PORTA = %00001000 If DigitDisp <> 0 Then GoSub LOOK DigitDisp = SETHOUR Dig 0 PORTA = %00000100 GoSub LOOK DigitDisp = SETMINUTES Dig 1 PORTA=%00000010 GoSub LOOK DigitDisp = SETMINUTES Dig 0 PORTA=%00000001 GoSub LOOK Return DisplayTime: ; отображение текущего времени PORTA=%00001000 PORTB=$ff DigitDisp = HOUR Dig 1 If DigitDisp <> 0 Then GoSub LOOK ;гашение незначащего нуля DigitDisp = HOUR Dig 0 PORTA=%00000100 GoSub LOOK DigitDisp = MINUTES Dig 1 PORTA = %00000010 GoSub LOOK DigitDisp = MINUTES Dig 0 PORTA = %00000001 GoSub LOOK If SEC=1 Then PORTA = %00000100 PORTB = %01111111 DelayMS 4 EndIf PORTB= $ff Return LOOK: ;здесь в порт Б передается кодированное значение цифр, удобное для восприятия ; таблица для индикаторов с общим анодом PORTB = LookUp DigitDisp,[192,249,164,176,153,146,130,248,128,144,156] DelayMS 4 ; задержка для показа цифры PORTB = $ff Return ; возврат