You are on page 1of 45

Proof of Concept Implementation With the SPARTAN 3E FPGA Evaluation Board for the CAL POLY SuPER Project

By Tony Wonsyld

Senior Project

ELECTRICAL ENGINEERING DEPARTMENT California Polytechnic State University San Luis Obispo 2008

TABLE OF CONTENTS
Section Page

Acknowledgments………………………..………………………4 I. Introduction…………………………………………………...5 II. Background……………………………………………………7 III. Requirements………………………………………………….9 IV. Hardware Design and Configuration ………………………..11
PWM Signal and Timer/Counter………………………………..11 Sensor ADC and Pre-Amp……………………………………...13 MUX Layout and Control……………………………………....14 Data Logging and Memory Control…………………………….17 Load Switch Control and LED Verification…………………....20 LCD User Display……………………………………………....21 V. Software Integration………………………………………………23 VI. Testing and Verification………………………………………….25 A. ADC and MUX………………………………………………….25 B. Memory…………………………………………………………26 C. PWM Output..…………………………………………………..27 D. Overall Timing………………………………………………….28 VII. Recommendations……………………………………………….31 VIII. Conclusions………………………………………………………33 A. B. C. D. E. F. Appendices A: Bibliography……………………………………………………………32 B: UCF File………………………………………………………………..33 C: C Software File and Headers…………………………………………...35 1. Main.c…………………………………………………………….35 2. Lcd.c and Lcd.h…………………………………………………..39 3. Inputs.c and Inputs.h…………………………………………… 4. Output.h………………………………………………………….. 5. IntC.c and IntC.h…………………………………………………… 6. Spi.c and Spi.h……………………………………………………. D: Senior Project Analysis……………………………………………….

2

List of Figures
Figures Page

Figure 2.1: Current Phase 1 Block Diagram………………………………………..6 Figure 2.2: Projected Block Diagram Using A Spartan 3E FPGA………………..8 Figure 3.1: Spartan 3E FPGA Development Kit…………………………………..10 Figure 4.1: Analog-to-Digital Converter Interface………………………………..13 Figure 4.2: Detailed View of Analog Capture Circuit……………………………..14 Figure 4.3: Functional Diagram and Truth Table For The LF 13508 MUX……16 Figure 4.4: DDR Controller Clocking Option For Asynchronous System………18 Figure 4.5: Functional Block Diagram For On-Board DDR SDRAM…………..19 Figure 4.6: Character Display Address Map For The LCD……………………...21 Figure 4.7: Sectioned LCD Screen Design…………………………………………22 Figure 5.1: Software Flow Diagram………………………………………………...24 Figure 6.2: Excerpt From main.c Program for Memory Test……………………26 Figure 6.3: PWM Output……………………………………………………………27

List of Table
Figures Page

Table 4.1: Programmable Gain Settings For The Pre-Amp………………….…..15 Table 6.1: A/D Conversion Accuracy………………………………………………25 Table 6.2: Elapsed Time for a Single Poll…………………………………………29 Table 6.2: Lower Time Bound of System …………………………………………30

3

Acknowledgments
I would like to thank Dr. Harris for bringing me on-board and letting me be involved in this wonderful program. I cannot tell you how much I‟ve learned. Also, my family who have all been so supportive, especially my mother and father, who I have everything to thank because of them. I love you so much. Lastly, I would like to thank Tom Hickock, for all of your help and wisdom. Your knowledge is priceless.

4

Ali Shaban and various EE and CPE students have started a prototype that aims to solve the fundamental problem of power distribution and affordability. This project will help move into Phase 2 by producing a proof of concept that will dramatically reduce overhead by replacing the current laptop with an FPGA device. Dr. a possible solution has been brought to research by the members of Cal Poly‟s Sustainable Power for Electronic Resources (SuPER). Currently the project is still in Phase 1 and the estimated price tag is about $1500. The idea is to harness solar energy via a solar panel to bring energy to household necessities such as lighting and refrigeration for a cost of under $500. The project is intended to help financially troubled regions with high levels of solar radiation. This project focuses on the actual interface functions for the FPGA to handle. Harris. sustainable source of solar power with a 20 year life cycle[1]. along with Dr. With solar technology and energy conversion efficiency increasing every year. For greater control and reliability. yet can be reprogrammed rapidly to adapt to changing circumstances and environments.I. The lab top acts as the central device that stabilizes the entire system and processes all the data and controlling algorithms. James Harris presented his white paper discussing a proposed activity to develop a low-cost. Dr. Technology has brought the FPGA industry into the high performance market of computers. progress is currently underway to install an OS onto the FPGA [12]. 5 . Introduction In 2005. In an ever-growing weak global economy. but great strides and improvements have been made along the way. where government aid and humanitarian projects lack funding.

1. It is an integral component to the functionality of the SuPER design. Figure 2. and the MOSFET switches. but consumes a large portion of power and is also very costly. shown in Figure 2.II. the PIC microcontroller. the DC-DC converter.1: Current Phase 1 Block Diagram [7] 6 . Background The system is currently controlled by a laptop computer. The laptop is the interface between data acquisition.

the development kit satisfies current demands as well as possible future additions such as a PS2 module for a keyboard or other user interface I/O. It is limited in physical size. PIC Microcontroller.2. is a simplified block diagram with the Spartan 3E as the central controlling component. The system uses the Xilinx‟s EDK to configure the FPGA‟s hardware and create and update the software. instead of the NiDAQ 6009‟s. which need new routed signals for future operation. The Spartan 3E runs at 50MHz and can be tailored to the users‟ demands. Two multiplexers will be added to handle all sensor signals. 7 . an FPGA is proposed to substitute for the laptop. several parts are cut out of the design and will be replaced with on-board devices and internal modules. like the pyrometer and thermocouple. in Figure 2. The Spartan 3E comes with an LCD display and is the only available interface for the user to verify and check data and address values. With all of its on-board hardware.In order to make the design more economically feasible. and speed. such as scope probes and logic analyzers. As you can see. the designer can gather enough information to verify the systems functionality. Below. An FPGA offers a powerful alternative in terms of accessibility. and two NiDAQ 6009‟s. because the Spartan 3E has a limited A/D interface. The only significant drawbacks are to the user interface and available on-board memory. The Spartan 3E development board is capable of performing all the necessary control and acquisition requirements at a fraction of the cost. but along with other troubleshooting and measurement devices. cost. Other additions have been added to the overall project. Not only will the laptop be replaced but also several other components: TTL-to-Serial Converter.

