-- name : clockv2.jal -- edited : Mark Craig -- date : 25-1-05 -- project : Robosapien Alarm Clock -- original authors website: http://users.skynet.be/langewouters/alarmclock.html -- original details: -- name : wekker.jal -- author : Thomas Langewouters -- date : 25-5-02 -- µC : PIC 16F84A -- Clockf : 4 MHz -- purpose : Clock with Hd44780, 4 pushbuttons, buzzer include 16f84_4 include jpic include jdelay include hd447804z -- use edited LCD connections. include jprint -- set up Pic-to-pic comms pin_b5_direction = input -- IN_comm pin_b4_direction = output var volatile bit IN_comm is pin_b5 -- connected to PIC(a), a2 var volatile bit OUT_comm is pin_b4 -- connected to PIC(a), a3 var byte pic_clock = 0b_0000_0001 -- as this is the pic clock include mark_comms_asm -- my pic-to-pic comms (pretty crappy) (assembly version) var byte data_in -- // Vars var byte W_TEMP -- used to store W while in interupt var byte alarm_hours_tens = 0 var byte alarm_hours_units = 0 var byte alarm_min_tens = 0 var byte alarm_min_units = 1 var bit timechange_flag = true var bit alarm_flag = false var byte cursorpos = 0 const c_time_position = 4 -- originally 5 var byte sec_units = 0 var byte sec_tens = 0 var byte min_units = 0 var byte min_tens = 0 var byte hours_units = 0 var byte hours_tens = 0 var byte roman_hi = 0x_0f var byte roman_mid = 0x_43 var byte roman_lo = 0x_40 var bit alarmtriggeredonce = false -- used to trigger alarm only once (as opposed to every clock tick for a minute) -- LED output pin_b6_direction = output pin_b7_direction = output var volatile bit led_anode is pin_b6 var volatile bit led_cathode is pin_b7 led_anode = on led_cathode = off -- / Pic initseq / clear_watchdog bank_1 option = 0x_88 -- prescaler asigned to watchdog, no pullup bank_0 tmr0 = 0 asm bsf intcon_gie -- enable interrupts asm bsf intcon_t0ie -- enable overflow interrupts -- / Pic initseq / -- //// Lcd init //// -- Klok hd44780_define( 1, 0b_0000_1110, 0b_0001_0101, 0b_0001_0101, 0b_0001_0101, 0b_0001_1001, 0b_0001_0001, 0b_0000_1110, 0b_0000_0000 ) -- Bell hd44780_define( 2, 0b_0000_0100, 0b_0000_1110, 0b_0000_1110, 0b_0000_1110, 0b_0001_1111, 0b_0000_0100, 0b_0000_0000, 0b_0000_0000 ) procedure bell_lcd is hd44780_position( 0 ) hd44780 = 2 end procedure procedure klok_lcd is hd44780_position( 0 ) hd44780 = 1 end procedure Procedure Message is HD44780 = "P" HD44780 = "i" HD44780 = "c" HD44780 = " " HD44780 = "C" HD44780 = "l" HD44780 = "o" HD44780 = "c" HD44780 = "k" HD44780 = " " HD44780 = "V" HD44780 = "1" HD44780 = "." HD44780 = "0" HD44780 = "1" End Procedure procedure checkforalarm is if alarm_hours_tens == hours_tens & alarm_hours_units == hours_units & alarm_min_tens == min_tens & alarm_min_units == min_units then if ( alarmtriggeredonce == false ) then led_anode = on alarmtriggeredonce = true -- so we don't send it every time the clock ticks send_to_pic( 0h_B0 ) -- send "execute main program" end if else alarmtriggeredonce = false led_anode = off end if end procedure procedure time is asm bsf timechange_flag asm incf sec_units, f -- Increment with one second if sec_units == 10 then asm clrf sec_units asm incf sec_tens, f end if if sec_tens == 6 then asm clrf sec_tens asm incf min_units, f end if if min_units == 10 then asm clrf min_units asm incf min_tens, f end if if min_tens == 6 then asm clrf min_tens asm incf hours_units, f end if if hours_units == 10 then asm clrf hours_units asm incf hours_tens, f end if if hours_tens == 3 then asm clrf hours_tens end if if hours_tens == 2 & hours_units >= 4 then asm clrf hours_tens asm clrf hours_units end if checkforalarm -- check alarm end procedure procedure isr is pragma interrupt assembler local out movwf W_TEMP tstf roman_mid -- roman_mid = 0 ? skpnz decf roman_hi, f -- yes, roman_mid = 0 so decrement roman_hi decfsz roman_mid, f -- roman_mid = roman_mid - 256 goto out -- if nz then not one second yet tstf roman_hi -- test roman_hi skpz -- if z then roman_hi and roman_mid are 0 goto out -- if nz then not one second yet movlw 0x_0f movwf roman_hi -- load msb movlw 0x_42 movwf roman_mid -- load mid movlw 0x_40 addwf roman_lo, f -- add to remainder already in lsb skpnc -- no overflow incf roman_mid, f -- if c, roman_lo overflowed, increment roman_mid call time -- call user task out: bcf intcon_t0if -- reset interrupt flag movfw W_TEMP end assembler end procedure -- **************** User interface ***************** procedure cursor_to_position is if cursorpos >= 3 then hd44780_position(c_time_position + cursorpos) else hd44780_position(c_time_position + cursorpos - 1) end if end procedure procedure displaytime is if timechange_flag then hd44780_position(c_time_position) hd44780 = hours_tens + 48 hd44780 = hours_units + 48 hd44780 = ":" hd44780 = min_tens + 48 hd44780 = min_units + 48 hd44780 = ":" hd44780 = sec_tens + 48 hd44780 = sec_units + 48 asm bcf timechange_flag -- reset timechangeflag end if if cursorpos != 0 then cursor_to_position end if end procedure procedure display_cursor (bit in value) is if value == true then hd44780_instruction( 0b_0000_1110 ) -- display on, cursor on, blink off else hd44780_instruction( 0b_0000_1100 ) -- display on, cursor off, blink off end if end procedure procedure incr_cursor is if cursorpos == 4 then asm clrf cursorpos -- if last, then first display_cursor( false ) else asm incf cursorpos, f -- advance display_cursor( true ) end if end procedure -- *******************// Time // ********************* procedure incr_time is if cursorpos == 1 then asm incf hours_tens, f elsif cursorpos == 2 then asm incf hours_units, f elsif cursorpos == 3 then asm incf min_tens, f elsif cursorpos == 4 then asm incf min_units, f end if asm bsf timechange_flag end procedure procedure decr_time is if cursorpos == 1 then asm decf hours_tens, f elsif cursorpos == 2 then asm decf hours_units, f elsif cursorpos == 3 then asm decf min_tens, f elsif cursorpos == 4 then asm decf min_units, f end if asm bsf timechange_flag end procedure -- *******************// Alarm // ********************* procedure incr_alarm is if cursorpos == 1 then asm incf alarm_hours_tens, f elsif cursorpos == 2 then asm incf alarm_hours_units, f elsif cursorpos == 3 then asm incf alarm_min_tens, f elsif cursorpos == 4 then asm incf alarm_min_units, f end if end procedure procedure decr_alarm is if cursorpos == 1 then asm decf alarm_hours_tens, f elsif cursorpos == 2 then asm decf alarm_hours_units, f elsif cursorpos == 3 then asm decf alarm_min_tens, f elsif cursorpos == 4 then asm decf alarm_min_units, f end if end procedure procedure displayalarm is hd44780_position(c_time_position) hd44780 = alarm_hours_tens + 48 hd44780 = alarm_hours_units + 48 hd44780 = ":" hd44780 = alarm_min_tens + 48 hd44780 = alarm_min_units + 48 if cursorpos != 0 then cursor_to_position end if end procedure procedure set_alarm is hd44780_clear bell_lcd displayalarm data_in = 0 -- Do the alarm set until the Stop button is pressed while ( data_in != 0h0E & data_in != 0h8E ) loop displayalarm read_from_pic( data_in ) hd44780_position( 0h_40 ) -- move to next line print_hexadecimal_2( HD44780, data_in ) -- display received byte if ( data_in == 0h88 | data_in == 0h08 ) then -- Key_Set incr_cursor elsif ( data_in == 0h86 | data_in == 0h06 ) then -- Key_Incr incr_alarm elsif ( data_in == 0h87 | data_in == 0h07 ) then -- Key_Decr decr_alarm end if end loop end procedure -- ***************** Start **************** hd44780_clear message delay_500ms(3) hd44780_clear klok_lcd forever loop displaytime read_from_pic( data_in ) if ( data_in != 0 ) then -- we have some data hd44780_position( 0h_40 ) print_hexadecimal_2( HD44780, data_in ) if ( data_in == 0h_88 | data_in == 0h_08 ) then -- Key_Set ( right arrow on remote ) incr_cursor elsif ( data_in == 0h_8E | data_in == 0h_0E ) then -- Key_Func ( stop button on remote ) set_alarm klok_lcd elsif ( data_in == 0h_86 | data_in == 0h_06 ) then -- Key_Incr ( up arrow on remote ) incr_time elsif ( data_in == 0h_87 | data_in == 0h_07 ) then -- Key_Decr ( down arrow on remote ) decr_time end if end if end loop