펌웨어디자인(Firmware Design)

충전기제작

arirangled 2006. 5. 5. 11:46
Intelligent NiCd/NiMH Charger/Cycler with 2x16 Character LCD

http://www.oshonsoft.com/picchargerlcd.html

 

제어부회로도

 

 

충전부회로도

 

 

**********프로그램소스리스트*************

Define CLOCK_FREQUENCY = 12
Define CONF_WORD = 0x3f72

Symbol t_right = PORTB.3
Symbol t_down = PORTB.2
Symbol t_up = PORTB.1
Symbol t_left = PORTB.0
Symbol ledcharge = PORTA.1
Symbol leddischarge = PORTA.5
Symbol charge = PORTC.2
Symbol discharge = PORTC.1
Symbol i2cclock = PORTC.3
Symbol i2cdata = PORTC.4

Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4
Define LCD_RSREG = PORTC
Define LCD_RSBIT = 0
Define LCD_EREG = PORTC
Define LCD_EBIT = 5

Const c_right = 1
Const c_up = 2
Const c_down = 3
Const c_left = 4

Dim vin As Word
Dim i As Byte
Dim j As Byte
Dim an0 As Word
Dim vmod As Word
Dim vfinal As Word

Dim v(13) As Word
Dim vlast As Word
Dim vmax As Word
Dim vmaxdelay As Byte

Dim finish As Bit
Dim address As Word
Dim seconds As Word
Dim minutes As Word

Dim voltage As Word
Dim voltage1 As Word
Dim voltage2 As Word
Dim count As Word
Dim sample As Word

Dim program As Byte
Dim phase As Byte
Dim key As Byte

Dim dischargelimit As Word
Dim signalfiltertype As Byte
Dim peakgap As Byte
Dim peakdetect As Byte
Dim mintime As Byte
Dim minvalue As Word
Dim maxtime As Word

PORTA = 0
PORTB = 0
PORTC = 0
TRISA.1 = 0
TRISA.5 = 0
TRISC.2 = 0
TRISC.1 = 0
ADCON1 = 0x0f
Hseropen 19200
Lcdinit
WaitMs 1000

Gosub loadparameters

newprogram:
Gosub welcome
Gosub selectprogram
If program = 1 Then Gosub prog_charge
If program = 2 Then Gosub prog_discharge
If program = 3 Then Goto prog_cycle
If program = 4 Then Goto prog_setup
If program = 5 Then Gosub prog_setupdefaults
If program = 6 Then Gosub prog_memory
Goto newprogram
End

welcome:
Lcdcmdout LcdClear
Lcdout "OshonSoft Cycler"
Lcdcmdout LcdLine2Home
Lcdout "Initializing..."
WaitMs 4000
Return

selectprogram:
phase = 1
Lcdcmdout LcdClear
Lcdout "Select Program:"
krug1:
Lcdcmdout LcdLine2Clear
If phase = 1 Then Lcdout "1-Charge"
If phase = 2 Then Lcdout "2-Discharge"
If phase = 3 Then Lcdout "3-Cycle"
If phase = 4 Then Lcdout "4-Setup"
If phase = 5 Then Lcdout "5-Setup defaults"
If phase = 6 Then Lcdout "6-Memory"
Gosub waitkey
If key = c_down Then
 phase = phase + 1
 If phase = 7 Then phase = 1
 Goto krug1
Endif
If key = c_up Then
 phase = phase - 1
 If phase = 0 Then phase = 6
 Goto krug1
Endif
If key = c_right Then program = phase
If key = c_left Then program = 0
Return

waitkey:
key = 0
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
If key = 0 Then Goto waitkey
Gosub debounce
Return

getkey:
key = 0
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
If key > 0 Then Gosub debounce
Return

debounce:
If t_right = 1 Then i = 0
If t_up = 1 Then i = 0
If t_down = 1 Then i = 0
If t_left = 1 Then i = 0
i = i + 1
WaitMs 10
If i < 10 Then Goto debounce
Return