2: Projected Block Diagram With A Spartan 3E FPGA 8 .Thermocouple PV Array Pyrometer PWM Signal 5 DC/DC Converter Sensors FPGA 32:1 MUX Battery Note: Does not show sensor placement or MOSFET switch outputs from FPGA DC Motor TV LED’s Fridge Figure 2.

Log and display all sensor data. The entire system could efficiently be controlled and thereby limit the power consumption and wiring complexity. Thus. Eral Tan [8] understood and realized the importance of replacing the PC with an FPGA. Adjust the PWM signal to the DC-DC converter according to the MPPT algorithm. Allow for emergency shut-off to all loads and hardware to protect against reversed currents and current overload with a response time of 1/100 seconds. The Spartan 3E will allow the designers to remove with the PIC 9 .Requirements: As stated in his thesis. the requirements for the system are: Ensure the battery is being charged/discharged properly via switch control and sensor monitoring. Do all above requirements within a period of at least 1/10 of a second or faster. Allow user to select desired loads via the on-board switches. Create multiplexing and interfacing design to handle all sensor data lines. Due to the flexibility of the Spartan-3E board we will be able to replace several expensive components and ultimately lower the wiring complexity and simplify the user interface. Brian Estrada and Patrick Mariano [3] furthered this idea with their senior project porting UClinux to the Spartan3E development board from Digilent Inc.

there are only about 50 usable pins to interface the system. Due to the design of the FPGA. This latter approach would significantly reduce the number of I/O signals coming off the board to a few data lines. This allows us to either directly connect each system signal line to the board or to create a generic MUX design to handle the multiplexing. half of those I/O‟s are shared with the FX2. The sensors will require a simple voltage divider to bring the voltage level within a 0-5V range and can easily be implemented with an additional PCB design. Figure 3.1: Spartan 3E FPGA Development Kit The Spartan-3E development board has over 100 I/O‟s that can handle all of the systems proposed 32 signals according to Estrada and Mariano [3]. but would also require several MUX selector lines if the design is external to the board.microcontroller and TTL-to-serial converter. The Spartan-3E has 16Mbytes of RAM and 4Mbytes of Flash. along with the USB interface consisting of the two National Instrument 6009 DAQ‟s. In reality. Estrada and Mariano [2] suggested that uCLinux operating platform will require a major portion of 10 . The Spartan-3E has on-board ADC and DAC to handle the sensor conversions.

and can connect to the high-side driver that drives the DC-DC converter. This will not be a large expense. This module will produce the required PWM scheme according to the MPPT algorithm. The Xilinx‟s MicroBlaze (uBlaze) Embedded Development Kit (EDK) will be the softcore-based operating platform. the on-board memory devices. In order to log a sufficient amount of the sensor data.the flash memory and further stated that an external memory device may need to be implemented to store a reasonable amount of senor data. In particular. as well as monitoring the MOSFET switches. Converting and logging the sensor data. 11 . including time stamps. there is a timer/counter IP core that can be designed specifically as a PWM generator. or 100MHz. would not be a viable solution. 50. can easily be performed to satisfy the timing requirements above. The platform allows the user to custom tailor their designs by adding modules and adjusting their parameters to fit their design needs. The Spartan-3E‟s clock can be varied to run at 25. such as SDRAM. so timing constraints should not be a factor and should allow ample time to cycle through the design program. MicroBlaze EDK has numerous IP cores that give designers pre-made modules through user friendly software. but a necessary one.

This allows to the user/designer to add a timeline to the gathered information. the MicroBlaze EDK supports a Timer/Counter IP core that can operate in several timing modes. a pseudo-MPPT algorithm was created to adjust the duty-cycle according to a specific power supply voltage acting as a system sensor.Hardware Design and Configuration PWM Signal and Timer/Counter As stated in the last section. an internal clock is implemented with . The IP core can be configured using two separate counter registers within the core architecture that act as a PWM‟s period and duty-cycle. The PWM core also offers an interrupt signal which is connected to the Interrupt Controller IP core to maximize the codes efficiency.1s period increments. and plot trend lines for error correction. Since the system has a desired duty cycle of at least 1/10 of a second. since the system will not have to poll the PWM to check its status. and comparisons. therefore. which will provide sufficient accuracy and precision. power. Within this routine. The original MPPT algorithm is very complicated and requires several of the systems status signals and sensor readings in order to calculate the proper operating mode and duty-cycle adjustment. Witts[9] had found the ideal operating frequency to be 25 kHz for the DCDC converter. Another requirement of the design is providing all acquired sensor and system data a time-stamp. It is important to be able to distinguish different data points. The easiest solution is use the 25 kHz PWM generated signal and implement a simple software algorithm that increments a counter every 250 times the PWM ISR is accessed: 12 . The interrupt is sent to the uBlaze processor and the proper interrupt service routine (ISR) is followed. this system was modeled according to that specification.

