Reporte de Inversor PIC16f87X
-
Upload
reynaldo-martinez -
Category
Documents
-
view
235 -
download
0
Transcript of Reporte de Inversor PIC16f87X
-
8/6/2019 Reporte de Inversor PIC16f87X
1/42
Fuel Cell Powered Go-Kart
Final Report
ECE 291: Spring 2002
Team 2:
Peter Prizio (EE)
Brian Stevens (EE)
Anhtuan Truong (EE)
Kenneth Cappola (ME)
James OBrien (ME)
Nathan Snape (ME)
Advisor:
Professor Martin D. Fox
Sponsored by the University Of Connecticut
Contact:
Professor James M. Fenton, Chemical Engineering
-
8/6/2019 Reporte de Inversor PIC16f87X
2/42
Table of Contents
Executive Summary3
Statement of Need...3
Project Description..4
Inverter......5 Power Supply5
Buck Converter.6
Battery charger......8
Battery.....14
Data and Results16
Budget...21
Timeline23
Conclusion.....23
References.....24
Appendix...25
2
-
8/6/2019 Reporte de Inversor PIC16f87X
3/42
Executive Summary
Fuel cells are becoming an increasingly important fuel supply for portable powerapplications. Their environmentally friendly emissions and high efficiency make them agood solution for renewable energy source vehicles. The project involves converting an
electric go-kart into a fuel cell electric vehicle. The project research and design issponsored by the University of Connecticut, Professors James M. Fenton, and Martin D.Fox.
The power source provided was a 12-volt, 42-amp fuel cell, which was not powerfulenough to directly drive a 36-volt, 38-amp motor. The fuel cell was utilized as a powersupply for a battery charger to dynamically charge the batteries during the operation ofthe kart. The design of this charger was the crux of the design effort this semester. The best and most feasible way to charge the three 12-volt batteries was to isolate eachbattery while sensing current, voltage, and temperature. The approach proposed applied amicro-controller to create a pulse width modulation (PWM) battery charger, due to its
ability to change parameters quickly and efficiently.
Statement of Need
Designing a fuel cell powered go-kart will help explore the potential for alternative fuelvehicle transportation. According to the Sustainable Energy Coalition, a coalition that promotes renewable energy technologies, a 10% penetration for fuel cells into theautomobile market can reduce petroleum imports by 800,000 barrels per day, or roughly10% of the U.S. daily usage. Fossil fuels also have many emissions that are harmful tothe environment. Fuel cells are good, clean alternatives to conventional fossil fuel powerplants. They can run on pure hydrogen gas or any other gaseous fuel from natural gas tolandfill waste methane gas. Fuel cells also operate with high efficiencies, and usinghydrogen gas, produce no harmful emissions. The go-kart project takes an electric go-kartand attaches a fuel cell with its subsystems to power the kart in some way. The projectwill be considered a success if the kart can be operated for a significantly longer timethan running the kart off the battery pack alone.
The bulk of the problem lies in creating an intelligent battery charger that can handle theinput and output voltage and current levels. Todays battery chargers have manylimitations. Many chargers run one charging algorithm tailored for one specific type of battery and do not monitor the battery for optimal charging conditions. Smart batterychargers are mostly micro-controller based and monitor battery conditions whilecharging, but are not portable. Thus, a portable, smart battery charger that can monitormultiple batteries at a time and charge only the most discharged battery is necessary.Many applications for portable battery chargers are present today, and having the abilityto charge the batteries during discharge will extend the life cycle of the go-kartsbatteries.
3
-
8/6/2019 Reporte de Inversor PIC16f87X
4/42
Project limitations are regulated by budget, time, and weight. The fuel cell is veryexpensive. Thus, the project must be completed without spending in excess of the allottedbudget. The kart must also be completed by May 2002. The final limitation is the weight.The kart is to be fitted with all of the original kart components as well as the fuel cell,hydrogen tank, water tank, some type of chiller, and a full-grown person rather than a
child. It can potentially be a difficult task for the motor to push all of the extra weight.The focus of the electrical engineering group will be limited to the fuel cell-batteryinterface while the mechanical engineers will concentrate on the fuel cell and itsoperation.
Project Description
The solution to the problem given to the Fuel Cell Go-Kart Electrical Engineering Teamby the University of Connecticut has focused on implementing the fuel cell to charge thebattery while under continued load. The blocks that will be involved include theDC-ACInverter, the 48VDC Power Supply, the Buck Converter, the Battery Charger, and
the Battery. Each section will be discussed using block diagrams and schematics in orderto understand the full scope of the problem.
Figure 1 Project Block Diagram
4
-
8/6/2019 Reporte de Inversor PIC16f87X
5/42
Figure 2 Battery Charger Overall Circuit Diagram
Inverter
The inverter is made by SUPEREX and has a rated input of 10-15VDC and an output of115VAC 1000W continuous. The inverter simply converts DC to AC in order to drive thepower supply. A commercially available inverter was chosen due to its low cost, highefficiency, and convenient packaging. Efficiency calculations are shown in the Data andResults section of the report.
Power Supply
The power supply takes an AC input and produces a DC output. The circuit is rated for48VDC, 10 Amps and 500 Watts. It provides a DC input for the charger and buckconverter circuits. It always produces a constant current and voltage. Since it is
unregulated, the voltage may increase or decrease inversely proportional to the current.The power supply is approximately 80% efficient per the manufacturer at a full load of48VDC and 10 Amps.
5
-
8/6/2019 Reporte de Inversor PIC16f87X
6/42
Buck Converter
One of the most important parameters in charging batteries is the control of thepower source. Whether a current or voltage-based charging is used, control of the powersource is imperative to prolonged battery life. The power source for this design was a
48VDC power supply. A buck converter was chosen because of its simplicity, efficiency,and low heat dissipation. A simplified diagram of the converter circuit is shown below.
Figure 3 Buck Converter Circuit
The Pulse-width modulation (PWM) controlled buck DC/DC converter consists of aninput voltage source, transistor driver, high power P-channel HEXFET, inductor, andan output capacitor used for filtering. The buck converter is a dc-to-dc step downconverter in which PWM is applied to the Power MOSFET Switch. When the output ofthe PWM is high, current passes through the inductor to the battery. The inductorenergizes and the capacitor charges. When the PWM is low, the capacitor dischargesthrough the diode as the inductor voltage reverses to resist the change in current. Thefilter at the output of the converter is used for eliminating harmonics and noise.
The varying duty cycle of the PWM controls the on and off times of the MOSFET. As theduty cycle changes, the output voltage from the buck converter changes per the equations
below.
The micro-controller PWM output is shown in Figure 2.
6
-
8/6/2019 Reporte de Inversor PIC16f87X
7/42
ton
T
Figure 4 PWM Output
The relationship between PWM output and the output voltage is:
)(
)(
Dsati
DOt
VVV
VV
T
On
+-
+=
Where: = On time of PWMon
t
T = PWM period
V = Input voltagei
V = Output voltageO
V =Saturation voltage of transistorSAT
= Diode forward-bias voltage dropD
V
DV
ForV , V , V , and T constant, increasing or decreasing will increase or decrease
the output voltage Vo. Therefore, for different battery technologies requiring different
charging voltage, Vo may be varied by varying .
D i SAT ont
ont
The buck converter inductor value is determined by:
L =( )
PK
OnOSATi
I
tVVV --
Where = 2 and is Maximum output current.PK
IOMAX
IOMAX
I
7
-
8/6/2019 Reporte de Inversor PIC16f87X
8/42
Below is a graph of the efficiency of the buck converter and charger circuit. As batteryvoltage increases towards 43.5VDC, the efficiency increases from a minimum of 78% toa maximum of 93%. The circuit is more efficient when the P-channel MOSFET is onsince that is the normal operating condition.
Charger Efficiency versus Charger Output Voltage
76
78
80
82
84
86
88
90
92
94
36 37 38 39 40 41 42 43 44
Charger Output Voltage (Volts)
C
hargerEfficiency(%)
Figure 5 Buck Converter/Charger Efficiency
Battery Charger
An intelligent battery charger is necessary for this project to maximize the life of the batteries. What makes a charger intelligent is its ability to monitor multiple batterycharacteristics and adjust the parameters accordingly, thus providing efficient safecharging. Unlike intelligent chargers, dumb chargers require the battery to bedisconnected from its application and they do not sense current, voltage, and temperature.These parameters are required for safe operation and charging.
The brain of the battery charger is the PIC16F874 micro-controller. This micro-controller
was chosen for its versatility. It has eight, ten bit A/D inputs, which are used for accuratevoltage and current sensing. It also has two capture compare modules, which allow for anaccurate and easy decoding of an Analog Devices TMP04 temperature sensor and an easygeneration of an adjustable pulse width modulation pulse train. Currently, few of theinputs are being used, but there are more available for future expansion and refinement ofthe project.
8
-
8/6/2019 Reporte de Inversor PIC16f87X
9/42
Since the battery voltage is high when compared to the limits of the micro-controller, itmust be scaled down to allow for sensing. The voltage is sent through a voltage divider,which brings a maximum of 20 volts to the 5-volt micro-controller threshold. The currentis sensed through a current shunt resistor, the voltage drop is read across this resister.This voltage is very small and will only translate to about 20 steps of accuracy within the
micro-controller. Since current is a very important parameter, this is not accurate enough.To solve this problem, the voltage is amplified utilizing a non-inverting amplifier circuit.This voltage now has a 10A to 5V correlation. When input into the A/D of the PIC, thisresults in about a 10mA per bit resolution. The PIC can then display the readings on aliquid crystal display (LCD) so the user can check the level of charge and the chargingcurrent.
The basic functions performed by the micro-controller are generating a pulse widthmodulation (PWM) pulse train and parameter sensing. The functionality of a PWMintelligent charger is to charge the battery while the PWM output is a 1 and sense thevoltage, current, and temperature on the 0. This is accomplished by using one of the
hardware PWM modules of the PIC. The reason a hardware PWM was chosen was foraccuracy. The PWM has up to a 10-bit resolution and is not affected by interrupts or thetiming of the other subroutines in the program. Writing to the PR2 register periodcontrols the PWM frequency. The frequency also depends on the clock frequency and thetimer 2 pre-scale value, but they are not addressable once the program has been built. Thebattery charger runs at a constant frequency of 15kHz and is not varied in operation. ThePWM duty cycle is what gets changed to vary the charging voltage and maintain aconstant current. Like the frequency, the duty cycle also depends on the clock frequencyand the timer 2 pre-scale value, but is also dependant on the CCPR1L register for the 8most significant bits and the CCP1CON bits 5 and 4 for the 2 least significant bits. This10-bit value is varied depending on the current sensing input to maintain a constantcurrent charging.
9
-
8/6/2019 Reporte de Inversor PIC16f87X
10/42
Figure 6 Battery Charger Flowchart
The beginning cycle of the charger initializes all of the necessary inputs and outputs ofthe PIC (figure 1). It also sets up the PWM frequency and sets all initial variable values. Next, the initial PWM duty cycle is calculated. In the PWMON subroutine, an initialreading of the battery voltage is taken. This enables the PIC to calculate the starting duty
cycle so the output voltage is slightly higher than the voltage of the battery (figure 2).Charging can now begin normally and the battery charger becomes fully autonomous.
10
-
8/6/2019 Reporte de Inversor PIC16f87X
11/42
Figure 7 PWMON Subroutine Flowchart
Next, the TestMode subroutine is entered (figure 3). Here the PIC reads all of its inputsand determines what to do to control the charging. The first parameter sensed on the lowPWM cycle was the voltage. This is controlled by the duty cycle and is compared to 43.5volts. If the voltage is under the threshold, the charging continues and the programreturns to the main loop and the state variable is set to test current next. If the value isover 43.5, the charging is complete and the duty cycle is set to 0% and charging ceases.
The battery temperature is also calculated. This parameter has no effect on the charging
scheme. Tests run on charging the battery pack has shown that the temperature does notrise uncontrollably and would not cause damage to the batteries. Also the air temperaturewould cause for erroneous charging due to the fact that the sensor would not only bereading the temperature of the battery, but the ambient temperature. Ideally, thetemperature of the cell would be the internal battery temperature. Only then would thetemperature be a valid charging parameter. The temperature sensor is a pulse train inputto a capture compare module. Once the sensor detects a temperature reading is available,
11
-
8/6/2019 Reporte de Inversor PIC16f87X
12/42
the program interrupts and the input times are captured. After sensing the temperature theprogram again sets the state variable to test the charging current.
After temperature or voltage has been calculated, the next subroutine is to check thecurrent. The charging current is limited to between 4 and 4.5 amps. Reading an A/D input
and performing some scaling calculations provided an accurate reading of the current towithin 0.1A. The reading is firs checked for the low current value. The 10-bit A/D inputis subtracted from a value that corresponds to 4A. If this action does not cause a borrow,the current is lower than 4A and the program moves to an increase duty cycle subroutine.Here, 2 is added to the previous 10-bit value and the program returns to the main loop tosense other parameters. If the current is above 4A, the input value will get subtractedfrom a value that corresponds to 4.5A. If a borrow occurs here, the current is too high andthe duty cycle is decreased by subtracting 2 from the previous 10-bit value and returns tothe main loop. If the current is now determined to be below 4.5A, the duty cycle remainsunchanged and the program returns to the main loop. The reason for checking currenttwice is to maximize the controllability of the current so it always remains within the
0.5A range. Finally, the values sensed are all displayed simultaneously in the DisplayAllsubroutine.
12
-
8/6/2019 Reporte de Inversor PIC16f87X
13/42
Figure 8 TestMode Subroutine Flowchart
13
-
8/6/2019 Reporte de Inversor PIC16f87X
14/42
It was decided that the battery charger should require little user/charger interaction. The battery charger is completely stand-alone. Once activated, it will not need any userinputs. The LCD is there to display the parameters to the driver so they can view thecondition of the batteries. The charging and discharging will be completely controlled bythe micro-controller in order to provide the most efficient and safe battery charging
available. The code for the intelligent battery charger is located in the Appendix.
Battery
The go-kart utilizes three PC12330 Sealed Absorbed Glass Mat (AGM) Deep CycleInterstate Batteries; each rated at 12V and 33-Ampere Hours output. In AGM batteries,the acid is absorbed between the plates and immobilized by a very fine fiberglass mat,keeping the acid available to the plates. A fast reaction between the acid and platematerial results from this construction. Coupled with low internal electrical resistance,the battery can deliver and absorb higher rates of current than other sealed batteriesduring discharging and charging. In addition, AGM batteries can utilize the same
chargers used for wet cell batteries. The battery is also valve regulated, meaning there isno gassing, no electrolyte spillage, no corrosion, and no special handling precautions.This makes the battery the best choice for an environment consisting of constant stressand motion, as in a go-kart.
The absorbed glass mat is porous. The oxygen gas generated at the positive plate willdiffuse to the negative plate, contact the lead, and form lead oxide. The lead oxide reactswith the sulfuric acid to form lead sulfate. If the voltage used during charging isexcessive, considered overcharging, oxygen gas develops at a rate faster than what theseparator can diffuse. Thus, the battery will act like a regular vented battery, releasinghydrogen and using water, drying out a cell and causing it to fail.
Undercharging occurs when a battery is discharged and less than the 107% - 115% of theremoved amp-hours is not supplied to the battery during recharge. As a result, leadsulfate stays on the plates, eventually hardening. The lead sulfate may not be converted back to lead oxide as it should, the battery will suffer permanent capacity loss. Tooptimize life, overcharging and undercharging must be avoided.
The large amount of discharging and charging cycles of the batteries dictates that anytype of trickle or float charging is undesirable. The trickle charges are used to maintain abattery fully charged without a state of discharge. The best method for charging,according to the battery manufacturer, is to charge the battery using cycling applications.The maximum current of the charger should be less than 20% of amp-hour capacity ofthe battery. The 20% value of the amp-hour capacity is 6.6Amps. The battery is then
charged to 14.40 to 14.70 Volts at approximately 68F (20C) under load. The voltagereaches 14.40 to 14.70 Volts until the current drops to approximately 3.3 Amps. At thispoint, the battery is fully charged and will be disconnected from the charger. Voltage,current, and temperature readings would be sent to the micro-controller. The micro-controller uses the feedback to stop charging the battery pack. The charge is considered aconstant current charge in that the current is limited to a certain value while the voltage
14
-
8/6/2019 Reporte de Inversor PIC16f87X
15/42
changes until the battery is fully charged. The starting charging voltage is chosen basedupon a value, which leaves a proper safety margin to allow proper operation of the go-kart. In other words, it is undesirable for the batteries to go dead before the chargingbegins.
Below is a diagram typical of a constant current charge for a valve-regulated battery. Thecurrent value shown is a generic value. The PC12330 deep cycle battery limits the chargeto a maximum of 6.6 Amps.
Figure 9 Constant Current Charging Curve
Depending upon the response of the battery to charging and continued cycling, voltagevalues may be adjusted within the limits above to obtain the best charging rates for thebattery. Although the extended range of the go-kart is an important goal, the integrity ofthe battery and the safety of the passenger must not be compromised.
Due to the above and the application, the constant current charging scheme was chosen.
This will allow the charger to control the current during the charging cycle and prevent adifference in potential between the battery and the charger from causing current to riseout of control. It also keeps the difference in potential from allowing current to flow backinto the charger circuit and damaging the output diode.
The current limit for charging was based upon the limits of the components, circuit board,and the fuel cell. The resistors in the circuit were the limiting factor in keeping thecurrent between 4 to 4.5 amps. The power dissipation of the majority of the resistors in
15
-
8/6/2019 Reporte de Inversor PIC16f87X
16/42
the circuit was a watt. Thus, to keep the safety margin large, we ensured that the product of the voltage and current was well within the limits. The circuit board waslimiting as a result of the size of the current runs. As the circuit runs became larger andthe board area increased, the price of the board increased dramatically. Thus, we wereable to limit the cost and size of the board. Lastly, the fuel cell limits dictated that we
should keep the current low. The combination of the battery and fuel cell limits made 4 to4.5 amps an appropriate choice.
Data and Results
The best measure of how well the project worked is to follow the level of efficiencythroughout the system. The efficiency was measured between each module and combinedto obtain the overall efficiency. The results were then compared with the battery chargerdelivered with the go-kart. The charging test with the intelligent battery charger wasperformed and the results are posted below. The battery pack was successfully chargedusing the intelligent battery charger. The fuel cell was not used due to its low power
output. The power would have been insufficient for our needs. The fuel cell will beexplained in the Discussion section.
Inverter
An experiment was performed in which the battery was charged using the inverter andthe battery charger that was delivered with the go-kart. The efficiency of the inverter iscalculated below from the experiment:
DC Power into Inverter:
P = IV = (12V)(14.3A) = 171.6W
AC Power out of Inverter:
P = VRMSIRMS = (105.1VAC)(1.5) = 157.65W
VRMS = VP / 2 = 105.1VAC
IRMS = IP / 2 = 1.5A
Efficiency:
Inverter: (100)*157.65W/171.6W = 91.9%
The AC Power was calculated using the RMS value or root mean square value ofcurrent and voltage. Assuming a power factor of unity and the voltage and current inphase, then P = (VRMS)(IRMS)(pf) = VRMSIRMS. The efficiencies were measured bydividing the output power by the input power. The charging current and voltage of thebattery pack is shown below. These numbers were used to calculate the power. Thechanges in current and voltage are due to the algorithm of the battery charger and thestate of charge of the battery.
16
-
8/6/2019 Reporte de Inversor PIC16f87X
17/42
Battery Charging Current vs. Time Using Inverter
0
0.5
1
1.5
2
2.5
3
3.5
0 50 100 150 200 250 300 350 400
Time (Minutes)
Figure 10 Battery Charging Current vs. Time
In the charging current plot, it can be observed that the current initially ramps up from 2.7to 3.0 Amps and then slowly decreases over time, especially once the time exceeds 300minutes or 5 hours.
Total Battery Charge vs. Time using Inverter
0
5
10
15
20
25
30
35
40
45
50
0 50 100 150 200 250 300 350 400
Time (Minutes)
17
-
8/6/2019 Reporte de Inversor PIC16f87X
18/42
Figure 11 - Total Battery Voltage vs. Time
The voltage increased linearly for the first 5 hours. At the five-hour point when currentstarted to drop more rapidly, the voltage increased more quickly and then stabilized atabout 43.5 Volts for the pack and 14.3 Volts for each individual battery. Once the current
flow was secured, the battery voltage dropped to a steady-state open circuit voltage ofabout 39.9 Volts for the pack and 13.38 Volts for each individual battery.
Power Supply
The power supply is rated for an efficiency of 80% at 48VDC and 10 Amps according tothe manufacturer data sheet. Below is the calculated efficiency of the power supply.
Power Supply Current vs. Efficiency
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
50 51 52 53 54 55 56 57
Efficiency (%)
Figure 12 Power Supply Efficiency
The disparity between the data sheet and the calculated efficiency results from the limitedcurrent setting. The changing efficiency is due to the changing voltage of the batteryinput as it is depleted. A higher efficiency would be observed if the current was closer to
10 Amps.
Intelligent Battery Charger
The intelligent battery charger includes the buck converter, microcontroller, andvoltage/current sensing circuits. The efficiency of the battery charger is shown below.
18
-
8/6/2019 Reporte de Inversor PIC16f87X
19/42
Charger Efficiency versus Charger Output Voltage
76
78
80
82
84
86
88
90
92
94
36 37 38 39 40 41 42 43 44
Charger Output Voltage (Volts)
Figure 13 Charger Efficiency
The efficiency of the charger increased as the voltage became closer to the designed finalfull battery charge. Below is the overall efficiency of the entire circuit.
Overall Efficiency versus Charger Output Voltage
36
37
38
39
40
41
42
43
44
0 10 20 30 40 50 6
Charger Voltage (Volts)
0
Figure 14 System Efficiency
19
-
8/6/2019 Reporte de Inversor PIC16f87X
20/42
The discrepancy at 41VDC is due to the switching of the battery source. The inverterwould not operate at such a low input voltage near 11VDC. Overall, the efficiency waslow. The main problem is limiting the power supply to such a low current when it wasdesigned for a higher efficiency at a higher current.
The overall goal of charging the battery pack was accomplished and the result is shownin Figure 15.
Battery Voltage vs. Time
36
37
38
39
40
41
42
43
44
0 50 100 150 200 250 300 350
Time (Minutes)
Figure 15 Battery Charge Results
Discussion
The major problem encountered during the project was the fact that the fuel cell could notproduce a voltage high enough to supply the needs of our circuit. At the required 28 ampsfor our inverter input, the voltage was less than 5 volts. In order to compensate, we used a70 amp-hour 12VDC battery donated by Douglas Batteries Inc. in order to mimic thehigh current needed by the project.
20
-
8/6/2019 Reporte de Inversor PIC16f87X
21/42
Voltage vs. Current
0
5
10
15
20
0 5 10 15 20
Current (A)
Voltage
(V)
Figure 16 Fuel Cell Voltage versus Current
Cell Power
0
20
40
60
80
100
120
0 5 10 15 20
Current (A)
Power(W)
Figure 17 Fuel Cell Power versus Current
The low voltage and current developed by the fuel cell was not sufficient to drive thebattery charging circuit as shown above.
The power supply was rated at a higher efficiency at a higher output current. As a resultof the limited current used, the overall efficiency of the project suffered. Improvements inthe power supply can possibly be made if a bridge rectifier was used in place of thepower supply bought commercially.
Budget
The following is an approximation of the cost of the device. The budget is based upon theactual cost of purchased items for the end product. The following is an estimate and maydeviate from stated values if additional parts are necessary.
Component Quantity Price (each) TotalExpress-PCB Circuit Board 1 $73.00 $73.00
21
-
8/6/2019 Reporte de Inversor PIC16f87X
22/42
PIC Micro-controller 1 $4.00 $4.00TMP04 Temperature Detector 1 $3.25 $3.25IRF9540 P-Channel MOSFET 1 $1.68 $1.68LF353N Operational Amplifier 1 $0.69 $0.69DSEI8-6A FRED Diode 1 $1.41 $1.41M9908 Inductor 1 $4.73 $4.73DN1185-140V Diode 1 $3.44 $3.444MHz Crystal 1 $0.88 $0.88LCD Screen 1 $18.00 $18.0048V/10A Power Supply 1 $147.85 $147.85Digital Multi-meter 2 $17.95 $35.90Voltage Inverter 1 $140.00 $140.00Current Shunt Resistor 1 $4.38 $4.3812VDC, 0.12A Fan 1 $12.00 $12.00Project Enclosure Boxes 2 $15.00 $30.00Various Components 25 $0.05 $1.25
Total $482.46
Note: Budget for project was not limited and includes amounts for final design.
Table 1 Budget
22
-
8/6/2019 Reporte de Inversor PIC16f87X
23/42
Timeline
The project timeline shown below has been followed since the beginning of the
project. All steps have been completed.
Figure 18 Project Timeline
Conclusion
The intelligent battery charger has revolutionized the industry. Batteries are lastinglonger, charging is safer, and chargers are becoming more versatile. The intelligentbattery charger can be specifically tailored to a situation where a conventional chargercannot. In the case of the fuel cell powered go-kart, a conventional charger can onlycharge the battery pack when the kart is not being used. Even commercially available
intelligent chargers cannot be used while the kart is in operation. Since most intelligentchargers are micro-controller based, the charger was coded in a way that allows forcharging under the circumstances required by the fuel cell and the kart during kartoperation. A product of this nature also has applications outside the fuel cell powered go-kart industry and can prove to be a valuable product for electric vehicle applications aswell as other portable electric power applications.
23
-
8/6/2019 Reporte de Inversor PIC16f87X
24/42
References
Renewable Energy Resources http://www.sustainableenergy.org
Micro-Controller http://www.diversifiedengineering.net and
http://www.microchip.com
Motor http://www.kangoev.com
Battery http://www.interstatebatteries.com
MAXIM http://www.maxim-ic.com
National Instruments: http://www.zone.ni.com
ETID (Texas A&M): http://www.entcweb.tamu.edu
ExpressPCB http://www.expresspcb.com
24
-
8/6/2019 Reporte de Inversor PIC16f87X
25/42
Appendix
Below is the computer code for the intelligent battery charger.
;******************************************************************************;******************************************************************************
;************************* Battery Charger **********************************;******************************************************************************;********************* Fuel Cell Design Group *******************************;********** Peter Prizio, Anhtuan Truong, Brian Stevens *********************;******************************************************************************;******************************************************************************;***************** May 4, 2002 - Final Version ******************************;******************************************************************************;* *;* Program Description: *;* This program utilizes a current controlled duty cycle to charge a 36V *;* battery pack from a 12V fuel cell. The charging algorithm mimics constant *;* current charging by limiting the charging current between 4.3 and 4.5 *;* Amps. This is accomplished by controlling the charging voltage. *;* *;* This program reads the temperature, voltage and current of the batteries. *;* Once the desired voltage has been achieved, the charging stops. *
;* *;******************************************************************************;******************************************************************************;******************************************************************************;* Program hierarchy **********************************************************;* *;* Mainline *;* Initial *;* PWMON *;* *;* MainLoop *;* TestMode *;* Current *;* Voltage *;* Temperature *;* DisplayAll *;* goto MainLoop *
;* *;* IntService *;* Capture *;* *;******************************************************************************
list P=PIC16F874, F=INHX8M, C=160, N=77, ST=OFF, MM=OFF, R=DEC, X=OFF#include P16F874.inc__config(_CP_OFF & _PWRTE_ON & _XT_OSC & _WDT_OFF & _BODEN_OFF)errorlevel -302
;******************************************************************************;******* Equates **************************************************************;******************************************************************************
Bank0RAM equ H'20' ;Start of Bank 0 RAM areaMaxCount equ 50 ;Number of loops in half a second
;******************************************************************************;******* Variables ************************************************************;******************************************************************************
cblock Bank0RAMW_TEMP ;Temporary storage for W during interruptsSTATUS_TEMP ;Temporary storage for STATUS during interruptsTEMP1 ;Temporary variable for BarChart subroutineTEMP3 ;temp stor for displayTEMP4 ;temp store for displayINT_FLAG ;keep track of alternate interrupts
25
-
8/6/2019 Reporte de Inversor PIC16f87X
26/42
LCD_TEMP ;keep track of LCD vectorCHARCODE ;address location for RPG output
TEMPSTG:10 ;temperature stringCURRSTG:10 ;Current StringVOLTSTG:10 ;Voltage String
T1BEGINH ;temp for begin of T1 high
T1BEGINL ;temp for begin of T1 highT1ENDH ;temp for end of T1 highT1ENDL ;temp for end of T1 lowT1HIGH ;Temp time1 high byteT1LOW ;Temp time1 low byteT2HIGH ;Temp time2 high byteT2LOW ;Temp time2 low byteT2ENDH ;temp stor for t2 high endT2ENDL ; temp store for t2 low endCAP_FLAG ;Capture FlagADCHARGETIME ;var to allow ad to charge upCHANGECHANGE1PWMFLGSTATEVARVOLTLOWVOLTHIGH
SETDUTYHSETDUTYLOLDDUTYLOLDDUTYHDutyFlagWASTE1WASTE2WASTEDONEendc
#include math.inc ;include math include file
;======= #DEFINE
#define rdAN0 b'11000001',ADCON0 ;set internal ad to read AN0#define rdAN1 b'01001001',ADCON0 ;set internal ad to read AN1
#define startAD ADCON0,2 ;start internal ad#define offAD ADCON0,0 ;turn ad off
;******************************************************************************;****** Macro definitions *****************************************************;******************************************************************************
MOVLF macro literal,destmovlw literalmovwf destendm
MOVFF macro source,destmovf source,Wmovwf destendm
BANK1 macrobsf STATUS,RP0endm
BANK0 macrobcf STATUS,RP0endm
;******************************************************************************;****** Program Code **********************************************************;******************************************************************************
26
-
8/6/2019 Reporte de Inversor PIC16f87X
27/42
-
8/6/2019 Reporte de Inversor PIC16f87X
28/42
retlw H'C0'dt " For Correct Charging Current Level "retlw 0
;******************************************************************************;****** End of Tables *********************************************************
;******************************************************************************
;******************************************************************************;****** Mainline program ******************************************************;******************************************************************************Mainline
call Initial ;Initialize everythingcall PWMON
MainLoopcall TestModecall DisplayAllgoto MainLoop
;***********************************************************************************; 32/16 Bit Unsigned Fixed Point Divide 32/16 -> 32.16
; Input: 32 bit unsigned fixed point dividend in AARGB0,AARGB1,AARGB2,AARGB3; 16 bit unsigned fixed point divisor in BARGB0,BARGB1; Use: CALL FXD3216U; Output: 32 bit unsigned fixed point quotient in AARGB0,AARGB1,AARGB2,AARGB3; 16 bit unsigned fixed point remainder in REMB0,REMB1; Result: AARG, REM 32; Input: 16 bit unsigned fixed point multiplicand in AARGB0,AARGB1; 16 bit unsigned fixed point multiplier in BARGB0,BARGB1
; Use: CALL FXM1616U; Output: 32 bit unsigned fixed point product in AARGB0,AARGB1,AARGB2,AARGB3; Result: AARG
-
8/6/2019 Reporte de Inversor PIC16f87X
29/42
MOVLF B'10000010',ADCON1 ;Select PORTA pins for ADC or digital I/O;an4-an0 on
MOVLF B'00001011',TRISA ;Set I/O for PORTAMOVLF B'00000000',TRISB ;Set I/O for PORTB; 1-4=outMOVLF B'11010011',TRISC ;Set I/O for PORTC-bit 1 makes CCP2 an inputclrf TRISD ;Set I/O for PORTDMOVLF B'00000100',TRISE ;Set I/O for PORTE
MOVLF B'11000001',OPTION_REG ; Initialize option register for 32:1 ;prescaleMOVLF 66,PR2
BANK0 ;Set register access back to bank 0
clrf CCP1CON
clrf TMR2 ;initialize timer 2MOVLF B'00001100',CCP1CON ;Set CCP1 for PWMMOVLF B'00000100',T2CON ;Initialize Timer 2 for a 1:1 prescaleclrf TMR0 ;initialize timer 0
clrf TMR1L ;initialize to zero low and high bytes of timer 1clrf TMR1H ;clrf T1CON ;to turn on set bit 0 to 1 (TMR1ON bit)bsf T1CON,TMR1ON ;start timer1
MOVLF b'00000101',CCP2CON ;init capture to rising
MOVLF B'00000000',INT_FLAG ;initialize interrupt flagMOVLF H'30',CHARCODE ;initialize CHARCODE
MOVLF H'C8',TEMPSTG ;POSITION OF beginning of temp strMOVLF B'00101110',TEMPSTG+4 ; ASCII code for a decimal pointMOVLF H'DF',TEMPSTG+6 ;ASCII code for the degree symbolMOVLF H'46',TEMPSTG+7 ; ASCII code for FMOVLF A' ',TEMPSTG+8;put space here initiallyMOVLF H'00',TEMPSTG+9 ; serve as the end-of-string designator.
MOVLF H'88',CURRSTG ;POSITION OF beginning of temp strMOVLF B'00101110',CURRSTG+4 ; ASCII code for a decimal point
MOVLF H'DF',CURRSTG+6 ;ASCII code for the degree symbolMOVLF H'46',CURRSTG+7 ; ASCII code for FMOVLF A' ',CURRSTG+8;put space here initiallyMOVLF H'00',CURRSTG+9 ; serve as the end-of-string designator.
MOVLF H'80',VOLTSTG ;POSITION OF beginning of temp strMOVLF B'00101110',VOLTSTG+4 ; ASCII code for a decimal pointMOVLF H'DF',VOLTSTG+6 ;ASCII code for the degree symbolMOVLF H'46',VOLTSTG+7 ; ASCII code for FMOVLF A' ',VOLTSTG+8;put space here initiallyMOVLF H'00',VOLTSTG+9 ; serve as the end-of-string designator.
MOVLF B'00000001',STATEVAR ;set variable to measure voltageclrf PWMFLGclrf AARGB0clrf AARGB1clrf AARGB2
clrf AARGB3clrf CCPR2L ;init CCPR2 registersclrf CCPR2Hclrf T1LOWclrf T1HIGHclrf T2HIGHclrf T2LOWclrf CAP_FLAG ;initialize capture flagclrf PORTD ;Turn off LEDs
; clrf PORTBclrf PORTEclrf VOLTLOW
29
-
8/6/2019 Reporte de Inversor PIC16f87X
30/42
clrf VOLTHIGHclrf SETDUTYHclrf SETDUTYLclrf OLDDUTYHclrf OLDDUTYLMOVLF 1,DutyFlagclrf INTCON ;initialize interrupt control registerbsf INTCON,T0IE ;enable timer 0 [bit5]
bsf INTCON,PEIE ;enable peripheral interrupts for capturebcf INTCON,INTE ;disable port b interrupts for RPGbsf ADCON0,0 ;turn on a/d modulecall InitLCD ;set up lcd for Nibble modebcf INTCON,GIE ;global interrupt disable [bit7]
return
;******************************************************************************
TestModebtfsc PORTC,6 ;check pwm if low, continue testing valuesgoto TestModenopbtfsc STATEVAR,0goto VoltageTestnop
btfsc STATEVAR,1goto CurrentTestnopbtfsc STATEVAR,2goto Temperature
btfsc STATEVAR,3goto CurrentTestAgainnop
Temperature
bcf STATEVAR,2 ;Set state to test current againbsf STATEVAR,3bsf INTCON,GIE ;enable interupts
TEMPWAITbtfss CAP_FLAG,2 ;stay in main loop
goto TEMPWAITcall CalcTemp ;until temp available
bcf INTCON,GIE ;disable interuptsreturn ;go back to normal loop until temp avail.
;;;;;;;;;;Calculation;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AARGB0, AARGB1,... where the B0 byte represents the;most-significant byte.; You need to take the 16-bit result from;AARGB2 and AAARGB3, not from AARGB0 and AARGB1.;Temperature = 4550 - [7200xT1/T2];;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CalcTemp
nopMOVFF T1HIGH,AARGB0 ;move to most sign bytes for mult.MOVFF T1LOW,AARGB1
MOVLF H'1C',BARGB0 ;move hex equiv of D'7200'MOVLF H'20',BARGB1 ;H'1C20' to BARG regs.CALL FXM1616U ;do multiply,result in AARGB0,1,2,3
MOVFF T2HIGH,BARGB0 ;BARG is only 16 bitsMOVFF T2LOW,BARGB1 ;0 is most sign.CALL FXD3216U ;do division
;****** 16 bit literal subtract **********************************************movf AARGB3,W ;D'4550'= H'11C6' now need 16 bit subtract.
30
-
8/6/2019 Reporte de Inversor PIC16f87X
31/42
sublw H'C6' ;subtract lit-w, result in wmovwf AARGB3 ;put result in AARGB3
movf AARGB2,W ;put high byte into w
btfss STATUS,C ;if C=0->Carry from low byteaddlw 1 ;if C set add 1 back to high byte
;if carry bit=0 (not set) reduce high byte by 1
;if carry bit=0 (not set) reduce high byte by 1 to 10sublw H'11' ;H'11'-w(+1), result in w
movwf AARGB2 ;put result back in AARGB2
;******************************************************************************
;;;;;;;;;;Binary to ASCII Conversion;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Peatman 154;After you have completed the calculation; of the temperature, you need to take the two-byte binary result;and break it into a three-ASCII-character result.;If you divide the two-byte binary value by ten, the remainder;will be the units digit value. Add H'30' to this to convert;it to the ASCII code for the digit.;Dividing the quotient by ten will yield the tens digit in the
;new remainder and the hundreds digit in the new quotient.;;Divide; Output: 32 bit unsigned fixed point quotient in; AARGB0,AARGB1,AARGB2,AARGB3; 16 bit unsigned fixed point remainder in REMB0,REMB1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF 10,BARGB1 ;divide result by 10MOVLF 0,BARGB0 ;put 0 into BARGB0CALL FXD3216U ;remainder in BARG is unitsmovlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,TEMPSTG+5 ;put in tenths of a degree slot
;divide again by 10CALL FXD3216U ;remainder in REMB1 =degreesmovlw H'30'
addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,TEMPSTG+3 ;put in degrees slot
;divide result by 10 againCALL FXD3216U ;movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,TEMPSTG+2 ;put in 10s degrees slot
;divide result by 10 againCALL FXD3216U ;movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1
movf REMB1,Wsublw H'30'btfsc STATUS,Z
goto Blankgoto Digit
Blank MOVLF H'20',REMB1
Digit MOVFF REMB1,TEMPSTG+1 ;put in 100s degrees slot
MOVLF H'02',REMB1 ;move space into 100's if = 0
MOVLF H'DF',TEMPSTG+6
31
-
8/6/2019 Reporte de Inversor PIC16f87X
32/42
MOVLF A'F',TEMPSTG+7MOVLF A' ',TEMPSTG+8
NewValue
clrf CAP_FLAG ;reset capture flag to get new value
MOVLF b'00000101',CCP2CON ;set for rising edge
bcf PIR2,CCP2IF ;clear CCP2 interrupt flag
MOVLF PIE2,FSR ;PIE2=H'8D'use indir. addr. to set interruptbsf INDF,CCP2IE ;enable [ CCP2IE bit].return
;******************************************************************************;****** InitLCD subroutine ****************************************************;******************************************************************************;; Initialize the FEMA 16x2 character LCD display.; (Initialize PIC ports prior to calling this subroutine.); This subroutine uses a one-byte RAM variable called LCD_TEMP.
InitLCDMOVLF 25,LCD_TEMP ;Wait 1/4 second
InitLCD_1call LoopTime ;Call LoopTime 25 timesdecfsz LCD_TEMP,Fgoto InitLCD_1
;LCD_TEMP now equals zerobcf PORTE,0 ;RS=0 for command
InitLCD_2call LCDinit_Table ;Get next byte, pointed to by LCD_TEMPiorlw H'00' ;Set Z flag if W=0btfsc STATUS,Zgoto InitLCD_donemovwf TEMP4 ;Save copy of bytemovwf TEMP3 ;save another copyswapf TEMP4,F ;position for xfer part1
rlf TEMP4,W ;position for xfer part2
movwf PORTB ;Send upper nibblebsf PORTE,1 ;Drive E highbcf PORTE,1 ;Drive E low so LCD will process inputcall LoopTime ;Wait ten milliseconds
rlf TEMP3,W ;rotate and put into W for Xfermovwf PORTB ;Send lower nibblebsf PORTE,1 ;Drive E highbcf PORTE,1 ;Drive E low so LCD will process inputcall LoopTime ;Wait ten milliseconds
incf LCD_TEMP,F ;Point to next bytegoto InitLCD_2 ; and deal with it
InitLCD_donereturn
;******************************************************************************;****** DisplayC subroutine ***************************************************;******************************************************************************;; This subroutine is called with W containing the offset from CDS to the; beginning of the desired constant display string. It uses a one-byte LCD_TEMP; to the next byte in the display string
DisplayCmovwf LCD_TEMP ;Save pointerbcf PORTE,0 ;Drive RS pin low for cursor positioning code
32
-
8/6/2019 Reporte de Inversor PIC16f87X
33/42
DisplayC_1call DisplayC_Table ;Get byte from string into Wincf LCD_TEMP,F ;Point to the next byteiorlw 0 ;Set Z if end of stringbtfsc STATUS,Z ;if not, then go ongoto DisplayC_donemovwf TEMP4 ;Save copy of bytemovwf TEMP3 ;save another copy
swapf TEMP4,F ;position for xfer part1rlf TEMP4,W ;position for xfer part2movwf PORTB ;Write upper nibblebsf PORTE,1 ;Strobe Ebcf PORTE,1rlf TEMP3,W ;rotate and put into W for Xfer
movwf PORTB ;Write lower nibblebsf PORTE,1 ;Strobe Ebcf PORTE,1call T40 ;Wait 40 usecbsf PORTE,0 ;Drive RS pin high for displayable charactersgoto DisplayC_1
DisplayC_donereturn
;******************************************************************************
;****** DisplayV subroutine ***************************************************;******************************************************************************;; This subroutine is called with W containing the offset from CDS to the; beginning of the desired constant display string.; This extracts the bytes of a display string from ram.; It saves pointer in w to FSR; to the next byte in the display string
DisplayVmovwf FSR ;Save pointerbcf PORTE,0 ;Drive RS pin low for cursor
;positioning codeDisplayV_1
movf INDF,w ;Get byte from string into Wincf FSR,F ;Point to the next byteiorlw 0 ;Set Z if end of string
btfsc STATUS,Z ;if not, then go ongoto DisplayV_donemovwf TEMP4 ;Save copy of bytemovwf TEMP3 ;save another copyswapf TEMP4,F ;position for xfer part1rlf TEMP4,W ;position for xfer part2movwf PORTB ;Write upper nibblebsf PORTE,1 ;Strobe Ebcf PORTE,1rlf TEMP3,W ;rotate and put into W for Xfermovwf PORTB ;Write lower nibblebsf PORTE,1 ;Strobe Ebcf PORTE,1call T40 ;Wait 40 usec
bsf PORTE,0 ;Drive RS pin high for displayable characters
goto DisplayV_1DisplayV_done
return
;******************************************************************************;****** T40 subroutine ********************************************************;******************************************************************************;; Pause for 40 microseconds (assumes 4 MHz crystal).
T40
33
-
8/6/2019 Reporte de Inversor PIC16f87X
34/42
movlw 12movwf TEMP1
T40_1decfsz TEMP1,Fgoto T40_1return
;******************************************************************************
;****** LoopTime subroutine ***************************************************;******************************************************************************;; This subroutine waits for Timer2 to complete its ten millisecond count; sequence.
LoopTimeclrf TMR0bcf INTCON,T0IF
LoopTimeWaitbtfss INTCON,T0IF ;Check whether ten milliseconds are upgoto LoopTimeWait
return
;******************************************************************************;****** IntService interrupt service routine **********************************
;******************************************************************************;; This interrupt service routine fields all interrupts. It first sets aside W; and STATUS. It assumes that direct addressing will not be used in the; mainline code to access Bank 1 addresses (once the Initial subroutine has; been executed and interrupts enabled). It polls each possible interrupt; source to determine whether it needs service.
IntServicenop
; Set aside W and STATUSmovwf W_TEMP ;Copy W to RAMswapf STATUS,W ;Move STATUS to W without affecting Z bitmovwf STATUS_TEMP ;Copy to RAM (with nibbles swapped)
; Execute polling routinePoll
btfsc PIR2,CCP2IF ;Check for interrupt (CCP2IF)goto Capture ;save values and return
Poll2
btfsc INTCON,INTF ;Test PB0/INT flaggoto RPG ;increment or decrement CHARCODE
btfsc INTCON,T0IF ;test for timer 0 overflowbcf INTCON,T0IF ; clear T0 flag
Back
; Restore STATUS and W and return from interruptswapf STATUS_TEMP,W ;Restore STATUS bits (unswapping nibbles)movwf STATUS ; without affecting Z bitswapf W_TEMP,F ;Swap W_TEMPswapf W_TEMP,W ; and swap again into W without affecting Z bitretfie ;Return from mainline code; reenable interrupts
;****** Capture Interrupt Handler *********************************************;;Captures times for a pulse train input into RC1 [CCP2];Returns Delta T1 in T1High and T1Low, Delta T2 in T2LOW and T2HIGH;Capture
bcf PIR2,CCP2IF ;software reset of interrupt flag
btfsc CAP_FLAG,1 ;if second cycle,get T2goto CaptureT2
34
-
8/6/2019 Reporte de Inversor PIC16f87X
35/42
btfss CAP_FLAG,0 ;get time of rising edge of T1goto CaptureT1Begin
btfsc CAP_FLAG,0 ;get time of falling edge of T1goto CaptureT1End
goto Poll ;go back to poll, execute return from int
CaptureT1Begin
MOVFF CCPR2L,T1BEGINL ;save low byteMOVFF CCPR2H,T1BEGINH ;save high byte
MOVLF b'00000100',CCP2CON ;set back to falling
bcf PIR2,CCP2IF ;software reset of interrupt flagbsf CAP_FLAG,0 ;set cap_flag to get falling nextgoto Poll
CaptureT1End
bcf CAP_FLAG,0 ;clear bit 0 of capture flag
MOVFF CCPR2L,T1ENDL ;save low byteMOVFF CCPR2H,T1ENDH ;save high byte
MOVLF b'00000101',CCP2CON ;set for rising edge
bcf PIR2,CCP2IF ;clear CCP2 interrupt flag
bsf CAP_FLAG,1 ;set bit 1 of capture flag so next pass;gets T2
MOVLF b'00000101',CCP2CON ;set back to risinggoto Poll
CaptureT2
MOVFF CCPR2L,T2ENDL ;save low byteMOVFF CCPR2H,T2ENDH ;save high byte
MOVLF b'00000101',CCP2CON ;set for rising edge
bcf CAP_FLAG,1 ;clr bit 1 so we go thru nl sequencebsf CAP_FLAG,2 ;set bit 2 of capture flag so
;temp calc can proceedMOVLF PIE2,FSR ;PIE2=H'8D'use indir. addr. to clear interruptclrf INDF ;enable [ CCP2IE bit].
;i.e. no interrupts while calculatingbcf PIR2,CCP2IF ;clear CCP2 interrupt flag
;******************************************************************************;****** 16 bit subtract; T1END[B] - T1BEGIN[A] ********************************;;result in T1LOW,T1HIGH
movf T1BEGINL,w ;move t1beginh to wsubwf T1ENDL,w ;sub f-w, result in wmovwf T1LOW
movf T1BEGINH,w ;move high byte into wbtfss _C ;check carry bit from prev. subtr.incfsz T1BEGINH,w ;if carry NOT set incrsubwf T1ENDH,wmovwf T1HIGH
;******************************************************************************
35
-
8/6/2019 Reporte de Inversor PIC16f87X
36/42
;***** 16 bit subtract; T2END[B] - T1END[A] ***********************************;;result in T2HIGH,T2LOW
movf T1ENDL,w ;move t2 end to wsubwf T2ENDL,w ;sub f-w, result in wmovwf T2LOW
movf T1ENDH,w ;move high byte into w
btfss _C ; check carry bit from first calc.incfsz T1ENDH,wsubwf T2ENDH,w ;sub high bytes result in wmovwf T2HIGH ;move from w to T2HIGH
;******************************************************************************
goto Back
;******************************************************************************;****** Voltage Test Subroutine ***********************************************;******************************************************************************VoltageTest
bcf STATEVAR,0 ;set state to test current nextbsf STATEVAR,1
FirstVoltageTest
StartMOVLF rdAN1 ;load control for AN1movlw d'15'movwf ADCHARGETIME
Wait4Settledecfsz ADCHARGETIME,F ;delay 30 usec for settlinggoto Wait4Settle
bsf startAD ;start conversion
ADWaitbtfsc ADCON0,GO_DONE ;check GO_DONE bit and continue if cleargoto ADWait
BANK1movf ADRESL,wBANK0movwf AARGB1MOVFF AARGB1,VOLTLOW
MOVFF ADRESH,AARGB0
MOVFF AARGB0,VOLTHIGH
nop
MOVLF H'3',BARGB0MOVLF H'E8',BARGB1CALL FXM1616UnopMOVLF H'7',BARGB0
MOVLF H'91',BARGB1CALL FXD3216Unop
;;;;;;;;;;Binary to ASCII Conversion;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Peatman 154;After you have completed the calculation; of the temperature, you need to take the two-byte binary result;and break it into a three-ASCII-character result.;If you divide the two-byte binary value by ten, the remainder;will be the units digit value. Add H'30' to this to convert;it to the ASCII code for the digit.
36
-
8/6/2019 Reporte de Inversor PIC16f87X
37/42
;Dividing the quotient by ten will yield the tens digit in the;new remainder and the hundreds digit in the new quotient.;;Divide; Output: 32 bit unsigned fixed point quotient in; AARGB0,AARGB1,AARGB2,AARGB3; 16 bit unsigned fixed point remainder in REMB0,REMB1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF 10,BARGB1 ;divide result by 10MOVLF 0,BARGB0 ;put 0 into BARGB0CALL FXD3216U ;remainder in BARG is unitsmovlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,VOLTSTG+5 ;put in tenths of a degree slot
;divide again by 10CALL FXD3216U ;remainder in REMB1 =degreesmovlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,VOLTSTG+3 ;put in degrees slot
;divide result by 10 againCALL FXD3216U ;movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1
MOVFF REMB1,VOLTSTG+2 ;put in 10s degrees slot
;divide result by 10 againCALL FXD3216U ;movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1
movf REMB1,Wsublw H'30'btfsc STATUS,Zgoto Blank1goto Digit1
Blank1 MOVLF H'20',REMB1
Digit1 MOVFF REMB1,VOLTSTG+1 ;put in 100s slot
MOVLF H'02',REMB1 ;move space into 100's if = 0
MOVLF A' ',VOLTSTG+6MOVLF A'V',VOLTSTG+7MOVLF A' ',VOLTSTG+8
;******************************************************************************;****** 16 bit literal subtract ***********************************************
movf VOLTLOW,W
sublw H'7C' ;subtract lit-w, result in w
movf VOLTHIGH,w ;put high byte into w
btfss STATUS,C ;if C=0->Carry from low byteaddlw 1 ;if C set add 1 back to high byte
;if carry bit=0 (not set) reduce high byte by 1;if carry bit=0 (not set) reduce high byte by 1 to 10
sublw H'03' ;H'11'-w(+1), result in w
btfss STATUS,Cgoto TurnChargingOff2
return
37
-
8/6/2019 Reporte de Inversor PIC16f87X
38/42
;******************************************************************************;****** Turn On PWM If First Time Thru Program ********************************;* First check if first time thru and then check the initial voltage of the ***;* battery and set initial duty cycle accordingly *****************************;******************************************************************************
PWMON;******************************************************************************
movlw _Initial1 - CDS ;Put initial messages on the screencall DisplayC
movlw _Initial2 - CDScall DisplayC
bcf CCP1CON,5 ;Clear bits of duty vyvle controlbcf CCP1CON,4
call FirstVoltageTest ;Take Initial voltage values
nopMOVFF VOLTLOW,AARGB1 ;Move variables into arguments forMOVFF VOLTHIGH,AARGB0 ;calculationsnopMOVLF 0,BARGB0 ;divide by frequency of PWMMOVLF 57,BARGB1 ;to get dutycycle value
CALL FXD3216U ;needed by PIC
nopMOVFF AARGB2,AARGB0 ;Move arguments to get properMOVFF AARGB3,AARGB1 ;inputs for 16x16 multiplynopMOVLF 0,BARGB0 ;multiply by frequency of clockMOVLF 4,BARGB1 ;also needed by PICCALL FXM1616U ;see page 60nop
btfsc AARGB3,0 ;set least sig bits forbsf CCP1CON,4 ;duty cycle controlbtfsc AARGB3,1bsf CCP1CON,5
rrf AARGB3,f ;get rid of 2 least sig bits
rrf AARGB3,f
movlw B'00111111' ;Clear two most sig bits to get rid ofandwf AARGB3,f ;of any errors from the rotation and carry
swapf AARGB2,f ;Set up the upper two bits in the 10-bitrlf AARGB2,f ;control.rlf AARGB2,f
movlw B'11000000' ;clear all other bitsandwf AARGB2,fmovf AARGB2,w
iorwf AARGB3,f ;or lower 6 and upper 2 bits together;to get 8 bit value
MOVFF AARGB3,CCPR1L ;move into upper 8 bit duty cycle controlcall WaitSeconds
return
;******************************************************************************;****** Increase Duty Cycle Routine *******************************************;* Called from current test if current is too low. Need to slowly increase ****;* the duty cycle to increase the output voltage to get desired current. ******;* Increases duty cycle by adding 2 to the CCP1R,CCP1CON register. *******;******************************************************************************IncreaseDutyCycle
bcf STATEVAR,6 ;Clear flag that sets duty cycle to 0;In decrease routine
movf CCPR1L,w ;check to see if duty cycle is too high
38
-
8/6/2019 Reporte de Inversor PIC16f87X
39/42
sublw B'00111111' ;If so put max suty cycle value in.btfsc _Cgoto Continuebtfss CCP1CON,5goto Continuereturn
Continue
movlw 1 ;Check to see if bit 1 is highbtfsc CCP1CON,5 ;if so, goto AddLowgoto AddHigh ;else goto AddHighgoto AddLow
AddHighaddwf CCPR1L,f ;Add 1 to upper 8 bits then clear bitbcf CCP1CON,5 ;1 of the 10 bits. i.e. add 2, butgoto CheckAgain ;there is a carry to bit 3
AddLowbsf CCP1CON,5 ;set bit 1, (add 2 to bit 1, no carry)goto CheckAgain
CheckAgaincall WaitSecondsreturn
;******************************************************************************;****** Decrease Duty Cycle Routine *******************************************;* Called from current test if current is too high. Need to slowly decrease ***;* the duty cycle to decrease the output voltage to get desired current. ******;* Decreases duty cycle by subtracting 2 to the CCP1R,CCP1CON register. **;******************************************************************************DecreaseDutyCycle
btfsc STATEVAR,6 ;Check flag to see if duty cycle lowgoto CheckAgainbtfsc CCP1CON,5 ;Check to see if bit 1 is highgoto SubLow ;If so goto SubLowgoto SubHigh ;Else goto SubHigh
SubHighbsf CCP1CON,5 ;Set bit 1 of 10 bit valuedecfsz CCPR1L,f ;Subtract 1 from bit 0 of upper 8 bits
;i.e. Subtract 4 and add 2
;if clear, skip and set duty = 0goto CheckAgainbsf STATEVAR,6 ;Set low duty flagbcf CCP1CON,5 ;Clear duty cycle control registersbcf CCP1CON,4goto CheckAgain
SubLowbcf CCP1CON,5 ;Clear bit 1, i.e. subtract 2 from 10-goto CheckAgain ;bit value
;******************************************************************************;****** Clear PWM DutyCycle ***************************************************;* Called from voltage test if full voltage is reached. Simply clears the *****;* duty cycle control register to produce a duty cycle of 0%. *****************;******************************************************************************PWMOFF
;;;Set Duty Cycle;;;MOVLF B'00000000',CCPR1Lbcf CCP1CON,5bcf CCP1CON,4return
;******************************************************************************;****** Current Test Subroutine ***********************************************;
39
-
8/6/2019 Reporte de Inversor PIC16f87X
40/42
CurrentTestAgainbcf STATEVAR,3bsf STATEVAR,0 ;set statevariable to test voltage next
CurrentTest
bcf STATEVAR,1 ;Set state variable to test temperature nextbsf STATEVAR,2
MOVLF rdAN0 ;load control for AN1movlw d'15'movwf ADCHARGETIME
CheckCurrentLevelWait4CurrSettle
decfsz ADCHARGETIME,F ;delay 30 usec for settlinggoto Wait4CurrSettle
bsf startAD ;start conversion
ADWaitCurrbtfsc ADCON0,GO_DONE ;check GO_DONE bit and continue if cleargoto ADWaitCurr
; bcf offAD
BANK1
movf ADRESL,wBANK0movwf AARGB1MOVFF AARGB1,VOLTLOWMOVFF ADRESH,AARGB0MOVFF AARGB0,VOLTHIGHnopMOVLF 0,BARGB0MOVLF 100,BARGB1call FXM1616UnopMOVLF 3,BARGB0MOVLF 192,BARGB1CALL FXD3216Unop
;;;;;;;;;;Binary to ASCII Conversion;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Peatman 154
;After you have completed the calculation; of the temperature, you need to take the two-byte binary result;and break it into a three-ASCII-character result.;If you divide the two-byte binary value by ten, the remainder;will be the units digit value. Add H'30' to this to convert;it to the ASCII code for the digit.;Dividing the quotient by ten will yield the tens digit in the;new remainder and the hundreds digit in the new quotient.;;Divide; Output: 32 bit unsigned fixed point quotient in; AARGB0,AARGB1,AARGB2,AARGB3; 16 bit unsigned fixed point remainder in REMB0,REMB1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVLF 10,BARGB1 ;divide result by 10MOVLF 0,BARGB0 ;put 0 into BARGB0CALL FXD3216U ;remainder in BARG is units
movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,CURRSTG+5 ;put in tenths of a degree slot
;divide again by 10CALL FXD3216U ;remainder in REMB1 =degreesmovlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,CURRSTG+3 ;put in degrees slot
;divide result by 10 againCALL FXD3216U ;
40
-
8/6/2019 Reporte de Inversor PIC16f87X
41/42
movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1MOVFF REMB1,CURRSTG+2 ;put in 10s degrees slot
;divide result by 10 againCALL FXD3216U ;movlw H'30'addwf REMB1,F ;add H'30' to remainder in REMB1
movf REMB1,Wsublw H'30'btfsc STATUS,Zgoto Blank2goto Digit2
Blank2 MOVLF H'20',REMB1
Digit2 MOVFF REMB1,CURRSTG+1 ;put in 100s degrees slot
MOVLF H'02',REMB1 ;move space into 100's if = 0
MOVLF A' ',CURRSTG+6
MOVLF A'A',CURRSTG+7MOVLF A' ',CURRSTG+8
;******************************************************************************;****** 16 bit literal subtract ***********************************************;* Used to check if current is too low. ***************************************;******************************************************************************
movf VOLTLOW,W
sublw H'DC' ;subtract lit-w, result in w
movf VOLTHIGH,w ;put high byte into w
btfss STATUS,C ;if C=0->Carry from low byteaddlw 1 ;if C set add 1 back to high byte
;if carry bit=0 (not set) reduce high byte by 1
;if carry bit=0 (not set) reduce high byte by 1 to 10sublw H'01' ;H'11'-w(+1), result in w
btfsc STATUS,Cgoto IncreaseDutyCycle
;******************************************************************************;****** 16 bit literal subtract ***********************************************;* Used to check if current is too high ***************************************;******************************************************************************
movf VOLTLOW,W
sublw H'17' ;subtract lit-w, result in w
movf VOLTHIGH,w ;put high byte into w
btfss STATUS,C ;if C=0->Carry from low byteaddlw 1 ;if C set add 1 back to high byte
;if carry bit=0 (not set) reduce high byte by 1;if carry bit=0 (not set) reduce high byte by 1 to 10
sublw H'02' ;H'11'-w(+1), result in w
btfss _Cgoto DecreaseDutyCycle
return
41
-
8/6/2019 Reporte de Inversor PIC16f87X
42/42
;******************************************************************************;****** Turn off charging *****************************************************;* Display end of charging message and clear duty cycle ***********************;******************************************************************************TurnChargingOff2
call PWMOFF
movlw _Done1 - CDS
call DisplayC
movlw _Done2 - CDScall DisplayC
goto StopAll
;******************************************************************************;****** Display Subroutine ****************************************************;* Clears the LCD and displays the new values *********************************;******************************************************************************DisplayAll
movlw _ClrRow1End - CDScall DisplayC
movlw _ClrRow2End - CDS
call DisplayC
movlw _ClrRow2Begin - CDScall DisplayC
MOVLW VOLTSTGcall DisplayV
MOVLW CURRSTGcall DisplayV
MOVLW TEMPSTGcall DisplayV
return
;******************************************************************************
;****** WaitSeconds Subroutine ************************************************;* Utilizes LoopTime to pause for about 2 secs. between duty cycle calcs. *****;******************************************************************************WaitSeconds
MOVLF 150,LCD_TEMP ;Wait 2 secondsWaiting
call LoopTime ;Call LoopTime 25 timesdecfsz LCD_TEMP,Fgoto Waitingreturn
;******************************************************************************;****** StopAll Subroutine ****************************************************;* Stops all further action of the charger and must be reset. *****************;******************************************************************************StopAll
nopgoto StopAll
end