;-------------------------------------------------------------------------------
; 16F88
; interne oscillator op 8MHz
; interne MCLR
;-------------------------------------------------------------------------------
include 16f88
pragma target OSC INTOSC_NOCLKOUT -- HS crystal or resonator
pragma target clock 8_000_000 -- oscillator frequency
pragma target WDT disabled -- no watchdog
pragma target LVP disabled -- no low-voltage programming
pragma target CCP1MUX pin_B3 -- ccp1 pin on B3
pragma target MCLR internal -- reset internally
OSCCON_IRCF = 7 -- set prescaler to 1 (8 MHz)
enable_digital_io() ;alle pinnen digitale IO
;LED is via voorschakelweerstand aangesloten op pin B7
alias led is pin_B7
pin_B7_direction = output
led = off
alias Motorola is pin_B0
pin_B0_direction = input
alias Switch is pin_A5
pin_A5_direction = input
;-------------------------------------------------------------------------------
;instellingen voor Timer0
;-------------------------------------------------------------------------------
INTCON_TMR0IE = high ;interrupt
OPTION_REG_T0CS = low ;Timer0 timer mode
OPTION_REG_PSA = low ;prescaler op Timer0
;de prescaler op 1/4
OPTION_REG_PS = 0b001
TMR0 = 0
;-------------------------------------------------------------------------------
;LCD declaratie en initialisatie
;-------------------------------------------------------------------------------
;Volgende constanten moeten gedeclareerd worden:
const byte LCD_ROWS = 2 -- 1, 2 or 4 lines
const byte LCD_CHARS = 16 -- 8, 16 or 20 chars per line
;Alisassen voor de handshake-lijnen:
alias lcd_rs is pin_A4 -- cmd/data select
alias lcd_en is pin_A6 -- trigger
pin_A4_direction = output
pin_A6_direction = output
;Aliassen voor de vier datalijnen:
alias lcd_dataport is portA_low -- 4 databits
pin_A0_direction = output
pin_A1_direction = output
pin_A2_direction = output
pin_A3_direction = output
;laad de eigenlijke bibliotheek
include lcd_hd44780_4
;en initialiseer het display
lcd_init() -- init the lcd controller
;de printbibliotheek
include print
;wis het scherm
lcd_clear_screen()
;Het kloppend hart van de decoder
include MMInterrupt
;De marklin adres lookuptabel
include MMLookup
;-------------------------------------------------------------------------------
;PROG variabelen
;-------------------------------------------------------------------------------
var byte*3 dwRawData = 0
var byte RawData[3] at dwRawData
var byte DataLow
var byte DataMid
var byte DataAddr
var byte Temp
var word wSwitchAdres
;LCD strings
const byte RED[3] = "Red"
const byte GREEN[3] = "Grn"
const byte SW_ON[3] = "ON "
const byte SW_OFF[3] = "OFF"
;-------------------------------------------------------------------------------
T2CON_TMR2ON = high ;turn timer2 on;
INTCON_GIE = high ;enable interrupts
;-------------------------------------------------------------------------------
forever loop
if(DataStatus > DATA_NONE)then
;Er is data, de led mag uit
Led = off
;schuif data door zodat de interruptvariabele terug 'vrij' komt om
;terug aangepast te worden door de interruptroutine
dwRawData = dwMMPassData
;Verdeel de data:
;DataLow bevat de 'ruwe' data
;bij seindata is dit de schakeldata (subadres + schakelstatus)
DataLow = RawData[0]
;DataMid heeft bij seindata geen zin (is steeds 0)
DataMid = RawData[1] & 0x03
;DataAddr bevat het adres (eerst van 18 bits 24 bits maken om eenvoudiger
;te kunnen bewerken)
dwRawData = dwRawData << 6
DataAddr = RawData[2]
;enkel wisseldata interesseert ons voor het ogenblik
if(DataStatus == DATA_TURNOUT)then
;seindata
;Op het display geven we op de bovenste regel de 'ruwe' data
;Ruw - Adres - Subadres - schakelstatus
lcd_cursor_position(0,0)
print_byte_hex(lcd, MMPassData[2])
print_byte_hex(lcd, MMPassData[1])
print_byte_hex(lcd, MMPassData[0])
_lcd_write_data("-")
;Adres
print_byte_hex(lcd, DataAddr)
_lcd_write_data("-")
;SubAdres
print_byte_hex(lcd, (DataLow & 0xFC))
_lcd_write_data("-")
;Schakelstatus
print_byte_hex(lcd, (DataLow & 0x03))
;Op de tweede regel zetten we 'leesbare' data
;Schakeladres - Rood/groen - Schakelstatus
;bereken het decimaal adres
wSwitchAdres = MMAdresLookup[DataAddr]
;wSwitchAdres - 1 * 4
wSwitchAdres = (wSwitchAdres - 1) << 2
;bereken de individuele schakelaar
Temp = (DataLow & 0xFC)
case Temp of
0x00 : wSwitchAdres = wSwitchAdres + 1
0xC0 : wSwitchAdres = wSwitchAdres + 1
0x30 : wSwitchAdres = wSwitchAdres + 2
0xF0 : wSwitchAdres = wSwitchAdres + 2
0x0C : wSwitchAdres = wSwitchAdres + 3
0xCC : wSwitchAdres = wSwitchAdres + 3
0x3C : wSwitchAdres = wSwitchAdres + 4
0xFC : wSwitchAdres = wSwitchAdres + 4
end case
lcd_cursor_position(1,0)
;Adres
print_byte_dec(lcd, wSwitchAdres)
_lcd_write_data(" ")
_lcd_write_data("-")
_lcd_write_data(" ")
;Kleur schakelaar
Temp = DataLow & 0xC0
if(Temp == 0)then
print_string(lcd, RED)
else
print_string(lcd, GREEN)
end if
_lcd_write_data(" ")
_lcd_write_data("-")
_lcd_write_data(" ")
;Status
Temp = DataLow & 0x03
if(Temp == 0)then
print_string(lcd, SW_OFF)
else
print_string(lcd, SW_ON)
end if
_lcd_write_data(" ")
_lcd_write_data(" ")
_lcd_write_data(" ")
end if
;data verwerkt
DataStatus = DATA_NONE
end if
;T0 afgegaan?
if(T0Passed != 0)then
T0Passed = 0
BlinkTimer = BlinkTimer - 1
if(BlinkTimer == 0)then
BlinkTimer = BLINKTIME
;knipper de led om aan te tonen dat er geen MM signaal is!
Led = !Led
end if
end if
end loop
;-------------------------------------------------------------------------------