reporte de inversor pic16f87x

Upload: reynaldo-martinez

Post on 07-Apr-2018

235 views

Category:

Documents


0 download

TRANSCRIPT

  • 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