Стали у нас менять в домах электросчетчики по истечению межповерочного интервала.
Вообще-то их можно поверять, но предпочитают просто менять на новые, а старые выбрасывают.
Не могла пройти мимо и подобрала несколько штук.
Вскрытие показало, что внутри счетчика (СЭБ - 2А) стоит ЖКИ, у которого рабочими являются всего 5 ног, остальные по углам -- крепежные и никуда не подключены.
До этого мне уже попадались ЖКИ счетчиков со встроенным контроллером, причем I2C (счетчики НЕВА).
Однако небольшой реверс-инжинириг схемы включения показал, что здесь какой-то другой интерфейс. На самом дислпее какие-либо обозначения отсуствовали.
У него было 5 ног и 8 разраядов, точка в каждом разряде, а также галочка V под каждым разрядом для указания на какую-нибудь надпись - обозначение функции прибора.
После некоторого гугления и реверс-инжиниринга стало понятно, что мой дисплей очень похож на типовой TIC55M с чипом MT1001.
Копание в даташитах и метод тыка позволили запустить дисплей.
Для тех, кто совсем не встречался ЖКИ типа TIC, краткий экскурс. Два вывода -- это Vcc и GND. Остальные три имеют следующее назначение: DATA -- сюда мы выставляем передаваемые данные; CLK -- такт. При подаче "1" данные с вывода DATA записываются в сдвиговый регистр. LOAD -- при подаче сюда "1" данные из регистра переписываются в регистр индикации и начинают отображаться на экране. Каждый записанный бит соответствует одному сегменту индикатора. В моем случае для одного знакоместа следовало передать 9 бит: 7 для сегментов, один управлял десятичной точкой, и еще один -- галочкой под разрядом. Всего, стало быть, необходимо передать 8 разрядов * 9 бит = 72 бита (здесь отличие от TIC55, которому, согласно datasheet, следует передавать 80 бит несмотря на то, что сегментов у него всего 72).
В итоге я сделала простую демо-программку, которая управляет ЖКИ. Чтобы не было совсем скучно и дисплей показывал какие-нибудь данные, я прицепила термометр DS18B20. Кстати, я написала корректный код для считывания DS18B20 в виде числа с плавающей точкой, который реализует максимальную точность датчика и корректно считает отрицательные температуры -- потому что в интернете полно неправильных примеров, которые только вводят в заблуждение.
Ловите
' -----------------------------------------------------------
' Пример работы с ЖКИ с последовательной загрузкой данных
' в регистр сдвига. аналог TIC55M. 5 выводов, 8 знакомест и галочки под
' каждым знакоместом. в отличие от оригинального TIC55, в этот
' ЖКИ надо задвигать всего 72 бита, а не 80, как в TIC55.
' Назначение выводов: (1- Vcc, 2 - GND, 3- LOAD) ... (4 - DATA, 5 - CLK)
' Vcc 3V3...5V. Сигнальные выводы следует притянуть к GND через 10K,
' сигналы подавать через ~5K, хотя работает и так. Это может быть важно, если вы
' планируете реализовать прибор с питанием от батарейки, и МК будет уходить
' в режим сна -- индикатору не нравятся "болтающиеся в воздухе" выводы.
'
' Written by Cirno_9 (t.me/Cirno9)
' -----------------------------------------------------------
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
config submode = new
LCD_LOAD alias PORTD.5 ' pin used to load data from shift-regiter content to display
LCD_DATA alias PORTD.6 ' serial data pin
LCD_DCLK alias PORTD.7 ' clock of data ("1" stores data from data pin to register)
config LCD_LOAD = output
config LCD_DATA = output
config LCD_DCLK = output
LCD_LOAD = 0
LCD_DATA = 0
LCD_DCLK = 0
config 1wire = PortD.4 ' uses by DS18B20 sensor
dim wserial(8) as word ' uses by tic55 procedures
declare sub tic55_display(byval ss as string) ' show string to display
declare sub tic55_set_checkmark(byval pos as byte) ' set chekmark sign "v" in specified position
declare sub _tic55_send_data() ' internal use sub
declare function ds18b20_read() as single ' get temperature from DS18B20
dim thermo as single
dim ss as string * 8
do
thermo = ds18b20_read()
ss = fusing(thermo , "0.0") + "*C"
tic55_display ss
loop
end
' -----------------------------------------------------------
' TIC55M
' -----------------------------------------------------------
sub tic55_set_checkmark(byval pos as byte)
' display chekmark "v" in the specified position.
' pos = 0...8, pos = 0 clears all chekmarks.
if pos = 0 then
for pos = 1 to 8
wserial(pos).7 = 0
next
else
wserial(pos) = wserial(pos) or &b0000_0000_1000_0000
end if
_tic55_send_data
end sub
' -----------------------------------------------------------
sub tic55_display(byval ss as string)
' shows string to display.
' string can contains any digits, some symbols...
' (letter C, sing * means "degreee sign", sign "-")...
' and the "dot" symbol.
' you can add all other aplhabet simbols and
' special characters by yourself if you need.
local i as byte , j as byte , bchar as byte
ss = ucase(ss) ' remove this line if you'll need to display a small letters
j = 1
for i = 1 to len(ss)
bchar = asc(ss , i)
select case bchar
case 42 ' degree sign
wserial(j) = &b0000_0000_0011_1100
case 45 ' minus sign
wserial(j) = &b0000_0000_0000_0100
case 46 ' dot sign
decr j
wserial(j) = wserial(j) or &b0000_0001_0000_0000
case 48 to 57 ' digits
bchar = bchar - 48
wserial(j) = lookup(bchar , digits)
case 67 ' "C" letter
wserial(j) = &b0000_0000_0001_1011
case else ' space
wserial(j) = &b0000_0000_0000_0000
end select
incr j
if j = 9 then exit for
next
' fill unused positions by space
while j < 9
wserial(j) = &b0000_0000_0000_0000 ' space
incr j
wend
_tic55_send_data
end sub
' -----------------------------------------------------------
sub _tic55_send_data() ' send data to the display (72 bits must be sent)
local i as byte , j as byte
for j = 8 to 1 step -1 ' symbols
for i = 8 to 0 step -1 ' bits for each symbol
LCD_DATA = wserial(j).i ' set bit to DATA line
LCD_DCLK = 1 ' }
waitus 10 ' } (just use "nop" for slow microcotrollers less or eq 4 MHz)
LCD_DCLK = 0 ' } clock to store data bit to display register
next
next
LCD_LOAD = 1 ' }
waitus 10 ' } (just use "nop" for slow microcotrollers less or eq 4 MHz)
LCD_LOAD = 0 ' } show register data on the display
end sub
' -----------------------------------------------------------
' DS18B20
' -----------------------------------------------------------
function ds18b20_read() as single
local lsb as byte , msb as byte , nvalue as integer , fvalue as single , sign as byte
1wreset
1wwrite &HCC ' command: call DS18B20 indirect (single sensor inline)
1wwrite &H44 ' command: start themperature measuring
waitus 780
1wreset
1wwrite &HCC ' command: call DS18B20 indirect (single sensor inline)
1wwrite &HBE ' command: read DS18B20 data
lsb = 1wread()
msb = 1wread()
sign = msb.7 ' bits 7...3 of msb means temperature less 0
if sign = 1 then
msb = 0xFF - msb ' }
lsb = 0xFF - lsb ' } convert if value less 0
incr lsb ' an 1 must be to added to lsb
else
msb = msb and &b0000_0111 ' clear bits 7...3 if temperature over or eq 0
end if
nvalue = makeint(lsb , msb)
if sign = 1 then nvalue = -nvalue
fvalue = nvalue
fvalue = fvalue / 16
ds18b20_read = fvalue
end function
' -----------------------------------------------------------
' TIC55M DIGITS CODE
' -----------------------------------------------------------
digits:
' A
' F B
' G
' E C
' D
' ._vCBA_FGED ' bit order
data &b0000_0000_0111_1011% ' 0
data &b0000_0000_0110_0000% ' 1
data &b0000_0000_0011_0111% ' 2
data &b0000_0000_0111_0101% ' 3
data &b0000_0000_0110_1100% ' 4
data &b0000_0000_0101_1101% ' 5
data &b0000_0000_0101_1111% ' 6
data &b0000_0000_0111_0000% ' 7
data &b0000_0000_0111_1111% ' 8
data &b0000_0000_0111_1111% ' 9



