Вот такая заготовка для всяких поделок типа вольтметров, счетчиков, датчиков и т.д. и т.п.
А вот пример кода для вольт-амперметра с программным шимом и опросом энкодера:
@device = pic16F676, intrc_osc_noclkout, wdt_on, mclr_off, protect_off
osccal = %11111100
enc1 var porta.5
enc2 var porta.4
butt var porta.3
D_C var portc.3
rst var portc.2
SDIN var portc.4
SCK var portc.5
shim var porta.2
voltm con 0 'an0
ampm con 1 'an1
define adc_bits 10
define adc_clock 3
define adc_sampleus 50
adval var word
trisa=%00111011
trisc=0
CMCON = 7
ANSEL = %00000011 ' an1, AN0
adcon0=%10000000 ' правое выравнивание, опорное - питание
LcdReg var byte
x var byte
y var byte
t var byte
e var byte
z var byte
Offset var byte
Char var byte
a var byte
tmpshim var byte
shcount var byte
portc = 0
counter var word
encstate var byte
new var byte
ioca = %00111000
wpua = %00110100
tmr0 = 255
INTCON = %10101000
OPTION_REG = %00000000
counter = 0
tmpshim = 0
shcount = 255
on interrupt goto encoder
DATA @0,$3E,$51,$49,$45,$3E,_ ';// 0
$00,$42,$7F,$40,$00,_ ';// 1
$42,$61,$51,$49,$46,_ ';// 2
$21,$41,$45,$4B,$31,_ ';// 3
$18,$14,$12,$7F,$10,_ ';// 4
$27,$45,$45,$45,$39,_ ';// 5
$3C,$4A,$49,$49,$30,_ ';// 6
$01,$71,$09,$05,$03,_ ';// 7
$36,$49,$49,$49,$36,_ ';// 8
$06,$49,$49,$29,$1E,_ ';// 9
$08,$08,$3E,$08,$08,_ ';// +
$08,$08,$08,$08,$08,_ ';// -
$00,$60,$60,$00,$00,_ ';// .
$3F,$40,$40,$40,$3F,_ ';// U
$7E,$11,$11,$11,$7E,_ ';// A
$00,$41,$7F,$41,$00,_ ';// I
$1F,$20,$40,$20,$1F ';// V
RST = 1
LcdReg = %00100001 'LCD Extended Commands.
call PrintCtrlLcd
LcdReg = 228 'Set LCD Vop (Contrast).
call PrintCtrlLcd
LcdReg = %00000111 'Set Temp coefficent.
call PrintCtrlLcd
LcdReg = %00010011 'LCD bias mode 1:48.
call PrintCtrlLcd
LcdReg = %00100000 'LCD Standard Commands, Horizontal addressing mode.
call PrintCtrlLcd
LcdReg = %00001100
call PrintCtrlLcd
call CursorHome
Call ClearLcd
Main: y = 1
x = 0
Char = 13 ' "U"
call PrintWChar
x = 24
adcin voltm, adval
adval = adval*3
Char = (adval dig 3) ' десятые
call PrintWChar
Char = (adval dig 2) ' единицы
call PrintWChar
Char = 12 ' точка
call PrintWChar
Char = (adval dig 1) ' десятые
call PrintWChar
Char = (adval dig 0) ' сотые
call PrintWChar
x = 0
y = 3
Char = 15 ' "I"
call PrintWChar
x = 24
adcin ampm, adval
adval = adval*3
Char = (adval dig 3) ' единицы
call PrintWChar
Char = 12 ' точка
call PrintWChar
Char = (adval dig 2) ' десятые
call PrintWChar
Char = (adval dig 1) ' сотые
call PrintWChar
Char = (adval dig 0) ' тысячн
call PrintWChar
y = 5
x = 0
Char = (counter dig 4) ' десятые
call PrintChar
Char = (counter dig 3) ' десятые
call PrintChar
Char = (counter dig 2) ' точка
call PrintChar
Char = (counter dig 1) ' десятые
call PrintChar
Char = (counter dig 0) ' сотые
call PrintChar
'PAUSE 500
Goto main
disable
encoder: if intcon.0 = 1 then
intcon.0 = 0
new = enc1 + enc2 * 2
if encstate = 2 then
if new = 3 then counter = counter + 1
if new = 0 then counter = counter - 1
endif
if encstate = 0 then
if new = 2 then counter = counter + 1
if new = 1 then counter = counter - 1
endif
if encstate = 1 then
if new = 0 then counter = counter + 1
if new = 3 then counter = counter - 1
endif
if encstate = 3 then
if new = 1 then counter = counter + 1
if new = 2 then counter = counter - 1
endif
encstate = new
counter = counter & %0000001111111111
endif
if intcon.2 = 1 then
intcon.2 = 0
tmr0 = 255
shcount = shcount - 1
if shcount = 0 then tmpshim = counter >> 2
if tmpshim > 0 then
shim = 1
tmpshim = tmpshim - 1
else
shim = 0
endif
endif
resume
enable
' Перевод курсора x=0..83 y=0..5
CursorHome: x = 0
y = 0
SetCursor: LcdReg = %10000000 + x ' cursor X
call PrintCtrlLcd
LcdReg = %01000000 + y ' cursor Y
call PrintCtrlLcd
return
PrintChar: offset = Char * 5
call SetCursor
for a = 1 to 5
read offset, LcdReg
call PrintDataLcd
offset = offset + 1
next a
x = x + 6
return
' печать символа удвоенного размера
PrintWChar: offset = Char * 5
for a = 1 to 5
read offset, z
t = (z & 1)*3
t = t|((z & 2)*6)
t = t|((z & 4)*12)
t = t|((z & 8)*24)
call SetCursor
LcdReg = t
call PrintDataLcd
LcdReg = t
call PrintDataLcd
z = z >> 4
t = (z & 1)*3
t = t|((z & 2)*6)
t = t|((z & 4)*12)
t = t|((z & 8)*24)
y = y + 1
call SetCursor
LcdReg = t
call PrintDataLcd
LcdReg = t
call PrintDataLcd
offset = offset + 1
x = x + 2
y = y - 1
next a
x = x + 2
return
' очистка китайца (708 нулевых байта)
ClearLcd:
D_C = 1
LcdReg = 0
for t = 0 to 235
for a = 0 to 2
call PrintDataLcd
next a
next t
Return
' отправка данных/команд на lcd
PrintCtrlLcd: D_C = 0
PrintDataLcd: for e = 1 to 8
SDIN = LcdReg.7
LcdReg = LcdReg << 1
SCK = 1
SCK = 0
next e
D_C = 1
return
end
вольтметр висит на AN0, амперметр на AN1, вывод шима с RA2. частотой програмный шим не блещет, поэтому фильтр я на него вешал из 2 резисторов на 4.7к и 2 емкостей 10 мкФ...


простой индикатор заряда lion-элемента 2


2972 просмотров
комментировать