Выпускаются недорогие и удобные в применении модули для управления 7-сегментными индикаторами, на которых можно построить часы или устройства с простым отображением информации.
Модули позволяют по 2-3 проводам отсылать данные для отображения, после чего участие МК не требуется (на динамическую индикацию и т.д.)
Модуль на TM1638 оснащен также кнопками, состояние которых можно считывать.
К сожалению, не предусмотрено никакого вывода для прерывания, поэтому МК должен регулярно сканировать клавиатуру.
Модуль на TM1637 управляется по двум линиям по интерфейсу, напоминающему I2C. Важным является считывание сигнала ack по линии данных.
Модуль на TM1638 управляется по трем линиям (добавлена линия STB). Каждый раз с низкого уровня STB начинается цикл приема-передачи данных. Сигнал ack можно не считывать.
Состояние клавиатуры приходится периодически считывать.
Предлагаю вашему вниманию библиотеки для работы с этими модулями.
Что следует учитывать. В библиотеках используются битовые операции. Битовые операции в BASCOM не атомарны, т.е. компилируются в несколько ассемблерных команд. Если во время битовой операции произойдет прерывание, то ее результат может быть испорчен.
Поэтому если в вашем проекте используются прерывания, следует отключать их на время обновления информации на дисплее -- командой в программе или модифировав код библиотеки.
Для TM1637:
$nocompile
'*******************************************************************************
' TM1637 display lib with 4 digints and semiclolon ":"
' Written by Alexandra "Cirno" https://t.me/Cirno9
'*******************************************************************************
' WARNING!!!! BITS and Interrupts!!!
'
' Bits are stored in bytes. A write to a bit/boolean variable is non-atomic. Which means that multiple operations
' are required to update the bit value in the byte. When interrupts are used that update bits in the same byte,
' you can have the effect that a change becomes lost.
' To prevent this you MUST disable interrupts and enable them after you have updated the bit variable.
' This concern Tm1637_wrbyte procedure.
'*******************************************************************************
' copy this code to main module, specify PINs and uncomment it
'*******************************************************************************
'(
TM_CLK alias PORTD.3
TM_DOUT alias PORTD.4
TM_DIN alias PIND.4
config TM_CLK = output ' for TM1637 CLK
config TM_DIN = input ' for TM1637 DIO
config TM_DOUT = output ' for TM1637 DIO
')
'*******************************************************************************
' external
'*******************************************************************************
declare sub Tm1637_on(byval bright as byte)
declare sub Tm1637_clear()
declare sub Tm1637(byval sString as string * 4 , byval point as byte)
'*******************************************************************************
' internal
'*******************************************************************************
declare sub Tm1637_wrbyte(byval bData as byte)
declare sub Tm1637_start()
declare sub Tm1637_stop()
declare sub Tm1637_ack()
goto tm1637_end
'*******************************************************************************
sub Tm1637(byval sString as string * 4 , byval point as byte)
local bChar as byte
local bOut as byte
local i as byte
local bAdr as byte
Tm1637_start
Tm1637_wrbyte 0x44 ' fixed adress mode
Tm1637_ack
Tm1637_stop
bAdr = 0xC0
for i = 1 to 4
bChar = Asc(sString , i )
bChar = bChar - 40
if bChar > 83 then
bOut = 0x00
else
bOut = lookup(bChar , digits)
end if
if point <> 0 and i = 2 then bout.7 = 1
Tm1637_start
Tm1637_wrbyte bAdr
Tm1637_ack
Tm1637_wrbyte bOut
Tm1637_ack
Tm1637_stop
incr bAdr
next i
end sub
'-------------------------------------------------------------------------------
sub Tm1637_clear()
local i as byte
Tm1637_start
Tm1637_wrbyte 0x40 ' autoincrement adress mode
Tm1637_ack
Tm1637_stop
Tm1637_start
Tm1637_wrbyte 0xC0 ' start address of first digit (0xC0) = MSB display
Tm1637_ack
for i = 0 to 3
Tm1637_wrbyte 0x00
Tm1637_ack
next
Tm1637_stop
end sub
'-------------------------------------------------------------------------------
sub Tm1637_wrbyte(byval bData as byte)
local bCnt as byte
for bCnt = 0 To 7 ' LSB first
reset TM_CLK
TM_DOUT = bData.bCnt
waitus 3
set TM_CLK
waitus 3
next
end sub
'-----------------------------
sub Tm1637_on(byval bright as byte)
Tm1637_start
select case bright
case 0 : Tm1637_wrbyte 0x80 ' set brightness 0 (off)
case 1 to 8 : Tm1637_wrbyte 0x87 + bright ' set brightness 1 - 8
case else : Tm1637_wrbyte 0x8F ' set brightness 8 (max)
end select
Tm1637_ack
Tm1637_stop
end sub
'-----------------------------
sub Tm1637_start()
set TM_CLK
set TM_DOUT
waitus 2
reset TM_DOUT
end sub
'-----------------------------
sub Tm1637_stop()
reset TM_CLK
waitus 2
reset TM_DOUT
waitus 2
set TM_CLK
waitus 2
set TM_DOUT
end sub
'-----------------------------
sub Tm1637_ack()
reset TM_CLK
waitus 5
reset TM_DOUT
bitwait TM_DIN , reset
set TM_CLK
waitus 2
reset TM_CLK
set TM_DOUT
end sub
'*******************************************************************************
'(
digits:
data &B01011000 '/( 0x28
data &B01001100 '/)
data &B01100011 '*
data &B00000000 '
data &B10000000 ',
data &B01000000 '-
data &B10000000 '.
data &B00000000 '
data &B00111111 '0
data &B00000110 '1
data &B01011011 '2
data &B01001111 '3
data &B01100110 '4
data &B01101101 '5
data &B01111101 '6
data &B00000111 '7
data &B01111111 '8
data &B01101111 '9
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B01001000 '=
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B01110111 'A
data &B01111100 'b
data &B00111001 'C
data &B01011110 'd
data &B01111001 'E
data &B01110001 'F
data &B01111101 'G
data &B01110110 'H
data &B00110000 'I
data &B00001110 'J
data &B00000000 '
data &B00111000 'L
data &B00000000 '
data &B01010100 'n
data &B00111111 'O
data &B01110011 'P
data &B01100111 'q
data &B11110111 'R
data &B01101101 'S
data &B01111000 't
data &B00111110 'U
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B00111001 '[
data &B00000000 '
data &B00001111 ']
data &B00000000 '
data &B00001000 '_
data &B00000000 '
data &B11011111 'a
data &B01111100 'b
data &B01011000 'c
data &B01011110 'd
data &B01111001 'E
data &B01110001 'F
data &B11101111 'g
data &B01110100 'h
data &B00010000 'i
data &B00001110 'J
data &B00000000 '
data &B00111000 'L
data &B00000000 '
data &B01010100 'n
data &B01011100 'o
data &B01110011 'P
data &B01100111 'q
data &B01010000 'r
data &B01101101 'S
data &B01111000 't
data &B00011100 'u
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B00000000 '
data &B00000000 '
')
tm1637_end:Для ТМ1638:
'(
The TM1638 "Led&Keys" library
Written by Alexandra "Cirno" https://t.me/Cirno9
*********************************************************************************
LOW LEVEL
*********************************************************************************
---------------------------------------------------------------------------------
WRITING:
---------------------------------------------------------------------------------
______ command stage _____________________________________
STB |____________ . . . ____________|_________if data transfer_______|
CLK _______ 0 __ 1 __ _ 6 __ 7 __ 0 __ 1 __ _ 6 __ 7 ______
|__| |__| . . . |__| |__| |__| |__| . . . |__| |__|
^ ^ ^ ^ ^ ^ ^ ^
__________|_____|_ . . . ____|_____|_____|_____|_ . . . ____|_____|______
DIO |__| |__| |__| |__| |__| |__| |__| |__|
The TM1638 interpretate every STB falling is a "Command Begin".
MCU can transfer an 8 bits of command and rise STB to stop operation -
or continue transfering a some Data byte(s) and rise STB at the end.
Data must be set on DIO and will be transfered at every CLK rising, LSB first.
---------------------------------------------------------------------------------
READING:
---------------------------------------------------------------------------------
______ command stage | data reading ____
STB |____________ . . . _____________________________________________|
CLK _______ 0 __ 1 __ _ 6 __ 7 ___ 0 ___ 1 __ _30 __ 31 _____
|__| |__| . . . |__| |__| |__| |__| . . . |__| |__|
^ ^ ^ ^ | | | |
__________|_____|__ . . . ___|_____|__*__v_____v___ . . . ___v_____v____$_
DIO |__| |__| |__| |__| * |__| |__| |__| |__| $
At first MCU transfers READ command (0x42) as described above.
Next, not rising the STB, MCU must switch the DIO line to Input Mode and set Vcc
pull-up. Now, MCU sending 32 CLK pulses to readout 32 bits (4 bytes) corresponding
key states. At the end, the MCU switch the DIO line to Output Mode and rise STB line.
*********************************************************************************
MID LEVEL
*********************************************************************************
There is a 3 sorts of TM1638 commands:
0x4* - writing or reading data
0x8* - display mode
0xC* - addreses
---------------------------------------------------------------------------------
WRITING OR READING:
---------------------------------------------------------------------------------
0x40 - write whit autoincrement: the MCU send starting address and some bytes of data
0x44 - write to fixed address: MCU send fixed address and then send 1 byte of data
0x42 - reading; MCU have reading out 4 bytes of key states
---------------------------------------------------------------------------------
DISPLAY MODE:
---------------------------------------------------------------------------------
0x80 - turn display off
0x88 - 1/16 of brightness (min)
0x89 - 2/16
0x8A - 4/16
0x8B - 10/16
0x8C - 11/16
0x8D - 12/16
0x8E - 13/16
0x8F - 14/16 of brightness (max)
---------------------------------------------------------------------------------
ADDRESSING:
---------------------------------------------------------------------------------
0xC0 - rigth digit
0xC1 - rigth LED
0xC2 - next digit
0xC3 - next led
...
0xCE - left digit
0xCF - left LED
The digits segments map is trivial; 7 bit means a decimal dot (comma).
The LEDs is controls by LSB of each byte only.
The TM1638 can scans 4*8 key matrix, but this module using 1*8 matrix only.
First 4 keys (counting right to left) controls LSBs in every byte, and
next 4 keys controls bit 4 of every byte.
*********************************************************************************
HIGH LEVEL
*********************************************************************************
1. At first you must invoke:
TM_SetBright (N)
where N is number from 0 to 8; 0 means display off, 1...8 set brtighness as described above.
2. Now (and every place of code of course) you can use:
TM_Clear ()
to clear up display digits (not changes the LEDs!).
3. To show some digits (or letters if it's possible), use:
TM_Show (string up to 16 chars)
The string can contain "." or "," symbol, showing appropriate decimal dot on display.
Use " " (space) to clear up apropriate digit.
you MUST care by youself about clearing not used digits by yourself. For exaple, you
shows "123" at first, and next you want to show "4". Then the "12" segments not be cleared
automaticaly. You can display " " at frist, or " 4", or use TM_Clear () before display
a new data.
4. TM_SetLED (B) used to set LEDs, where LBS of B is a rigthmost LED, MSB is a leftmost one.
5. B <- TM_GetKeys () can be used to poll keyboard. Unfortunately, there is no interrupt
to know when some key was pressed or relised, so MCU must periodicaly poll keyborad to know
state of the keys. The LSB of B is rigthmost key, and MSB is a leftmost one.
')
$nocompile
'*******************************************************************************
' Copy this code to main module, specify PINs and uncomment it
'*******************************************************************************
'(
TM_STB alias PORTD.2
TM_CLK alias PORTD.3
TM_DOUT alias PORTD.4
TM_DIN alias PIND.4
config TM_STB = output ' for TM1638 STB
config TM_CLK = output ' for TM1638 CLK
config TM_DOUT = output ' for TM1638 DIO
')
'*******************************************************************************
' external
declare sub TM_SetBright(byval bright as byte)
declare sub TM_Clear()
declare sub TM_Show(byval sString as string * 16)
declare sub TM_SetLED(byval bLedByte as byte)
declare function TM_GetKeys() as byte
' internal
declare sub TM_Wrbyte(byval bdata as byte)
declare sub TM_SendCmd(byval bCmd as byte)
declare sub TM_SendCmdData(byval bCmd as byte , byval bData as byte)
goto TM1638_end
sub TM_SetBright(bright)
select case bright
case 0 : TM_SendCmd &h80 'Turn display on and set PWM for brightness 0 Off
case 1 : TM_SendCmd &h88 'Turn display on and set PWM for brightness 1
case 2 : TM_SendCmd &h89 'Turn display on and set PWM for brightness 2
case 3 : TM_SendCmd &h8A 'Turn display on and set PWM for brightness 3
case 4 : TM_SendCmd &h8B 'Turn display on and set PWM for brightness 4
case 5 : TM_SendCmd &h8C 'Turn display on and set PWM for brightness 5
case 6 : TM_SendCmd &h8D 'Turn display on and set PWM for brightness 6
case 7 : TM_SendCmd &h8E 'Turn display on and set PWM for brightness 7
case 8 : TM_SendCmd &h8F 'Turn display on and set PWM for brightness 8 Max
case else : TM_SendCmd &h8F 'Turn display on and set PWM for brightness 8 Max
end select
end sub
sub TM_Show(sString)
local bChar as byte
local bOut as byte
local i as byte
local bAdr as byte
local flag as byte
TM_SendCmd 0x44 ' fixed adress mode
bAdr = 0xCE
for i = len(sString) to 1 step -1
bChar = Asc(sString , i )
bChar = bChar - 40
if bChar > 83 then
bOut = &B00000000
else
bOut = lookup(bChar , digits)
end if
if flag = 1 then
bOut.7 = 1 ' . or ,
flag = 0
end if
if bChar = 4 or bChar = 6 then
flag = 1
else
TM_SendCmdData bAdr , bOut
bAdr = bAdr - 2
end if
next i
end sub
sub TM_Clear()
local i as byte
TM_SendCmd 0x44 ' fixed adr mode
for i = 0xC0 to 0xCF step 2 ' digits only, not LEDs
TM_SendCmdData i , 0
next
end sub
sub TM_SetLED(byval bLedByte as byte)
local i as byte
local bAdr as byte
i = 7
for bAdr = 0xC1 to 0xCF step 2
TM_SendCmdData bAdr , bLedByte.i
decr i
next
end sub
sub TM_Wrbyte(bdata)
local i as byte
for i = 0 To 7 'LSB first
reset TM_CLK
TM_DOUT = bdata.i
waitus 2
set TM_CLK
waitus 2
next
end sub
sub TM_SendCmd(bCmd)
reset TM_STB
waitus 2
reset TM_DOUT
TM_Wrbyte bCmd
waitus 2
set TM_STB
end sub
sub TM_SendCmdData(bCmd , bData)
reset TM_STB
waitus 2
reset TM_DOUT
TM_Wrbyte bCmd
waitus 2
TM_Wrbyte bData
waitus 2
set TM_STB
end sub
function TM_GetKeys() as byte
local i as byte
local dwKeys as dword
local bOut as byte
reset TM_STB
waitus 2
reset TM_DOUT
TM_Wrbyte 0x42
waitus 2
config TM_DOUT = input
set TM_DOUT ' pullup to Vcc
for i = 0 to 31
reset TM_CLK
waitus 2
set TM_CLK
waitus 2
dwKeys.i = TM_DIN
next i
set TM_STB
config TM_DOUT = output
bOut.7 = dwKeys.0
bOut.6 = dwKeys.8
bOut.5 = dwKeys.16
bOut.4 = dwKeys.24
bOut.3 = dwKeys.4
bOut.2 = dwKeys.12
bOut.1 = dwKeys.20
bOut.0 = dwKeys.28
TM_GetKeys = bOut
end function
'*******************************************************************************
' Copy this code to the end of main module and uncomment it
'*******************************************************************************
'(
digits:
Data &B01011000 '/
Data &B01001100 '/
Data &B01100011 '*
Data &B00000000 '
Data &B10000000 ',
Data &B01000000 '-
Data &B10000000 '.
Data &B00000000 '
Data &B00111111 '0
Data &B00000110 '1
Data &B01011011 '2
Data &B01001111 '3
Data &B01100110 '4
Data &B01101101 '5
Data &B01111101 '6
Data &B00000111 '7
Data &B01111111 '8
Data &B01101111 '9
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B01001000 '=
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B01110111 'A
Data &B01111100 'b
Data &B00111001 'C
Data &B01011110 'd
Data &B01111001 'E
Data &B01110001 'F
Data &B01111101 'G
Data &B01110110 'H
Data &B00110000 'I
Data &B00001110 'J
Data &B00000000 '
Data &B00111000 'L
Data &B00000000 '
Data &B01010100 'n
Data &B00111111 'O
Data &B01110011 'P
Data &B01100111 'q
Data &B11110111 'R
Data &B01101101 'S
Data &B01111000 't
Data &B00111110 'U
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B00111001 '[
Data &B00000000 '
Data &B00001111 ']
Data &B00000000 '
Data &B00001000 '_
Data &B00000000 '
Data &B11011111 'a
Data &B01111100 'b
Data &B01011000 'c
Data &B01011110 'd
Data &B01111001 'E
Data &B01110001 'F
Data &B11101111 'g
Data &B01110100 'h
Data &B00010000 'i
Data &B00001110 'J
Data &B00000000 '
Data &B00111000 'L
Data &B00000000 '
Data &B01010100 'n
Data &B01011100 'o
Data &B01110011 'P
Data &B01100111 'q
Data &B01010000 'r
Data &B01101101 'S
Data &B01111000 't
Data &B00011100 'u
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
Data &B00000000 '
')
TM1638_end:Отредактировано Cirno_9 (2021-12-01 09:54:07)