though. Figure 4. DAC.(1/25 kHz) * 2500 = . Sensor ADC and Pre-Amp The Spartan 3E development kit has an ADC. which is a total sample period (conversion + acquisition period) of 667ns for the ADC [3]. and they work concurrently when sampling analog data using a serial peripheral interface (SPI).1: Analog-to-Digital Conversion Interface [3] 13 . It should be noted.82 Hours That allows plenty of time to gather sufficient data before the system backs up all saved data to another larger storage device or simply begin writing over pre-existing entries. As of now.1s Every logged data point will be concatenated with this count value. The ADC is a LTC 1407A-1 and the pre-amp is a LTC 6912-1. For the purposes of this project.5MHz. the timer accuracy is dependent of PWM frequency and should be changed future stages of the FPGA integration into the SuPER system. the timer in software must be adjusted as well. The maximum sampling rate is approximately 1. and a pre-amp chip on-board.1). only the ADC and pre-amp will be used (see Figure 4.1s = 1. The counter width will have a maximum width of 16 bits (due to the memories data interface). that if the PWM desing frequency changes. This will give a rollover time of: (2^16 – 1) * .

thereby ensuring only one device is selected at a time and won‟t block communication on the bus. including conversion and acquisition times. a higher ratio of 8 can be implemented. A ratio of 16 (system clock / SCK) was chosen to allow for extra design leeway. The SPI IP core in Xilinx‟s EDK allows for several parameterized configuration options regarding the two clock ratios.It requires 34 SCK cycles (SPI clock) to convert a sample analog input to digital data. The Pre-Amp has a clock limitation of 10MHz [6]. Figure 4.2: Detailed View of Analog Capture Circuit [3] 14 . if necessary. can operate at maximum of 50 MHz. The SPI has a tri-stated output and is configured as the master. The complete analog capture circuit below demonstrates the SPI interface with both devices and the Spartan 3E pin assignments. The SCK. while each subsequent device are defined as one-hot encode slaves to the master. so the maximum system clock to SCK ratio is 5:1. but. therefore.

channel 0 is used solely while the other channel is left unconnected. The two possible solutions for multiplexing the data using the FPGA are: 1. in return. will make scaling the input sensor voltages much easier.The ADC is a dual channel device which samples two separate signals during the same SPI read cycle. The ADC output is a two‟s complement value where the output is equated by: In order to make it more readable. Connect each signal to I/O pin on the board and multiplex using C or a VHDL state diagram. the user can compare the result directly with an oscilloscope or voltmeter to check the accuracy. Table 4. The old system used two NiDAQ 6009‟s which interfaced between the sensors and the laptop and each input sensor was multiplexed via software over the USB connection. By solving for Vin. some data processing must be implemented to solve for the actual Vin voltage. which. 15 .1: Programmable Gain Settings for the Pre-Amp [3] A gain of -1 was chosen primarily because it offered the largest input voltage range. It should be noted that during the SPI read cycle. For system testing purposes. both 14-bit samples are properly placed into separate channel variables within the C code of the project.

it was decided to use solution 2. which requires a certain amount of selector lines. and supply voltages. Therefore. The selector lines are defined in the uBlaze project as general-purpose I/O‟s (GPIO‟s). Figure 4. This will require two 16:1 MUX‟s. an external MUX.2. to allow for the additions.e. each requiring four selector control lines. this design recommends planning for 32 individual input sensors. Due to the lack (i. MUX Layout and Control The current SuPER design uses 21 sensors and 11 switches to monitor and control the entire system. Since the ADC offers two channels. There are plans to add at least an additional three signals for the ultracapacitor. and more for other components. The GPIO‟s can be configured to any data width (< system data bus width) and can varied within software to select the desired channel. Use an external N:1 MUX connected to the ADC (or N/2:1 using both ADC channels) . which will also reduce the complexity of the FPGA‟s internal software algorithm and also allow for easier signal troubleshooting.3: Functional Diagram and Truth Table for LF 13508 MUX [5]. 16 . the most efficient MUX solution would be implementing two separate selector devices to maximize throughput. over-lapping) usable I/O pins. a chip-enable.

The inputs will be simply changed by incrementing the value of the GPIO MUX register value in software. therefore. two additional Digital Clock Managers (DCM) (Figure 4.As a proof of concept. in Figure 4. To show that the system can handle switching between different sensors. 16bit data interface that can be accessed through a DDR SDRAM IP Memory Controller core within uBlaze. incrementing it will start the address back over to „000‟.8µs = 28. an entire sweep of all sixteen inputs causes a delay of: 16 * 1. The width is pre-parameterized to equal to 3 and the output will follow the truth table shown above. The other MUX input lines were grounded in order to make sure the device did not malfunction due to floating pins. this design used an available analog MUX from the EE department.3.8µs. were acquired and wired to a bread board that comes with the Hirose FX2-100P-1.8µs This delay can be minimized by switching the control lines in the program when other processes are being performed that don‟t require the current value of the sensor data such as data processing or memory writes and reads. Since the controller requires two fast clocks. Two LF 13508 8-channel analog multiplexers.27DS expansion kit[3] . out of sync by 180 degrees. Once „111‟ has been sampled and stored. This particular MUX has a worst case switching speed of 1. two MUX input lines were connected to separate power supplies so act as voltages coming from two separate sensors.4) are needed to 17 . Data Logging and Memory Control The Spartan 3E has a Micron (MT46V32M16) 64Mbyte DDR SDRAM chip.

The DCM‟s also require buffers for the clock outputs to clean up the signals before being passed to the DDR SDRAM controller. that uBlaze uses to route the net signals to external pins. and below is the clocking scheme used to connect the DDR SDRAM Controller to memory and the FPGA. the UCF file. Because the clock rate is so high. it is very susceptible to noise which can comprimise the signal. The physical connections can be viewed in Appendix B. the system resembled the recommended clocking setup more precisely and worked accordingly. which caused problems due to clock lagging through the top DCM. Clocking is the most important issue facing the memory interface. Figure 4. By switching the OPB clock to the output of the top DCM.ensure proper timing and eliminate clock skewing. and 18 . As aforementioned.4: DDR Controller Clocking Option for Asynchronous System [11] The DDR SDRAM Controller acts as an intermediate device which connects the OPB bus and all other necessary control lines to the on-board memory device. The “External Clock” below was used as the OBP clock initially. the A/D values are 14-bit.

which is handled by the controller. With a maximum of 32 sensors. but offer little extra room for the time stamp. For each sensor value.5: Functional Block Diagram For On-Board DDR SDRAM [4] After initialization. Figure 4. the memory goes through a software check to ensure all addresses are being accessed and all data is being read/write 19 . The address is 15-bit addressable.can fit into one memory address. this leaves a total of: 32M/32 = 1M individually logged data samples. which includes the two bits to signify which bank is being accessed. The memory can be easily written to and read from through assignment statements in software. The memory device itself is broken into four banks and the details of which are handled by the DDR SDRAM Controller internally. its time stamp will be stored in the address space above it. before the DDR SDRAM is full.

properly. 20 . be it a current.5). then the LED will illuminate. If the threshold is breached. then regardless of the switch position. and the mapped I/O pin will output 3. while being powered by the battery. the load switch control lines are treated as GPIO‟s that are mapped to specific I/O pins on the FPGA. The idea behind the design is for the on-board LED‟s to act as visual verifiers to the status of the selected loads. The Spartan 3E comes with four on-board switches that are active high in the up position. running at 50MHz. These load lines act as the MOSFET switch signals that allow the loads to turn on. the status of the switches and corresponding sensor data will be checked and subsequently turn ON/OFF the LED‟s and MOSFET switches accordingly. the read/write times are on the order of eight clock cycles. Throughout the main polling software algorithm. This will amount to a delay of less than . Since the memory device is double data rate (DDR) and has a parallel connection (Figure 4. Load Switch Control and LED Verification As with the MUX control lines. Part of the requirement is to shut-off a load if a given threshold is reached. The basic algorithm takes into account the switch position and corresponding sensor information for a particular load. where the clock rate is the system clock.2µs per memory write. The user can select a desired load to be turned by flipping a switch and the corresponding LED will illuminate. If the sensor information is within safe operating conditions.3 V when in the “ON” position. voltage or temperature warning level. 0V. the LED will deactivate and MOSFET load control signal will be brought to ground.

the controller is fed two four-bit nibbles to via the data interface. the design is limited to how much information the user can display at one time. much faster than the system clock frequency. Figure 4.7. the screen was split into four sections shown in Figure 4. in order to communication properly. The Spartan 3E I/O‟s have a switching speed of 5ns. LCD User Display The Spartan 3E Development Kit features an LCD that comes with an internal controller with which the FPGA communicates with the display. The display itself is limited in size and can handle a total of 32 characters (Figure 4. there are a five system loads and the Spartan 3E has only four switches.At this moment. For our purpose. 21 . but will need additional hardware to be able to interface the entire SuPER system design.6). Older Spartan versions had an eight-bit data line interface. This ensures that when emergency shut-off levels are reached the system will disable the MOSFET switch control lines and protect the system devices and circuitry.6: Character Display Addresses Map For The LCD [3] Therefore. For experimental purposes this offers enough user input to conduct the proof of concept design. The controller uses three control lines and four data lines to interface with the device.

This is a static display design for proof of concept purposes only. the report will offer possible solutions and recommendations.7.ADC Channel 0 Output ADC Channel 1 Output ADC Channel 0 From Memory ADC Channel 0 Time Stamp From Memory Figure 4. Later. 22 .: Sectioned LCD Screen Design This configuration allows the designer to monitor important sensors and time values for verification purposes. The big drawback is not allowing user input to change the data being displayed.

the more responsive the DC-DC converter. where the MPPT is truly needed and most efficient.1 shows the flow diagram for the entire system design. the programmer can interface with each of the components via the OPB bus. software must be added to make each module communicate with each other and external devices. These pins are declared in the UCF and lets uBlaze know where to be expecting the signals. along with battery power level. The EDK platform is capable of quickly adding pre-made C files and header files. That is why it increments using 5% steps until it reaches 35%. then the increase/decrease step becomes about . Figure 5. It produces a VHDL file that specifies names associated with each module. Most of the modules used within uBlaze. Software Integration After building the uBlaze project with the described components above. as mentioned before. require some initialization. Each I/O pin has a specific pin value that is associated with certain module components and GPIO. the small step size can still have a major effect in the overall duty cycle compared to the systems 1/10 second polling period. The start-up mode increases the duty cycle much faster to reach normal range. which better explains how the PWM is changed depending on “battery” voltage levels. while EDK takes care of all of the routing.5%. Since the ISR is entered at a frequency of 25 KHz. Appendix C includes C files and headers in full detail with comments to explain the process better.V. 23 . The quicker the PWM can adjust to the isolation levels of the PV array. Included in the ISR is the pseudo MPPT algorithm. By using those pre-defined names in software.

5V <= Battery < 2V? Y Y Set LED.5V N Initialize Interrupt Controller.5V? Y 1.5% Duty Cycle Unchanged Decrement Duty Cycle by ~. 24 . those stored memory values are read back out to compare them acutal ADC values on the LCD.1: Software Flow Diagram Once all initializations are completed and interrupts are enabled. the MUX selects the proper analog signals to pass through to the ADC where they are sampled. the program enters into its polling algorithm. and LOAD GPIO’s as Outputs Duty Cycle is <35%? N Y Increment Duty Cycle by ~. and stored. Here. processed.5% Duty Cycle = 0% Set SWITCH GPIO as Input Switch to Monitor Mode Clear Interrupt Bit Set Pre-Amp Gain to -1 Via SPI Write Return Enable MicroBlaze and IntC Interrupts Sample A/D Channels Increment MUX by 1 and Mem. The memory address MUX control lines are then incremented before the process begins all over again.Main: ISR Initialize Timer/ Counter to 25KHz PWM Mode Increment Duty Cycle by 5% Y Is in StartMode? N N N Battery < 2. and SPI Is Battery <1. LCD. For user verification purposes. along with the time stamp. Addr by 4 Process A/D Values Read Back From Memory (data and time) Display A/D Values on LCD Write A/D Value(addr = i) and Time Stamp(addr = i+1) to Memory Figure 5. MUX.

Testing and Verification Sensor ADC and MUX Two separate power supplies were connected to S0 and S15 on the MUX while the system polled through all sixteen MUX inputs and the LCD only displayed the two operating inputs.85 Actual (V) 0.04% %error (CH1) 5.43 1.54 2.64% 5.74 2.04 1. As the voltages are increased.74 0.81 0.00% 2.8 0. The lower limit for the ADC was found to be at about .78 volts.24 1.00% 2.60% 1.48% 2.28 2.21 1.53 2.45% 1. One reason of excess error is due to the 15V analog power supplies used in the test.88 1 1.76 2.8 2.05 2.14% 0.00% 4.74 2.29% 1.78 0.92 CH 1 (V) 0.78% 1.1 shows the accuracy of A/D conversion and data processing results.20% 1.09% 1.1: A/D Conversion Accuracy The results verify that ADC is working properly.9V.00% 0.25 2.55% 4. the error 25 .38% Table 6.06 2.49% 1.89 %error (CH0) 8.21 1.33% 1.41% 4.VI. yet there is relative error (>5%) associated with some data points.85 0.92 1. CH 0 (V) 0. which agrees with the spec sheet.88 0.93 1.4 1. rather than .04 1.79 2.72% 1.99% 1.29 2.5 2. Table 6.94% 4.01 2.68% 4.4 volts specified in the Spartan 3E data sheet[3]. which is seen in the lower ADC readings.77 2. The high limit was around 2. The actual voltage was read using an oscilloscope probe.11% 8.46 1. They are not capable of accurate output voltages below 1V.

the program enters into the polling algorithm where sensor data is stored. The test below in Figure 6. if ((a&0xFFFF) !=SDRAM[a]) fail = true. The LCD verified this result as well. a < SDRAM_MAX. along with the time stamp. The SDRAM memory appears to work and do so quickly enough to pass the requirements stated. a „-1‟ will appear in the upper left of the LCD. The variable „a‟ is masked with 0xFFFF to ensure that any data being passed to SDRAM is only 16-bit wide. 26 . After passing the test.c software file (Appendix C) that writes to every address and reads back from that address to verify the proper data was stored. } //stores value „a‟ at address „a‟ //checks each address for correct value //if wrong. a++){ SDRAM[a] = a & 0xFFFF. The value in memory matched exactly to the input voltage applied to the ADC. Memory The DDR SDRAM memory passed all initialization tests during the start-up of the system. and has yet to fail. repeatedly on LCD display_num(-1) } Figure 6.seems to be diminished. One solution would be to use a voltage divider or potentiometer with a constant 5V to get more accurate voltage readings from the power supplies. fail = true while(fail){ //displays -1.2: Excerpt From main. in the address above it. The test passed every time the program was loaded onto the board. for (a = 0.2 is an excerpt from the main.c Program For Memory Test If this test ever fails.

