/* * Name: PulseCanvas.java * Author: Jason Schwier, Rensselaer Polytechnic Institute * Date: 7 October 2005 * * Description: This class provides the variables and functions to plot the PWM output of PCA0 given * the value of the registers PCA0CMPL and PCA0CMPH for comparison and the system clock. A * square wave is produced by calculating the period of the counter from the system clock * and the start value to determine the length between pulses. The rising edge of the pulse * is determined from the compare value specified by the user. This class does not take input * directly from the user, it only provides the functions for painting the single canvas. * * Changes: From 19 July - corrected the period from doing Integer division to Double division * * Rights: You may form derivatives of this file to fit your needs, as long as some credit is given to myself and * RPI for providing a starting basis of your work. */ import java.awt.*; import java.applet.Applet; import java.lang.*; public class PulseCanvas extends Canvas { // Canvas size variables private int xSize = 500; private int ySize = 250; // Graphical axis size variables private int xAxisStart = 10; private int xAxisEnd = xSize - 20; private int yAxisStart = 40; private int yAxisEnd = ySize - 10; // Real axis size variables private int maxRealXAxis = 20; private int maxRealYAxis = 2; // this will put logic 1 about half way up // User / derived values from the applet private static int compareValue = 32768; private static int startValue = 0; private static double period = (double)65536 / (double)1000 / 22.1184; private static String systemClock = "SYSCLK"; // Determine how far in the axes sit from the edge private int horizontalAxisUp = 40; private int verticalAxisLeft = 40; // Import the user / derived values from the applet into this canvas public void captureValues( int compare, int start, double periodValue, String sysclock ) { compareValue = compare; startValue = start; period = periodValue; systemClock = sysclock; } // Draw both axes, hash marks, and labels for the hashes private void drawAxes( Graphics g ) { // Horizontal axis g.drawLine( xAxisStart, ySize-horizontalAxisUp, xAxisEnd, ySize-horizontalAxisUp ); // Vertical axis g.drawLine( verticalAxisLeft, yAxisStart, verticalAxisLeft, yAxisEnd ); // Vertical hash for logic 1 int hashHalfLength = 5; int hashTemp = realToGraphicYAxis( 1, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); g.drawLine( verticalAxisLeft-hashHalfLength, hashTemp, verticalAxisLeft+hashHalfLength, hashTemp ); g.drawString( "Logic 1", hashHalfLength, hashTemp-hashHalfLength ); // Allow for a variable amount of hashes depending on the user choice of system clock // These values should match the corresponding values for the counter plot int hashInterval; if( systemClock == "SYSCLK" ) { maxRealXAxis = 12; hashInterval = 2; } else if( systemClock == "SYSCLK/4" ) { maxRealXAxis = 50; hashInterval = 10; } else //if( systemClock == "SYSCLK/12" ) { maxRealXAxis = 150; hashInterval = 30; } // Horizontal hashes and labels for( int i = hashInterval; i <= maxRealXAxis; i += hashInterval ) { hashTemp = realToGraphicXAxis( i, maxRealXAxis, verticalAxisLeft, xAxisEnd ); g.drawLine( hashTemp, ySize-horizontalAxisUp-hashHalfLength, hashTemp, ySize-horizontalAxisUp+hashHalfLength ); String hashLabel = Integer.toString( i ) + " ms"; g.drawString( hashLabel, hashTemp-(4*hashHalfLength), ySize-(2*hashHalfLength) ); } } // Create the pulse width modulation plot private void drawPlot( Graphics g ) { // Millisecond value of the start register value double startMS = startValue * period / (double)65536; // Millisecond value of the compare register value double compareMS = compareValue * period / (double)65536; // Logic 0 and logic 1 int minY = realToGraphicYAxis( 0, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); int maxY = realToGraphicYAxis( 1, maxRealYAxis, yAxisStart, ySize-horizontalAxisUp ); g.setColor( Color.red ); // Case where the counter starts above the compare value, obviously zero will output for entire time if( compareValue < startValue ) { int minX = realToGraphicXAxis( 0, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int compareX = realToGraphicXAxis( compareMS, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int pulseLowX = realToGraphicXAxis( period, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int maxX = realToGraphicXAxis( maxRealXAxis, maxRealXAxis, verticalAxisLeft, xAxisEnd ); g.drawLine( minX, minY, compareX, minY ); g.drawLine( compareX, minY, compareX, maxY ); g.drawLine( compareX, maxY, pulseLowX, maxY ); g.drawLine( pulseLowX, maxY, pulseLowX, minY ); g.drawLine( pulseLowX, minY, maxX, minY ); } // Case where the counter starts at the compare value, undefined results, let's say it will output one // to provide an opposite case to the previous else if( compareValue == startValue ) { int minX = realToGraphicXAxis( 0, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int startX = realToGraphicXAxis( startMS, maxRealXAxis, verticalAxisLeft, xAxisEnd ); int maxX = realToGraphicXAxis( maxRealXAxis, maxRealXAxis, verticalAxisLeft, xAxisEnd ); g.drawLine( minX, minY, startX, minY ); g.drawLine( startX, minY, startX, maxY ); g.drawLine( startX, maxY, maxX, maxY ); } // Normal case where the compare value is greater than the start value else { // Variable that tells where the start value is on the graphical axis int pixelStartValue = realToGraphicXAxis( startMS, maxRealXAxis, verticalAxisLeft, xAxisEnd ); // Variable that tells where the pulse will start for this period on the graphical axis int pulseStart = realToGraphicXAxis( 0, maxRealXAxis, verticalAxisLeft, xAxisEnd ); // Variable that tells where the pulse goes high for this period on the graphical axis int pulseToHigh = realToGraphicXAxis( compareMS, maxRealXAxis, verticalAxisLeft, xAxisEnd ); // Variable that tells where the pulse goes low for this period on the graphical axis int pulseToLow = realToGraphicXAxis( period, maxRealXAxis, verticalAxisLeft, xAxisEnd ); // Variable that tells the distance in pixels that the pulse was high int pulseHigh = pulseToLow - pulseToHigh; // Variable that tells the distance in pixels that the pulse was low int pulseLow = pulseToHigh - pixelStartValue; // Continue drawing pulses while the falling edge does not exceed the axis range while( pulseToLow < xAxisEnd ) { // Draw the pulse g.drawLine( pulseStart, minY, pulseToHigh, minY ); g.drawLine( pulseToHigh, minY, pulseToHigh, maxY ); g.drawLine( pulseToHigh, maxY, pulseToLow, maxY ); g.drawLine( pulseToLow, maxY, pulseToLow, minY ); // Update the period start point to the falling edge pulseStart = pulseToLow; // Update the rising edge by adding in the pixel distance the pulse is low pulseToHigh = pulseStart + pulseLow; // Update the falling edge by adding in the pixel distance the pulse is high pulseToLow = pulseToHigh + pulseHigh; } } g.setColor( Color.black ); } // Convert between the real X axis and the graphical X axis of the plot private int realToGraphicXAxis( double realCoord, int maxRealCoord, int axisStart, int axisEnd ) { // Determine the multiplicative scalar which is primarily determined by the ending coordinate of the real axis double axisScalar = (axisEnd - axisStart) / ((double)maxRealCoord); // Determine the additive scalar which is determined by the starting coordinate of the graphical axis double graphicCoord = (realCoord * axisScalar) + axisStart; return ( (int) graphicCoord ); } // Convert between the real Y axis and the graphical Y axis of the plot private int realToGraphicYAxis( int realCoord, int maxRealCoord, int axisStart, int axisEnd ) { // Determine the multiplicative scalar which is primarily determined by the ending coordinate of the real axis. // Remember the graphical axis is inverted. double axisScalar = (axisStart - axisEnd) / ((double)maxRealCoord); // Determine the additive scalar which is determined by the ending coordinate of the graphical axis double graphicCoord = (realCoord * axisScalar) + axisEnd; return ( (int) graphicCoord ); } public void paint( Graphics g ) { // Draw the title FontMetrics fontmetric = getFontMetrics( g.getFont() ); String title = "PCA0 Pulse Output"; int xRel = fontmetric.stringWidth( title ) / 2; g.drawString( title, (xSize/2)-xRel, 30 ); // Place the axes, hashes, and hash labels drawAxes( g ); // Draw the plot itself drawPlot( g ); } }