scankey:
If t_right = 1 Then key = c_right
If t_up = 1 Then key = c_up
If t_down = 1 Then key = c_down
If t_left = 1 Then key = c_left
Return

initroutine:
Lcdcmdout LcdClear
Lcdout "Starting..."
WaitMs 5000
Gosub getvin
For i = 1 To 12
 v(i) = vin
Next i
vlast = 0
vmax = 0
vmaxdelay = 0
finish = 0
address = 0
seconds = 0
minutes = 0
key = 0
Lcdcmdout LcdClear
Return

prog_discharge:
discharge = 1
leddischarge = 1
Gosub initroutine
Lcdout "Discharging..."
Lcdcmdout LcdLine2Home
While finish = 0
 If signalfiltertype = 1 Then Gosub getvfinal1
 If signalfiltertype = 2 Then Gosub getvfinal2
 If signalfiltertype = 3 Then Gosub getvfinal3
 If signalfiltertype = 4 Then Gosub getvfinal4
 If signalfiltertype = 5 Then Gosub getvfinal5
 If vfinal <= dischargelimit Then finish = 1
 Gosub settime
 Gosub showvoltage
 Gosub storeeeprom
 Gosub serialroutine
 If key = c_left Then finish = 1
 key = 0
Wend
Lcdcmdout LcdLine1Clear
Lcdout "Completed!"
discharge = 0
leddischarge = 0
Gosub endroutine
WaitMs 3000
Return

prog_charge:
charge = 1
ledcharge = 1
Gosub initroutine
Lcdout "Charging..."
Lcdcmdout LcdLine2Home
While finish = 0
 If signalfiltertype = 1 Then Gosub getvfinal1
 If signalfiltertype = 2 Then Gosub getvfinal2
 If signalfiltertype = 3 Then Gosub getvfinal3
 If signalfiltertype = 4 Then Gosub getvfinal4
 If signalfiltertype = 5 Then Gosub getvfinal5
 If vfinal > vmax Then vmaxdelay = vmaxdelay + 1
 If vmaxdelay = 5 Then
  vmax = vfinal
  vmaxdelay = 0
 Endif
 If peakdetect = 1 Then
  vfinal = vfinal + peakgap
  If vfinal <= vmax Then finish = 1
  vfinal = vfinal - peakgap
 Endif
 If minutes < mintime Then
  finish = 0
  vmax = vfinal
  vmaxdelay = 0
 Endif
 If vfinal < minvalue Then
  finish = 0
  vmax = vfinal
  vmaxdelay = 0
 Endif
 If minutes >= maxtime Then finish = 1
 Gosub settime
 Gosub showvoltage
 Gosub storeeeprom
 Gosub serialroutine
 If key = c_left Then finish = 1
 key = 0
Wend
Lcdcmdout LcdLine1Clear
Lcdout "Completed!"
charge = 0
ledcharge = 0
Gosub endroutine
WaitMs 3000
Return

prog_cycle:
Gosub prog_discharge
WaitMs 10000
Gosub prog_charge
Goto newprogram
Return

prog_setupdefaults:
dischargelimit = 370
signalfiltertype = 2
peakgap = 2
peakdetect = 1
mintime = 5
minvalue = 615
maxtime = 120
Gosub saveparameters
Return

prog_setup:
phase = 1
setupkrug:
Lcdcmdout LcdClear
Lcdout "Setup Options:"
Lcdcmdout LcdLine2Clear
If phase = 1 Then Lcdout "1-DischargeLimit"
If phase = 2 Then Lcdout "2-FilterType"
If phase = 3 Then Lcdout "3-PeakGap"
If phase = 4 Then Lcdout "4-PeakDetect"
If phase = 5 Then Lcdout "5-MinTime"
If phase = 6 Then Lcdout "6-MinValue"
If phase = 7 Then Lcdout "7-MaxTime"
Gosub waitkey
If key = c_down Then
 phase = phase + 1
 If phase = 8 Then phase = 1
 Goto setupkrug