5V. The temporay variables passed the processed sensor data to variables that only were called by the LCD displays and memory R/W‟s.3 are snapshots of the PWM right at start-up. according to the pseudo-MPPT algorithm. (b). and the increase can be seen quite clearly. not only does the PWM duty-cycle drop to zero. the LED corresponding to that battery load line shuts off. by adjusting the incoming channel 0 ADC voltage. In order to get a better visualization of the signal. Both of those values are related to the ADC conversion equation and were factoring into the software‟s conversion of the data. The purpose was to show that a clean PWM signal can be produced and adjusted in real-time to increase efficiency and this point was well verified. 27 . where the duty cycle is 10%. The problem was solved by introducing temporary variables to do all data processing and manipulation. the duty-cycle increases by 5% until 35% was reached. Furthermore. PWM Output The PWM output signal performed as designed. demonstrating the emergency shut-off requirement was also met.6 volts and below where LCD periodically adds 130mV‟s to ADC value. The top is the initial 5% duty-cycle followed by the next ISR iteration.One small glitch occurs and a fix has not been found yet. the duty cycle could be increased or decreased by ~. During the start-up mode.25% steps. There is threshold of around 1. the PWM period was slowed down to 25Hz so measurements could be taken of the duty cycle step size. as the voltage is raised above 2. at which point. Figure 6.

