Hardware
It consists of keyboard (8 keys), 3 LEDs and nice looking a little bit retro alphanumeric VFD display (1 line by 16 characters ). Glance at the board reveals that it has voltage converter for VFD and 3 ICs. One is M66004FP - mitsubishi VFD controller, HC595 serial in-parallel out shift register and HC165 parallel in serial out shift register. Board is connected with the rest of the world with 10 wire ribbon cable. not saying more I've discovered pinout to be:Pin# | description(M66004/HC595/HC165) |
1 | GND |
2 | GND |
3 | GND |
4 | +5V |
5 | +5V |
6 | CSK/SRCLK/CLK |
7 | SDATA/SER/- |
8 | ~CS/-/- |
9 | -/RCLK/~LD |
10 | -/-/QH |
LEDs are connected to bits F, G, H (three MSB) of HC595 (active low - 0 in register makes led light up) and keys are connected to inputs of HC165 (active high - i.e. pressed key is loaded as hi to register).
(taken with shitty phone and after double re-compression, sorry for the quality)
VFD drivingThe most easy task, first - grab datasheet, M66004FP is very easy to drive, and datasheet is concise and useful. Most (well, all except custom character definition) commands are one byte long and "use" empty space in ascii character map. In a nutshell to send byte to M66004FP you need to:
- pull ~CS low (this enables M66004FP) [pin 8]
- clock data using CSK [pin 6] and SDATA [pin 7] lines (bits are latched on rising CSK edge)
- pull ~CS high [pin 8]
Leds and keyboard
And now for something completely different - reading keyboard and driving LEDs. Reminder: LEDs are connected to 3 MSB of serial-to-parallel shift register HC595, keyboard is connected (8 keys - 8 bits) to parallel in-serial out shift register HC165. LEDs ar light up by 0 in register. Pressing a key forces hi (1) state on register input. And now the tricky part - both registers share clock signal (SRCLK/CLK), and load line (RCLK/~LD). Unfortunately according to me it's impossible to independently read keys and drive LEDS. Which means that in your program you'll need ugly global variable to store LED state.Procedure is as follows:
- clock in 8 bits (they go to HC595) - 3 MSB define LED state
- drive RCLK/~LD high,low,high (which clocks data to HC595 outputs - setting LEDs and loads keyboard state to HC165)
- clock 8 bits of data from HC165 register, data is available on pin 10 of connector (QH)
Prototype
I used one of the most popular microcontrollers - PIC16F84 (or F628). And very nice programming language - similar to nothing but very well fitting 16F84 - JAL.Pins:
A0 - serial input (uC input)
B0 - sclk (uC output)
B1 - sdata (uC output)
B2 - ~LD (uC output)
B3 - M66004FP CS (uC output)
It looks like this:
Source code:
--
-- name : hp_panel.jal
-- author : misio
-- date : 2009
-- purpose : poc driving hp lj panel
-- author : misio
-- public domain
-- target configuration: 16f84 with 4 Mhz Xtal
include 16f84_4
-- standard library
include jlib
-- two LEDs that are "on board"
var volatile bit led1 is pin_b7
var volatile bit led2 is pin_b6
-- panel connection
var volatile bit sclk is pin_b0
var volatile bit sdata is pin_b1
var volatile bit data_ld is pin_b2
var volatile bit m6600fp_cs is pin_b3
var volatile bit serin is pin_a0
var byte i
procedure clock_byte( byte in b ) is
var bit x at b : 7
for 8 loop
delay_1us( 100 )
sclk = off
sdata = x
delay_1us( 100 )
sclk = on
b = b << 1
end loop
sclk = off
end procedure
procedure send_m6600fp( byte in b ) is
data_ld = on
m6600fp_cs = off
clock_byte( b )
delay_1us( 20 )
end procedure
procedure write_m6600fp( byte in b ) is
send_m6600fp( b )
m6600fp_cs = on
end procedure
procedure goto_m6600fp( byte in b ) is
send_m6600fp ( 0x_E0 | (b & 0x_0F) )
m6600fp_cs = on
end procedure
procedure show_byte( byte in b ) is
var bit v at b : 0
goto_m6600fp(0)
write_m6600fp("[")
for 8 loop
if ( v == on ) then
write_m6600fp(0x_7F)
else
write_m6600fp(" ")
end
if b = b >> 1
end loop
write_m6600fp("]")
end procedure
procedure send_hc595( byte in b ) is
m6600fp_cs = on
data_ld = off
clock_byte( b )
data_ld = on
delay_1us( 100 )
data_ld = off
end procedure
function get_kbd_set_leds ( byte in m ) return byte is
var byte n
var byte b
m6600fp_cs = on
data_ld = off
clock_byte( m )
data_ld = on
delay_1us( 100 )
n = 7
b = 0
for 8 loop
sclk = off
delay_1us ( 100 )
if serin == on then
b = b | ( 1 << n )
end if
sclk = on
delay_1us( 100 )
n = n - 1
end loop
return b
end function
-- ------------------ -- MAIN PROGRAM -- ------------------
var byte led_status
assembler
bsf 03, 5
bcf 01, 7
bcf 03, 5
end assembler
-- pin directions init
pin_b7_direction = output
pin_b6_direction = output
pin_b0_direction = output
pin_b1_direction = output
pin_b2_direction = output
pin_b3_direction = output
pin_a0_direction = input
delay_1ms( 300 )
send_hc595( 0x_FF )
write_m6600fp( 0x_F3 ) -- test mode - all on
write_m6600fp( 0x_07 ) -- 16 digits
write_m6600fp( 0x_0F ) -- dim max
write_m6600fp( 0x_F6 ) -- 128/fosc
-- delay_1s( 1 )
-- write_m6600fp( 0x_F7 ) -- 128/fosc
-- write_m6600fp( 0x_08 )
write_m6600fp( 0x_F1 ) -- test mode - normal
write_m6600fp( 0x_80 ) -- cursor off @ 0
write_m6600fp( 0x_11 ) -- cursor on @ 1
write_m6600fp( "-" )
write_m6600fp( "=" )
write_m6600fp( " " )
write_m6600fp( "D" )
write_m6600fp( "u" )
write_m6600fp( "p" )
write_m6600fp( "a" )
write_m6600fp( " " )
write_m6600fp( "b" )
write_m6600fp( "l" )
write_m6600fp( "a" )
write_m6600fp( "d" )
write_m6600fp( "a" )
write_m6600fp( " " )
write_m6600fp( "=" )
write_m6600fp( "-" )
-- endless loop
-- i = 0
-- for 32 loop
-- send_hc595( ! (1 << i) )
-- i = i + 1
-- if i > 7 then
-- i = 0
-- end if
-- delay_1ms( 200 )
-- end loop
-- send_hc595 ( 0x_FF )
led_status = 1
forever loop
i = get_kbd_set_leds ( led_status )
if (i & 1) == 1 then
while ( i & 1 ) == 1 loop
i = get_kbd_set_leds ( led_status )
end loop
led_status = led_status << 1
if led_status == 0 then
led_status = 1
end if
end if
-- i = read_hc165
show_byte( i )
led1 = on delay_1ms( 50 )
led1 = off
end loop -- final, never goes below
forever loop
i = 0
for 8 loop
write_m6600fp( 0x_10 + i )
write_m6600fp( 0x_10 + 15 - i )
delay_1ms(100)
write_m6600fp( 0x80 + i )
write_m6600fp( 0x80 + 15 - i )
i = i + 1
end loop
i = i - 1
for 7 loop
write_m6600fp( 0x_10 + i )
write_m6600fp( 0x_10 + 15 - i )
delay_1ms(100)
write_m6600fp( 0x80 + i )
write_m6600fp( 0x80 + 15 - i )
i = i - 1
end loop
-- delay_1s
-- led1 = on
-- delay_1s
-- led2 = on
-- delay_1s
-- led1 = off
-- delay_1s
-- led2 = off
end loop
No comments:
Post a Comment