Endif
If key = c_up Then
 phase = phase - 1
 If phase = 0 Then phase = 7
 Goto setupkrug
Endif
If key = c_right Then
 If phase = 1 Then Gosub setup1
 If phase = 2 Then Gosub setup2
 If phase = 3 Then Gosub setup3
 If phase = 4 Then Gosub setup4
 If phase = 5 Then Gosub setup5
 If phase = 6 Then Gosub setup6
 If phase = 7 Then Gosub setup7
 Goto setupkrug
Endif
If key = c_left Then Gosub saveparameters
Goto newprogram
Return

setup1:
Lcdcmdout LcdClear
Lcdout "DischargeLimit:"
Lcdcmdout LcdLine2Home
Lcdout #dischargelimit
Lcdout "   "
vfinal = dischargelimit
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
 If dischargelimit < 1000 Then dischargelimit = dischargelimit + 5 Else dischargelimit = 10
 Goto setup1
Endif
If key = c_down Then
 If dischargelimit > 10 Then dischargelimit = dischargelimit - 5 Else dischargelimit = 1000
 Goto setup1
Endif
Return

setup2:
Lcdcmdout LcdClear
Lcdout "FilterType:"
Lcdcmdout LcdLine2Home
Lcdout #signalfiltertype
Lcdout "   "
If signalfiltertype = 1 Then Lcdout "Raw values"
If signalfiltertype = 2 Then Lcdout "Average LO"
If signalfiltertype = 3 Then Lcdout "Average2 LO"
If signalfiltertype = 4 Then Lcdout "Average HI"
If signalfiltertype = 5 Then Lcdout "Average2 HI"
Gosub waitkey
If key = c_up Then
 If signalfiltertype < 5 Then signalfiltertype = signalfiltertype + 1
 Goto setup2
Endif
If key = c_down Then
 If signalfiltertype > 1 Then signalfiltertype = signalfiltertype - 1
 Goto setup2
Endif
Return

setup3:
Lcdcmdout LcdClear
Lcdout "PeakGap:"
Lcdcmdout LcdLine2Home
Lcdout #peakgap
Lcdout "   "
vfinal = peakgap
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
 If peakgap < 10 Then peakgap = peakgap + 1 Else peakgap = 1
 Goto setup3
Endif
If key = c_down Then
 If peakgap > 1 Then peakgap = peakgap - 1 Else peakgap = 10
 Goto setup3
Endif
Return

setup4:
Lcdcmdout LcdClear
Lcdout "PeakDetect:"
Lcdcmdout LcdLine2Home
Lcdout #peakdetect
Lcdout "   "
If peakdetect = 0 Then Lcdout "Off"
If peakdetect = 1 Then Lcdout on "
Gosub waitkey
If key = c_up Then
 peakdetect = 1
 Goto setup4
Endif
If key = c_down Then
 peakdetect = 0
 Goto setup4
Endif
Return

setup5:
Lcdcmdout LcdClear
Lcdout "MinTime:"
Lcdcmdout LcdLine2Home
Lcdout #mintime, " min"
Gosub waitkey
If key = c_up Then
 If mintime < 30 Then mintime = mintime + 1 Else mintime = 1
 Goto setup5
Endif
If key = c_down Then
 If mintime > 1 Then mintime = mintime - 1 Else mintime = 30
 Goto setup5
Endif
Return

setup6:
Lcdcmdout LcdClear
Lcdout "MinValue:"
Lcdcmdout LcdLine2Home
Lcdout #minvalue
Lcdout "   "
vfinal = minvalue
Gosub showvoltageonly
Gosub waitkey
If key = c_up Then
 If minvalue < 1000 Then minvalue = minvalue + 5 Else minvalue = 10
 Goto setup6
Endif
If key = c_down Then
 If minvalue > 10 Then minvalue = minvalue - 5 Else minvalue = 1000
 Goto setup6