including sampling every sensor. 28 . With these measurements the lower and upper timing bounds. and (3) each clock cycle takes 20ns.(a) (b) Figure 6. (2) each assembly instruction takes two clock cycles. can be extrapolated. Code length calculations are estimated by the following: (1) Each „C‟ code line takes five assembly instructions.3: PWM Output at (a) 5% and (b) 110% Overall Timing For a single cycle through the polling algorithm the following times have been estimated according to their spec sheets and code length. The A/D conversion time covers two sampled sensors and the memory write time is based on four writes– two for each sensor data sample and two for their corresponding time stamp.

the PWM ISR will be called every 40us. can be calculated by taking the single polling duty cycle time and multiplying it by the number of iterations to sample the remaining sensors: (14. The approximated elapsed time is: (15 lines) * (5 insn/line) * (2 cycle/insn) * (20 ns/cycle) = 3us As stated before. totaling a time of: 5.5 us/sample) * (16 samples) = . thereby being executed: (.2 is a summation of the software polling loop. Table 6. not including verification tests such as LCD writes and memory reads.8 Other Code 3 Polling Cycle Time 14. the remainder of the polling loop contains an estimated 15 lines of code.8us 29 .2us per write.232 ms During the above elapsed time.25 Memory Writes (X4) 0.5 Table 6.232ms) / (40us) = 5. Time (us) A/D Conversion 10. The code is comprismised of data processing and emergency tests.8 * 6us = 34.e. Therefore.25us and a memory write is estimated at . the quickest the system could sample of the sensors. the PWM ISR will take: (20 lines) * (5 insn/line) * (2 cycle/insn) * (20 ns/cycle) = 6us Like wise.The PWM ISR contains as estimated 20 lines of code. i.8 times.2: Elapsed Time for a Single Poll The lower bound. the ADC sample period is estimated at 10.

5us Total Sampling Time ISR Time 0.48us Lower Bound .267ms.3: Lower Time Bound of System Therefore. the design team could take multiple samples of each sensor and only store the average value.234ms 3. Polling Cycle Time 14. the system could theoretically process all of the information and control signals in . each sensor can be sampled approximately: 100ms/. the single polling duty cycle will as well. On the other end of the spectrum.267ms Time Table 6. taking multiple samples for each sensor will increase the reliability of the overall system and help ensure proper control of the external devices. This idea has merit because it would store a more accurate reading of the sensors actual value.3 is a summation of lowest possible limit the system can operate approprieately. Therefore.234ms = 375 times More testing would need to be made. which is well below this projects timing requirements of 1/10 of second. if the design sticks with the proposed system duty cycle time of 1/10 of a second. of course. Yet. each sensors data is effectively smoothed out from any discrepancies or spikes that might appear in the signals. 30 . because this is only a preliminary estimation according to the data gathered as of yet. By taking an averaging. The above number will turn out to be too large for the actual system because as the complexity of the software increases.Table 6.

complied. but would come at a cost to the performance of the overall system. as stated by Mariano and Estrada [2]. In order to transfer the sensor data and timing information. it is recommended that the software take multiple samples of the sensors and then average out their values. a new process must be implemented into software to control the operation. While the LCD allows for some data verification. there are still a few items that need to be worked out. Thirdly. Secondly. data will be lost every time the system is shut-down. This would cause a momentary lapse in the system monitoring process that could allow for adverse consequences. It is possible to elegantly set up the “memory dump” using interrupts instead of polling to minimize the systems break from system control. the polling algorithm will definitely increase as the design becomes more complicated and that upper bound will shrink. the current data logging scheme based solely on the on-board DDR SDRAM requires attention. the size and real-time configurability can be vastly improved. First. it would be recommended to use an additional external non-volatile memory device that the DDR SDRAM can dump its data into after reaching capacity. The upper bound of 375 samples per sensor is a little unrealistic. To circumvent the static memory. will be an issue. Recommendations Though the Spartan 3E has real potential for replacing the current laptop and other hardware. and downloaded 31 . As mentioned before. In order to look at different data. as already stated. This will ultimately save memory which. thereby losing valuable experimental data. The FPGA offers a few ports that could be interfaced to allow this transaction. the entire project must be programmed. adding a monitor and keyboard would offer a much better user interface. Since the memory is static.VII.

New software must be implemented to make sure voltage conversions are accurately calculated in reference to the MPPT algorithm and emergency shut-off thresholds. Adding an OS will give the user much more control via a monitor and keyboard to actively access control algorithms and make changes without rebooting the system.to see the results. 32 . step down voltage circuits must also be made to ensure all sensor voltage levels are within the required range of . The EDK design would need to add a few modules.3V. which is not high enough to drive the MOSFETS or DC-DC converter.9V.7V-2. The Spartan 3E has a PS2 and COM port already built on. On the other side. so some additional hardware would not be needed. but overall would not affect the size or speed too much if interrupts are used. the Spartan 3E has an output logic high voltage of 3. Additional circuitry will be required to boost the output signals to their required level by use of buffers. Lastly. thereby losing memory data. possible a UART or other communication core to interface to these components.

