Files
SyncHome/trunk/workspace/gcb/16f873a-TimerElisa.gcb
2023-03-09 12:51:54 +00:00

292 lines
8.1 KiB
Plaintext

' ########### start ###########
' pic:PIC16F873A
' ########### end ###########
'
' ******************************************************************
' Timer con Display 7 segmenti per Elisa
' 2023-02-16 (c) Paolo Iocco
' ******************************************************************
'
' Circuit diagram
' ---------------
' PIC28 Pinout
' +--\/--+
' /MCLR VPP 1|o |28 RB7 KBI3 PGD
' AN0 RA0 2| |27 RB6 KBI2 PGC
' AN1 RA1 3| |26 RB5 KBI1
' Vref- AN2 RA2 4| |25 RB4 KBI0
' Vref+ AN3 RA3 5| |24 RB3 PGM CAN-RX
' T0CKi RA4 6| |23 RB2 /INT2 CAN-TX
' SS AN4 RA5 7| |22 RB1 /INT1
' AVss 8| |21 RB0 /INT0
' OSC1 9| |20 Vdd
' OSC2 10| |19 Vss
' T1CKi RC0 11| |18 RC7 RX DT
' CCP2 RC1 12| |17 RC6 TX CK
' CCP1 RC2 13| |16 RC5 SKO D+
' SCL SCK RC3 14| |15 RC4 SDI D- SDA
' +------+
'
' ******************************************************************
'Chip model
#chip 16f873A, 16
#config OSC = HS, WDT = OFF, PWRTE = ON, CP = OFF
dim milliseconds as byte ' counter per i millisecondi
dim Timer_1 as byte
dim Timer_10 as byte
dim Timer_100 as byte
dim stato as byte ' Byte di stato del programma
#define S_Running stato.0 ' bit 0: countdown running
#define S_Led stato.7 ' bit 7: stato del led / PWM
dim blink as byte
#define B_Points blink.0
#define B_Digit1 blink.1
#define B_Digit2 blink.2
#define B_Digit3 blink.3
#define B_Digit4 blink.4
#define acceso on ' common cathode + NPN --> high = ON
#define spento off ' common cathode + NPN --> low = OFF
#define DISP_SEL_1 PORTC.7 '
#define DISP_SEL_2 PORTC.6 '
#define DISP_SEL_3 PORTC.5 '
#define DISP_SEL_4 PORTC.4 '
#define DISP_SEL_S PORTC.3 '
#define DISP_SEG_A PORTB.0 '
#define DISP_SEG_B PORTB.1 '
#define DISP_SEG_C PORTB.2 '
#define DISP_SEG_D PORTB.3 '
#define DISP_SEG_E PORTB.4 '
#define DISP_SEG_F PORTB.5 '
#define DISP_SEG_G PORTB.6 '
#define DISP_SEG_P PORTB.7 '
#define LED PORTA.2 ' led on Pin A2
#define Button1 PORTC.0 ' pushbutton on PORTC.0
#define Button2 PORTC.1 ' pushbutton on PORTC.1
#define Button3 PORTC.2 ' pushbutton on PORTC.3
#define Timer_Charge 226 ' 255-125 Costante da calibrare: IRQ ogni ms
#define minuti 6 ' Minuti iniziali
#define secondi 30 ' Secondi iniziali
#define scroll 150 ' velocità dello scroll in ms
Dir LED Out
Dir Button1 In
Dir Button2 In
Dir Button3 In
'----------------------------------------------------------------------
Interrupts:
On Interrupt Timer0Overflow Call Tmr0_ISR ' Interrupt su Timer Overflow
On Interrupt ExtInt0 ignore ' Interrupt su PORTB.0 INT
On Interrupt PORTBChange Ignore ' Interrupt su PORTB change
'----------------------------------------------------------------------
Startup:
InitTimer0 Osc, PS0_32 ' Impostazioni prescaler
TMR0=Timer_Charge ' impostazioni Timer
milliseconds=0 ' counter per i millisecondi
Counter_m = minuti ' Inizializzazione minuti
Counter_s = secondi ' Inizializzazione secondi
set S_Running off ' parto in STOP
Welcome ' splashscreen iniziale
'----------------------------------------------------------------------
Loop:
do
if S_Running=1 then ' se il countdown è attivo
' *** gestione del tempo ***
if Timer_100 = 0 then ' Tempo esaurito? 1000ms
if Counter_s>0 then ' decremento i secondi
Counter_s --
else
if Counter_m > 0 then ' decremento i minuti
Counter_m --
Counter_s = 59
end if
end if
Timer_100=10 ' ricarica il timer e riparto
end if
' *** Tempo esaurito ***
if (Counter_s=0) and (Counter_m=0) then
set S_Running off ' Stato --> stop
set LED off ' Uscita PWM --> off
end if
end if
' *** Gestione pulsante ***
if button1 = 0 then ' Premuto?
wait until button1 = 1 ' rilascio
if S_Running = 0 then ' se coutdown è fermo --> inizia
set S_Running on
set LED on
Timer_100 = 2 ' carico il timer per il ventilatore
wait until Timer_100 = 0 ' aspetto che il motorino parta 200ms al max per vincere l'inerzia
Timer_100 = 10 ' carico il timer da un secondo
else
set S_Running off ' se countdown È attivo --> stop
set LED off
end if
end if
' *** Display routine (ciclica continua) ***
Display7s 1, Counter_m / 10 ' visualizza decine di minuti
Display7s 2, Counter_m % 10 ' visualizza unità di minuti
Display7s 3, Counter_s / 10 ' visualizza decine di secondi
Display7s 4, Counter_s % 10 ' visualizza unità di secondi
loop
' *** Splashscreen iniziale ***
sub Welcome 'scrolling della scritta "HELLO"
timer_1=scroll
do
Display7s 1, " "
Display7s 2, " "
Display7s 3, " "
Display7s 4, " "
loop until timer_1=0
timer_1=scroll
do
Display7s 1, " "
Display7s 2, " "
Display7s 3, " "
Display7s 4, "H"
loop until timer_1=0
timer_1=scroll
do
Display7s 1, " "
Display7s 2, " "
Display7s 3, "H"
Display7s 4, "E"
loop until timer_1=0
timer_1=scroll
do
Display7s 1, " "
Display7s 2, "H"
Display7s 3, "E"
Display7s 4, "L"
loop until timer_1=0
timer_1=scroll
do
Display7s 1, "H"
Display7s 2, "E"
Display7s 3, "L"
Display7s 4, "L"
loop until timer_1=0
timer_1=scroll
do
Display7s 1, "E"
Display7s 2, "L"
Display7s 3, "L"
Display7s 4, "O"
loop until timer_1=0
timer_1=scroll
do
Display7s 1, "L"
Display7s 2, "L"
Display7s 3, "O"
Display7s 4, " "
loop until timer_1=0
timer_1=scroll
do
Display7s 1, "L"
Display7s 2, "O"
Display7s 3, " "
Display7s 4, " "
loop until timer_1=0
timer_1=scroll
do
Display7s 1, "O"
Display7s 2, " "
Display7s 3, " "
Display7s 4, " "
loop until timer_1=0
timer_1=scroll
do
Display7s 1, " "
Display7s 2, " "
Display7s 3, " "
Display7s 4, " "
loop until timer_1=0
end sub
' *** Display Routines ***
sub Display7s (posizione,numero)
set DISP_SEL_1 spento
set DISP_SEL_2 spento
set DISP_SEL_3 spento
set DISP_SEL_4 spento
wait 200 us
select case numero
case 0: segmenti = 0b'01111110'
case 1: segmenti = 0b'00110000'
case 2: segmenti = 0b'01101101'
case 3: segmenti = 0b'01111001'
case 4: segmenti = 0b'00110011'
case 5: segmenti = 0b'01011011'
case 6: segmenti = 0b'01011111'
case 7: segmenti = 0b'01110000'
case 8: segmenti = 0b'01111111'
case 9: segmenti = 0b'01111011'
case " ": segmenti = 0b'00000000'
case "A": segmenti = 0b'01110111'
case "B": segmenti = 0b'01111111'
case "C": segmenti = 0b'01001110'
case "D": segmenti = 0b'00111101'
case "E": segmenti = 0b'01001111'
case "F": segmenti = 0b'01000111'
case "G": segmenti = 0b'01011110'
case "H": segmenti = 0b'00110111'
case "I": segmenti = 0b'00011000'
case "L": segmenti = 0b'00001110'
case "O": segmenti = 0b'01111110'
case "P": segmenti = 0b'01100111'
case "R": segmenti = 0b'00000101'
case "S": segmenti = 0b'01011011'
case "U": segmenti = 0b'00111110'
case "Z": segmenti = 0b'01101101'
case else: segmenti = 0b'00000000'
end select
DISP_SEG_G = segmenti.0
DISP_SEG_F = segmenti.1
DISP_SEG_E = segmenti.2
DISP_SEG_D = segmenti.3
DISP_SEG_C = segmenti.4
DISP_SEG_B = segmenti.5
DISP_SEG_A = segmenti.6
select case posizione
case 1: set DISP_SEL_1 acceso
case 2: set DISP_SEL_2 acceso
case 3: set DISP_SEL_3 acceso
case 4: set DISP_SEL_4 acceso
end select
wait 1500 us
end sub
' *** Interrupt Routines ***
Sub Tmr0_ISR ' *** on Timer0 Overflow (IRQ on transition 255 to 0) ***
T0IF=0 'reset Interrupt Flag
TMR0=Timer_Charge 'reload counter --> Timer_Charge
milliseconds = (milliseconds +1) % 100
if Timer_1>0 then
Timer_1 -- 'decrease Timer 1ms
end if
if ((milliseconds%10)=0) and (Timer_10>0) then
Timer_10 -- 'decreases Timer 10ms
end if
if (milliseconds=0) and (Timer_100>0) then
Timer_100 -- 'decreases Timer 100ms
end if
End Sub