Endif
Return

setup7:
Lcdcmdout LcdClear
Lcdout "MaxTime:"
Lcdcmdout LcdLine2Home
Lcdout #maxtime, " min"
Gosub waitkey
If key = c_up Then
 If maxtime < 1000 Then maxtime = maxtime + 5 Else maxtime = 10
 Goto setup7
Endif
If key = c_down Then
 If maxtime > 10 Then maxtime = maxtime - 5 Else maxtime = 1000
 Goto setup7
Endif
Return

loadparameters:
address = 30000
I2CRead i2cdata, i2cclock, 0xa0, address, dischargelimit.LB, dischargelimit.HB
address = 30002
I2CRead i2cdata, i2cclock, 0xa0, address, signalfiltertype
address = 30003
I2CRead i2cdata, i2cclock, 0xa0, address, peakgap
address = 30004
I2CRead i2cdata, i2cclock, 0xa0, address, peakdetect
address = 30005
I2CRead i2cdata, i2cclock, 0xa0, address, mintime
address = 30006
I2CRead i2cdata, i2cclock, 0xa0, address, minvalue.LB, minvalue.HB
address = 30008
I2CRead i2cdata, i2cclock, 0xa0, address, maxtime.LB, maxtime.HB
If dischargelimit < 10 Then dischargelimit = 10
If dischargelimit > 1000 Then dischargelimit = 1000
If signalfiltertype < 1 Then signalfiltertype = 1
If signalfiltertype > 5 Then signalfiltertype = 5
If peakgap < 1 Then peakgap = 1
If peakgap > 10 Then peakgap = 10
If peakdetect > 1 Then peakdetect = 1
If mintime < 1 Then mintime = 1
If mintime > 30 Then mintime = 30
If minvalue < 10 Then minvalue = 10
If minvalue > 1000 Then minvalue = 1000
If maxtime < 10 Then maxtime = 10
If maxtime > 1000 Then maxtime = 1000
Return

saveparameters:
address = 30000
I2CWrite i2cdata, i2cclock, 0xa0, address, dischargelimit.LB, dischargelimit.HB
WaitMs 20
address = 30002
I2CWrite i2cdata, i2cclock, 0xa0, address, signalfiltertype
WaitMs 20
address = 30003
I2CWrite i2cdata, i2cclock, 0xa0, address, peakgap
WaitMs 20
address = 30004
I2CWrite i2cdata, i2cclock, 0xa0, address, peakdetect
WaitMs 20
address = 30005
I2CWrite i2cdata, i2cclock, 0xa0, address, mintime
WaitMs 20
address = 30006
I2CWrite i2cdata, i2cclock, 0xa0, address, minvalue.LB, minvalue.HB
WaitMs 20
address = 30008
I2CWrite i2cdata, i2cclock, 0xa0, address, maxtime.LB, maxtime.HB
WaitMs 20
Return

getvin:
vin = 0
For i = 1 To 60
 Adcin 0, an0
 vin = vin + an0
 Gosub scankey
 WaitMs 82
 WaitUs 500
Next i
vmod = vin Mod 60
vin = vin / 60
If vmod >= 30 Then vin = vin + 1
Return

getvfinal1:
Gosub getvin
vfinal = vin
Return

getvfinal2:
For i = 1 To 5
 j = i + 1
 v(i) = v(j)
Next i
Gosub getvin
v(6) = vin
vfinal = 0
For i = 1 To 6
 vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 6
vfinal = vfinal / 6
If vmod >= 3 Then vfinal = vfinal + 1
Return

getvfinal3:
For i = 1 To 5
 j = i + 1
 v(i) = v(j)
Next i
Gosub getvin
v(6) = vin
vfinal = 0
For i = 1 To 6
 vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 6
vfinal = vfinal / 6
If vmod >= 3 Then vfinal = vfinal + 1
If vfinal > vlast Then
 For i = 1 To 4
  v(i) = vfinal
 Next i
 For i = 5 To 6
  v(i) = vfinal + 1
 Next i