it has been shown that the I/O abilities of the Spartan 3E are capable of controlling all of the external components within the system. sustainable energy is moving closer to reality and hopefully this. The next step is to get the OS onto the FPGA. but some need adjustment and further investigation in regards to the performance limits and user interface. along with other SuPER research projects can help pave the way. The research and data gathered from this project will give the next generation of SuPER students a strong base to build upon. The other major system requirements reliability and lower power consumption are satisfied. it can better emulate the laptop‟s functionality within the system. 33 . The FPGA industry has proven to produce reliable and low power devices. Conclusions It was found that Spartan 3E Development Kit board is strongly suited for reproducing the capabilities of the current laptop controlling the SuPER system. The cost alone is a great reason to continue on with an FPGA centralized design. This will bring the price down much closer to the target price of $500. The fewer number of parts used. the less the chance of something breaking. compared to $600 laptop. As for now. and continue to improve upon the design. Reducing the number of components is directly correlated to reducing failure. the vision of low-cost. Once the FPGA has an OS. but there are still many hurdles to overcome due to the lack of documentation and experimental research. More work has been done this quarter. The major requirements are now known to be satisfied. None the less.VIII. The Spartan 3E evaluation board retails for around $150.

C 1121.pdf] [9] Joseph Witts “Cal Poly SuPER System Photovoltaic Array Universal DC-DC Step Down Converter” [http://courseware.pdf] [5] LF 13508 MUX Data Sheet [http://rbsfm.edu/~jharris/research/super_project/jw_thesis.pdf] 34 .edu/~jharris/research/super_project/et_thesis.edu/~jharris/research/super_project/white_paper_ super.ej.PDF] [6] LTC6912 Dual Programmable Gain Amplifiers with Serial Digital Interface [http://www.calpoly.com/support/documentation/ip_documentation/opb_ddr. Patrick “Development of UCLinux Platform for Cal Poly SuPER Project” [http://courseware.am/Downloads/Datasheet/LF/LF13508.pdf] [3] Spartan-3E Board User Guide [http://www.com/pdf/datasheets/dram/ddr/512MBDDRx4x8x16.calpoly.00b) [http://www. Tyler “Cal Poly SuPER System Simulink Model and Status of Control System” [http://courseware.C1154.xilinx.C1.ee.calpoly.ee.com/pc/downloadDocument.ee. Brain and Mariano. Eran “SuPER System Prototype Design and Implementation” [http://courseware.Appendix A Bibliography [1] Harris. Tech Support Email support@digilentinc.pdf] [4] MT46V32M16 (32M x 16) DDR SDRAM Data Sheet [http://download.edu/~jharris/research/super_project/ts_thesis.com [11] MicroBlaze OPB Double Data Rate (DDR) SDRAM Controller (v2.pdf] [2] Estrada.pdf] [10] Digilient Inc.pdf] [8] Tal.ee.com/support/documentation/boards_and_kits/ug230.C1009.linear. James G.micron.calpoly.D5359] [7] Sheffield. “White Paper for Sustainable Power for Electrical Resources SuPER” [http://courseware.ee.calpoly.P7596.do?navId=H0.edu/~jharris/research/super_project/be_pm_sp.xilinx.

"N7" . "F9" . NET NET NET NET NET NET NET NET NET NET NET NET NET NET NET "led_pin<7>" "led_pin<6>" "led_pin<5>" "led_pin<4>" "led_pin<3>" "led_pin<2>" "led_pin<1>" "led_pin<0>" "lcd_pin<6>" "lcd_pin<5>" "lcd_pin<4>" "lcd_pin<3>" "lcd_pin<2>" "lcd_pin<1>" "lcd_pin<0>" LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC = = = = = = = = = = = = = = = "F12" . "F11" . PULLDOWN . "D11" . PULLUP . PULLUP PULLUP PULLUP PULLUP . "C18" . needed here NET "sys_reset" LOC = "K17" | PULLDOWN.Appendix B # UCF for SuPER Prototype Project # # # # Created by: Tony Wonsyld # ################################### NET "sys_clk" LOC = "C9" . LOC = "T4" . . LOC LOC LOC LOC LOC = = = = = "P11" . # # # # # ROT_CENTER ROT_A ROT_B BTN_WEST BTN_EAST 0 1 2 3 "switches_pin<3>" "switches_pin<2>" "switches_pin<1>" "switches_pin<0>" #Switch #Switch #Switch #Switch 35 . LOC = "N10" . "E9" . "E11" . #SPI clock #SPI Write pin #SPI Read pin # # # # # AD_CONV for ADC Preamp Chip Select DAC Serial Flash NET "pwm_pin" NET NET NET NET NET NET NET NET NET "buttons_pin<4>" "buttons_pin<3>" "buttons_pin<2>" "buttons_pin<1>" "buttons_pin<0>" LOC = "D7" . LOC LOC LOC LOC LOC LOC LOC LOC LOC = = = = = = = = = "V16" "K18" "G18" "D18" "H13" "L13" "L14" "H18" "N17" | | | | | | | | | #PWM out signal PULLDOWN . # No pulldown in schematic. . # # # # # # # # # # # # # # # LED LED LED LED LED LED LED LED LCD LCD LCD LCD LCD LCD LCD 0 1 2 3 4 5 6 7 Data Data Data Data E RS RW 0 1 2 3 NET "spi_SCK_pin" NET "spi_MOSI_pin" NET "spi_MISO_pin" NET NET NET NET NET "spi_SS_pin<0>" "spi_SS_pin<1>" "spi_SS_pin<2>" "spi_SS_pin<3>" "spi_SS_pin<4>" LOC = "U16" . "N8" . . PULLDOWN . . . "C11" . . "R15" "R16" "P17" "M15" "M18" "L18" "L17" . "U3" . "E12" . PULLUP . . #Feedback clk for DCM NET "fb_clk_pin" LOC = "B9" |IOSTANDARD = LVCMOS25. . .

#MUX controll line 0 NET "mux_pin<1>" LOC = "B6" . SSTL2_I. LOC = "L6" | IOSTANDARD = SSTL2_I. . | | | | | | | | | | | | | #Load #Load #Load #Load IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD lines lines lines lines = = = = = = = = = = = = = 0 1 2 3 #SRAM Addrs pins NET "sd_a_pin<0>" NET "sd_a_pin<1>" NET "sd_a_pin<2>" NET "sd_a_pin<3>" NET "sd_a_pin<4>" NET "sd_a_pin<5>" NET "sd_a_pin<6>" NET "sd_a_pin<7>" NET "sd_a_pin<8>" NET "sd_a_pin<9>" NET "sd_a_pin<10>" NET "sd_a_pin<11>" NET "sd_a_pin<12>" #SRAM data pins NET "sd_dq_pin<0>" NET "sd_dq_pin<1>" NET "sd_dq_pin<2>" NET "sd_dq_pin<3>" NET "sd_dq_pin<4>" NET "sd_dq_pin<5>" NET "sd_dq_pin<6>" NET "sd_dq_pin<7>" NET "sd_dq_pin<8>" NET "sd_dq_pin<9>" NET "sd_dq_pin<10>" NET "sd_dq_pin<11>" NET "sd_dq_pin<12>" NET "sd_dq_pin<13>" NET "sd_dq_pin<14>" NET "sd_dq_pin<15>" #SRAM control lines NET "sd_ba_pin<1>" NET "sd_ba_pin<0>" NET "sd_cas_pin" NET "sd_clk_n_pin" NET "sd_clk_p_pin" NET "sd_cke_pin" NET "sd_cs_pin" NET "sd_ras_pin" NET "sd_we_pin" NET "sd_dqs_pin<1>" NET "sd_dqs_pin<0>" SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. . #MUX controll line 1 NET "mux_pin<0>" LOC = "E7" . SSTL2_I. SSTL2_I. SSTL2_I. LOC = "G3" | IOSTANDARD = SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. "H5" "H6" "G5" "G6" "F2" "F1" "E1" "E2" "M6" "M5" "M4" "M3" "L4" "L3" "L1" "L2" | | | | | | | | | | | | | | | | IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD = = = = = = = = = = = = = = = = LOC LOC LOC LOC LOC LOC LOC LOC LOC = = = = = = = = = "K5" "K6" "C2" "J4" "J5" "K3" "K4" "C1" "D1" | | | | | | | | | IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD IOSTANDARD = = = = = = = = = SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. 36 . SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. #MUX controll line 2 NET NET NET NET "loads_pin<3>" "loads_pin<2>" "loads_pin<1>" "loads_pin<0>" LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC LOC = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = "B4" "A4" "D5" "C5" "P2" "N5" "T2" "N4" "H2" "H1" "H3" "H4" "F4" "P1" "R2" "R3" "T1" . SSTL2_I. SSTL2_I. SSTL2_I.NET "mux_pin<2>" LOC = "A6" . SSTL2_I. . SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I. SSTL2_I.

CONFIG PROHIBIT = R4. L5.NET "sd_dm_pin<1>" NET "sd_dm_pin<0>" #prohibited IO's CONFIG PROHIBIT CONFIG PROHIBIT CONFIG PROHIBIT CONFIG PROHIBIT = = = = D2. G4. LOC = "J2" | IOSTANDARD = SSTL2_I. J6. LOC = "J1" | IOSTANDARD = SSTL2_I. 37 .

38 . // %5 step size duty_step_normal = 0x04.h" "intc. calls all initialization * functions. ch_1 = 0.h" unsigned int frequency = 25000. #define SDRAM ((volatile unsigned int *)(XPAR_DDR_MEM0_BASEADDR)) unsigned int button_array[5].h" "timer. // %5 intitial duty cycle duty_step_start = 0x62.h" "spi. // 50 MHz clock volatile volatile volatile volatile volatile volatile volatile volatile unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned int int int int int int int int duty_cycle = 0x62. //~. count=0.25% step size milli_count = 0. run * the timer ISR */ if(pendingIntc(XPAR_TIMER_INTERRUPT_MASK)) { timerISR(). unsigned int slow_down = 0. milli_sec = 0.h" "outputs. * *****************************************/ #include #include #include #include #include #include #include #include <xio. /* mainISR: main interrupt service routine * for the interrupt controller */ void mainISR() { /* If a timer interrupt is pending. unsigned int switch_array[3].h> <xparameters. and contains polling loop * to gather and store data. ch_0 = 0. /* Function prototype for ISR */ void mainISR() __attribute__((interrupt_handler)). // 25kHz unsigned int clock_freq = 50000000. sets up ISR.h> "lcd.Appendix C /***************************************** * main.c * * Core program for the SuPER FPGA prototype * * By: Tony Wonsyld * * * Purpose: Declares global variables.h" "inputs.

/* Enable interrupts */ microblaze_enable_interrupts(). } milli_count++. a < 0x3FFFFFF. k=0. unsigned char adc[5]. // Set SWITCHES's to output initLoads(). //End Memory Test 39 . //stores value address if ((a&0xFFFF) !=SDRAM[a]) //checks each address for fail = 1.2. } } /* main: core function to run the S3E demo */ int main(void) { int i=0. // Enable Interrupt Controller initTimer((clock_freq / frequency) . b. // Set Buttons to inputs initSPI(). if (milli_count == 2500) { milli_sec++. sendAmp(0x01. // Set MUX selector lines to output initLeds(). // correct value } while(fail) display_num(-1). Generate interrupt /* Turn on alternate LEDs as * part of the S3E demo */ LEDS = 0x00. 1). 0x02). // Setup LCD for 4-bit communication initSwitches(). //return home on LCD MUX = 0x00. a++){ SDRAM[a] = a & 0xFFFF. 0x01). //Set initial MUX address to "000" //Memory test for (a = 0. //Set the Pre-Amp gain to -1 writeLcd(LCD_CMD. // Enable Timer. unsigned int fail = 0. /* Initialize the various interfaces * and components */ initLcd(). // Set LEDs to outputs initButtons(). unsigned int button_pushed. //if fails.IAR = 0x03. unsigned int status. // Setup SPI module initIntc(). // Set LOAD lines to output's initMux(). j=0. milli_count=0. a. displays -1 via LCD write func.

