|
'{$STAMP BS2}
'March 2002. Ben Lennard.
'Program to demonstrate how to interface to the LENNARD5 Digit
'LED display module. Plus, how to communicate with a PC, and
display the
'Hexadecimal ASCII code of any keys pressed on the keyboard.
'The outputs from the 4094 registers
correspond to the Digit segments as follows:
'MSB -> .GFEDCBA <-LSB
'To write to a digit, do the following:
'1. Send data.
'2. Strobe the digit/s you want to display the data
'What this program does:
'Receives data from the PC everytime a key is pressed, and displays
the
'Decimal and Hexadecimal value of that Key's ASCII code.
'Data received from the PC will be 8 bits, so we need to translate
that 8 bits
'in to two sets of nibbles. Then, we use those nibbles to look
up the actual byte
'we need to send to the 4094's to display the correct data.
'Example: If we send "Z" via the serial port, we will
receive the following byte: 01011010
'Which is "5A" in Hexaedecimal.
'To display that value on the "LENNARD Display module":
Split the byte in to two nibbles.
'The lower nibble, 1010 (Hexadecimal = "A", Decimal
"10")
'will make the program look up position 10 in the table, and
then sends that data
'in the table to the display, digit A.
'The upper nibble, 0101 (Hexadecimal and Decimal = "5")
will make the program look up
'position 5 in the table, and then sends that data in the table
to the display, digit B.
'*****DECLARE VARIABLES*****
'DATA for the Display Character Lookup Table (EEPROM address
0 to 20)
data 63,6,91,79,102,109,125,7,127,111 '0-9
data %01110111,%01111100,%00111001,%01011110,%01111001,%01110001 'A-F
data 63,%00111000,%00111000,%01111001,%01110110
'O,L,L,E,H ("HELLO")
'CONSTANTS
clock CON 6 'P6 = clock to 4094's
pin 3
datapack CON 5 'P5 = Data to 4094's
pin 2
'VARIABLES
strobedigit var nib 'a four bit
variable used to determine which digit to update
'5 digits, 0 to 4
character var byte 'the data to
send to the display
datafromPC var byte 'the data from
the PC
a var byte 'just a FOR loop variable
nibble var nib 'used to store the
lower or upper 4 bits of "datafromPC"
divider var byte
'*****MAIN PROGRAM*****
'Set up the display
Gosub blankdisplay
'display "HELLO"
for a = 16 to 20
'go to EEPROM address "a"
and store the data at that address in "Character"
read a, character
'Send "character" to the
display module, and display on the digit
'determined by "strobedigit"
strobedigit=a-16
gosub loadregisters
next
pause 3000
'blank display again
Gosub blankdisplay
ReadSerialPort:
SERIN 16, 396, [datafromPC] 'Using
builtin serial port, 2400baud, 8, N, 1
if not datafromPC = 27 then keepgoing 'If
ESC pressed, send a message back to the PC
SEROUT 16, 396, [" Microcontroller demo. Ben Lennard 3/2002"]
keepgoing:
if datafromPC = 27 then ReadSerialPort
GOSUB DisplayASCIIcode
GOTO ReadSerialPort
DisplayASCIIcode:
nibble = datafromPC 'transfer lower
4 bits of byte to nibble
'NOTE: As "nibble" is a nibble, and "datafromPC"
is a byte,
'then only the lower half of "datafromPC" will be passed
to "nibble"
read nibble, character 'lookup data in table to send to the display
'load that data in to Digit A
strobedigit=0
gosub loadregisters
nibble = datafromPC >> 4 'transfer upper 4 bits of byte to nibble
read nibble, character 'lookup data
in table to send to the display
'load that data in to Digit B
strobedigit = 1
gosub loadregisters
DisplayDECIMALcode: '(this
code added 25/3/2002)
'This is a little more difficult than working out
'the HEX code (simply spliting the byte in to two nibbles)
'as we can have up to 3 digits. So, we need to split the
'decimal version of the character in to 3 parts to display...
'The following code takes advantage of the fact that the Stamp
'and similar Microcontrollers only do Integer maths without
'an external floating point coprocessor attached.
'Figure out hundreds unit (doing 100's
then 10's then 1's, rather
'than 1's, 10's, 100's saves 6 bytes of EEPROM! As this way you
don't need to repeat code)
nibble = datafromPC / 100 'eg: 214
/ 100 = 2.14 (integer maths drops the .14)
strobedigit = 4
read nibble, character
gosub loadregisters 'eg: load 01011011
in to digit 4, which displays a 2.
'Figure out tens unit
divider = nibble * 100 'eg: 2 *
100 = 200
divider = datafromPC - divider 'eg:
214 - 200 = 14
nibble = divider / 10 'eg: 14 /
10 = 1.4 (integer maths drops the .4), so nibble = 1
strobedigit = 3
read nibble, character
gosub loadregisters 'eg: load 00000110
in to digit 3, which displays a 1.
'Figure out ones unit
divider = datafromPC / 10 'eg: 214
/ 10 = 21.4 (integer maths drops the .4)
divider = divider * 10 'eg: 21 *
10 = 210
nibble = datafromPC - divider 'eg:
214 - 210 = 4
strobedigit = 2
read nibble, character 'eg: read
EEPROM address 4 (which has 01100110 stored in it)
'store value in EEPROM address 4 in character
'(turn on decimal point to seperate Dec from Hex on the display,
eg: 188.BC)
character = character + %10000000
gosub loadregisters 'eg: load 01100110
in to digit 2, which displays a 4.
return
blankdisplay:
SHIFTOUT datapack, clock, msbfirst, [0]
'blank display
for a = 0 to 4
pulsout a,1 'Strobe each digit
next
return
loadregisters:
SHIFTOUT datapack, clock, msbfirst, [character] 'Send data to the display
PULSOUT strobedigit,1 'Strobe required
digit to display the data
return
|