Endif
vlast = vfinal
Return

getvfinal4:
For i = 1 To 11
 j = i + 1
 v(i) = v(j)
Next i
Gosub getvin
v(12) = vin
vfinal = 0
For i = 1 To 12
 vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 12
vfinal = vfinal / 12
If vmod >= 6 Then vfinal = vfinal + 1
Return

getvfinal5:
For i = 1 To 11
 j = i + 1
 v(i) = v(j)
Next i
Gosub getvin
v(12) = vin
vfinal = 0
For i = 1 To 12
 vfinal = vfinal + v(i)
Next i
vmod = vfinal Mod 12
vfinal = vfinal / 12
If vmod >= 6 Then vfinal = vfinal + 1
If vfinal > vlast Then
 For i = 1 To 8
  v(i) = vfinal
 Next i
 For i = 9 To 12
  v(i) = vfinal + 1
 Next i
Endif
vlast = vfinal
Return

showvoltage:
'0V=0  2.5V=1023  2500/1023=2.444
voltage = (vfinal * 2) + (vfinal * 4 / 10)
voltage = voltage + (vfinal * 4 / 100) + (vfinal * 4 / 1000)
voltage1 = voltage / 1000
voltage2 = voltage Mod 1000
Lcdcmdout LcdLine2Clear
Lcdout #voltage1, "."
If voltage2 < 100 Then Lcdout "0"
If voltage2 < 10 Then Lcdout "0"
Lcdout #voltage2, "V(", #vfinal, "),", #minutes, "m"
Return

showvoltageonly:
'0V=0  2.5V=1023  2500/1023=2.444
voltage = (vfinal * 2) + (vfinal * 4 / 10)
voltage = voltage + (vfinal * 4 / 100) + (vfinal * 4 / 1000)
voltage1 = voltage / 1000
voltage2 = voltage Mod 1000
Lcdout #voltage1, "."
If voltage2 < 100 Then Lcdout "0"
If voltage2 < 10 Then Lcdout "0"
Lcdout #voltage2, "V"
Return

serialroutine:
Hserout #vfinal, Lf
Return

endroutine:
address = address + 2
I2CWrite i2cdata, i2cclock, 0xa0, address, 255, 255
address = address - 2
Return

storeeeprom:
address = address + 2
I2CWrite i2cdata, i2cclock, 0xa0, address, vfinal.LB, vfinal.HB
Return

settime:
seconds = seconds + 2
If seconds >= 60 Then
 seconds = 0
 minutes = minutes + 1
Endif
Return

prog_memory:
finish = 0
While finish = 0
 Lcdcmdout LcdClear
 Lcdout "Memory Ready..."
 Gosub waitkey
 If key = c_left Then finish = 1
 If key = c_right Then
  For count = 2 To 20000 Step 2
   I2CRead i2cdata, i2cclock, 0xa0, count, sample.LB, sample.HB
   If sample = 65535 Then Goto exit2
   Hserout #sample, Lf
  Next count
  exit2:
  address = count - 2
 Endif
Wend
Return

Intelligent NiCd/NiMH Charger/Cycler with 128x64 Graphical LCD

http://www.oshonsoft.com/picchargerlcdpro.html

회로도와 프로그램소스는 접근해서 다운로드 바랍니다. 컴파일러는 PICBASIC 데모용으로 가능할 것 같습니다.

回路図とプログラムソースは近付いてダウンロード願います.コンパイラーは PICBASIC デモ用で可能だと思います.挑戦して見てください.

반응형

'펌웨어디자인(Firmware Design)' 카테고리의 다른 글

PIC12F629  (0) 2006.07.24
PIC베이직컴파일러참조매뉴얼  (0) 2006.05.05
PIC18F8490  (0) 2006.03.10
asass  (0) 2006.02.05
마이크로칩사 원칩마이컴IC  (0) 2006.01.03