++i) writeLcd(LCD_CHAR. // Only display to the two channels that are applied voltages. // Sign extend ch_1 = ((adc[2]<<8)&0x3F00) | (adc[3]&0x00FF). display_num(SDRAM[a+1]). if(b&0x2000) // Check sign bit ch_1|=~0x1FFF. //dummy sample to align MEM and ADDR for(..' '). //Move cursor to begginning readSPI(SPI_ADC. ((ch_1)*250)/(0x3FFF)+43. 0x02).) // Infinite loop { //microblaze_disable_interrupts(). //increase address pointer and mask a=(a+4)&0x3FFFFFF. offset and multiplier (((-ch_0)-1)+0x2000)&0x3FFF. if(MUX == 0x00) { writeLcd(LCD_CMD. //convert to mV's //Write vaules and time stamp to SRAM SDRAM[a] = ch_0&0xFFFF. adc. 5). SDRAM[a+2] = ch_1&0xFFFF. ((ch_0)*250)/(0x3FFF)+43. writeLcd(LCD_CMD. for(i=0. ++i) writeLcd(LCD_CHAR. //Move Cursor to bottom line of LCD //Disaplay ADC value and time stamp from SRAM display_hex(SDRAM[a]). SDRAM[a+3] = milli_sec&0xFFFF. ch_0 = ((adc[0]<<8)&0x3F00) | (adc[1]&0x00FF). 5). 0x02). 0x80). //Move cursor over to display channel 1 display_num(ch_1). //convert to mV's (((-ch_1)-1)+0x2000)&0x3FFF. //writeLcd(LCD_CMD. SDRAM[a+1] = milli_sec&0xFFFF. 0xC0). for(i=0.readSPI(SPI_ADC. i<5. if(a&0x2000) // Check sign bit ch_0|=~0x1FFF. //display channel 0 value on top line of LCD display_hex(ch_0). // Sign extend //Conversion ch_0 = ch_0 = ch_1 = ch_1 = to eliminate gain. adc. i<5. //Display channel 1 writeLcd(LCD_CMD. 40 .' ').

LOADS=LEDS. for(i=0. // Set data lines to inputs // First read cycle (first 4 bits) // ~125ns // ~125ns (E high for ~250ns) // Wait ~750ns // Second read cycle (second 4 bits) r<<=4. } // ~125ns // ~125ns (E high for ~250ns) // Wait ~750ns // Set data direction back to outputs 41 .c * * LCD Main Functions * * By: Tony Wonsyld * * * Purpose: Handles all the functions to initialize. and * convert data. for(i=0. i<5. } } return 0. i<5. display.h" /* readLcdStatus: gets the status from the LCD */ int readLcdStatus() { int i. return r&0xFF. ++i) LCD=LCD_RW. * *****************************************/ #include <xparameters. LCD=LCD_RW. r=(LCD&LCD_DATA). } else { LEDS=SWITCHES&0x0E.} MUX++. LCD=LCD_RW|LCD_E. } /***************************************** * lcd. LCD_DD=0. r. LCD=LCD_RW|LCD_E. //Increase MUX address //Emergency shut-off check and Load/LED status update if(ch_0<250) { LEDS=SWITCHES. ++i) LCD=LCD_RW.h> #include "lcd. LOADS=LEDS. LCD_DD=LCD_DATA. r|=(LCD&LCD_DATA).

for(i=0. ++i) LCD=0. for(i=0. // First write cycle LCD=rs|LCD_E|d. // Wait for LCD to not be busy sendLcd(rs. sendLcd(LCD_CMD. i<20*5500. for(i=0. ++i) LCD=0. /* RS is set */ if(rs) rs=LCD_RS. LCD=rs. int d) { int i. } /* Writes the given int to the LCD for * both instructions and data (depends * on RS) */ void writeLcd(int rs. } /* initLcd: Performs the power initialization * and entry for the LCD to read/write 8 bits */ void initLcd() { int i. i<10. d. i<500. value&LCD_DATA). int value) { int i. /* Power initialization to prepare LCD * to read/write 8 bits as 2 4-bit nibbles */ LCD_DD=0./* sendLcd: send the given int as an * instruction or data (depnds on RS) * to the LCD */ void sendLcd(int rs. sendLcd(LCD_CMD. while(readLcdStatus()&LCD_BUSY). 0x03). // Set to outputs // ~20ms delay // Set to 8-bit Operation // ~91us delay // Set to 8-bit Operation // ~91us delay // Set to 8-bit Operation // Send High nibble // Send Low nibble // Wait ~1000ns // // // // ~125ns ~125ns total E high for ~250ns ~125ns Hold time Wait ~750ns 42 . sendLcd(LCD_CMD. LCD=rs|LCD_E|d. i<5. sendLcd(rs. ++i) LCD=0. 0x03). i<500. 0x03). for(i=0. ++i) LCD=rs. ++i) LCD=0. (value>>4)&LCD_DATA). LCD=rs|d. for(i=0.

++i) LCD=0. } 0x28). (n/i)%10 + '0'). 0x0C). 0x06). /* printLcd: Prints out the given string to * the LCD */ void printLcd(char *msg) { while(*msg) writeLcd(LCD_CHAR. i<500. ++i) { v=(n>>(4*((NUMDIGITS-1)-i)))&0x0F. 0x02). for(i=0. writeLcd(LCD_CMD. if(n<0) { writeLcd(LCD_CHAR. 'A'+v-10). n=-n. i. } for(i=10000. '-'). writeLcd(LCD_CMD. i<NUMDIGITS.for(i=0. } /* display_num: displays the given 4 digit number to the LCD */ void display_num(int n) { int i. for(i=0. '0'+v). i<500.h * * LCD Header File * * By: Tony Wonsyld * 43 . ++i) LCD=0. else writeLcd(LCD_CHAR. writeLcd(LCD_CMD. } #define NUMDIGITS 4 void display_hex(int n) { int i. v. *(msg++)). writeLcd(LCD_CMD. 0x01). } } /*************************************** * lcd. if(v<10) writeLcd(LCD_CHAR. // ~91us delay // Set to 4-bit Operation // ~91us delay // // // // Function Set Display On Clear Screen Set Entry Mode sendLcd(LCD_CMD. i/=10) writeLcd(LCD_CHAR.

commands.* * Purpose: Defines registers. void display_hex(int n). void writeLcd(int rs. void display_num(int n). int value). void printLcd(char *msg). and prototypes * for use of the LCD ***************************************/ #ifndef LCD_H #define LCD_H /* Register defitions */ #define LCD (*(volatile unsigned long *)(XPAR_LCD_BASEADDR+0x00)) // Data register #define LCD_DD (*(volatile unsigned long *)(XPAR_LCD_BASEADDR+0x04)) // Data direction register /* LCD instruction and data commands */ #define LCD_DATA 0x0F #define LCD_E 0x10 #define LCD_RS 0x20 #define LCD_RW 0x40 #define LCD_BUSY 0x80 #define LCD_CMD 0x00 #define LCD_CHAR LCD_RS /* Function prototypes */ void initLcd(). #endif 44 .

Appendix D 1. ADC sample valued takes an entire sampling period before data is valid 45 . The system clock net connections 2.