Microprocessors Final Project
- littlenv
- May 25, 2018
- 5 min read
The code for this project can be found here: https://drive.google.com/open?id=12x7A_y27FeFjO-CmSGD2eBJZulcCC-bO
This design is meant to utilize the Pulse Width Modulation and ADC components of the HCS12. There are five states to the design: rest, potentiometer, phototransistor, scan, and manual. The code uses a series of linear equations to convert the ADC value, or angle value depending on the mode, to the correct duty cycle. The LCD screen on the HCS12 also outputs the current mode and angle of the system.
The PWM can use either PWMCLKA or PWMCLKB. In this design, both clocks were initialized, but only CLKA was used. CLKA is set to have a prescaler of 8 using PWMPRCLK. Using PWMPOL, PWM channel 5 is set as an active high polarity. All channels are set to be left-aligned. PWMCTL sets channels 4 and 5 as the output for the PWM and concatenates both 8-bit channels into one 16-bit PWM channel, while PWME enabled those channels. The PWM also stops in wait mode and the counter stops in freeze mode. A value of 60000 was chosen for the PWM period since (1/(24MHz/8))*60000 = 20ms.
The serial communication is set to always poll the user for input. No interrupts were used.
ATD0CTL2 turns on the ADC and sets it for normal operation. ATD0CTL3 sets the ADC to take conversion, stores results in corresponding registers, and waits for the system to finish conversions before it begins the next conversion. ATD0CTL4 sets the ADC to 10-bit operation, sets the length of the 2nd phase of sample time to 16 clock periods, and sets the max bus clock to 4MHz.
LCD:
The LCD runs off of three functions: openLCD, putcLCD, cmd2LCD, and putsLCD. openLCD initializes the LCD. putcLCD puts a single char onto the screen. putsLCD outputs an entire string. cmd2LCD allows for the creation of a “newline.” All the modes for the system are defined in strings.
The LCD is handled in the main function. The top line of the display corresponds with the state of the system. After that is output, the system brings the LCD cursor to the next line and ouputs “Angle: “. It then parses the angle and can detect negative angles. If the angle happens to be negative, a ‘-‘ is output to the LCD before the angle is sent.
Rest Mode:
In rest mode, the LCD displays “Rest Mode” and “Angle: 00.” Since no conversions were needed, the duty cycle and angle to be displayed are hard coded
There is a latter if statement before the duty cycle is sent to the PWM that states if the duty cycle is 4500, set the angle to be displayed to 0;
Potentiometer:
In the potentiometer mode, the duty cycle is set by the output of the potentiometer. The system enables the potentiometer on Port 7 of the ADC as right justified, unsigned numbers, and constant conversions. Since the ADC converts the data 8 times before a success flag is sent, the data is averaged to reduce noise. This is done by adding all eight 16-bit registers together and bit shifting the result 3 times in order to get the correct 10-bit output.
Since the output of the ADC is right justified, PORTB for the LEDs is fed directly by a single output register. Every run through of the main function, however, PTP is set to 0xFF to turn off the 7-segment displays. This gives it the upper 8 MSB of the output. The linear equation for the whole duty cycle is calculated by finding the slope of the output of the ADC vs. the minimum and maximum duty cycle in seconds. This is then multiplied by 60000 to avoid overflow. The y-interrupt was found simply by knowing what the duty cycle should be when the ADC output is 0. The same process was used to find TC5count in order to output sound. Since the equations are not 100% exact in conversion due to decimals, if statements were used after any conversion that set the values to their maximum or minimum values in case those limits were reached. Since OC5 is tied directly to the speaker, it is initialized in our button interrupt whenever the system enters the potentiometer or phototransistor states. OC5 is set to have a prescaler of 8, so the TC5count range is set by the following equation:
TC5count = 1/((min/max frequency)/(2*24MHz/8))
OC5 is initialized as soon as the system enters this state.
Phototransistor:
The phototransistor follows the same pattern as the potentiometer, except Port 4 for the ADC is enabled instead.
Scan Mode:
Scan mode is controlled by OC6. OC6 is set to have a prescaler of 8 and a TC6 += value of 3000 to give even .001s interrupts. When this mode is initially entered, Putty prompts the user to enter a scaling factor between 00 and 99 as parsing from Putty only handles strings of length two. Once the user enters the scale value, the number is converted to an integer and used in the OC6 interrupt. The default incrementation of the angle is set to .01s with a count value of 10. The scaling factor is multiplied by the count value to vary the timing of the angle changes
The calculation for the duty cycle was made using the same method as the other conversions. The equation handles -90 to 90 as its “x” value and treats the duty cycle as the “y” value.
Manual Mode:
Manual mode allows the user to input an angle manually via Putty to the system
The system prompts the user to input an angle anywhere from -99 to 99. If the user inputs a value over/under +-90, the system sets the values to the respective maximum or minimum before the data is sent to the PWM. When the user inputs an angle, the input is stored in a temp variable, as well as a buffer array. Each index in that array holds the integer value of the ASCII equivalent of the characters the user entered. If that is ‘N’, or 78, the system flags that the user is done with serial communication and allows the system to move on. If the user enters ‘0’ or ‘00’, the system distinguishes that and hard codes the angle and duty cycle values. Both algorithms used to find other angles are roughly the same. If it’s a positive angle, the system subtracts 48(ASCII ‘0’) from buf[0]2, the tens place, and multiplies it by 10. It then does the same thing for buf2[1], except it is not multiplied. If the user enters a negative angle, or “45” in buf2[0], the indexes for the ones and tens places increment by one and the final angle is multiplied by -1. The system does not handle single integer angles entered in the for ‘1’ or backspaces, so the user must enter an angle in the form ‘00’
Komentáře