292 lines
8.1 KiB
Plaintext
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
|