This repository contains embedded software for a function generator implemented on the TMS320F28069M microcontroller. The function generator is capable of generating three-phase wave with configurable parameters such as: PWM frequency, sin frequency, modulation depth, offset, and phase (of each wave).
IDE: Code Composer Studio v12 Compiler: TI v22.6.1 LTS Serial terminal: HTerm 0.8.9
Microcontroller: Texas Instruments TMS320F28069M
The project is structured as a Code Composer Studio project.
- Download Code Composer Studio.
- Download a serial terminal
- Set: Correct port (found in device manager), baud rate to 9600, Data 8, Stop bit = 1, Parity = 0
- Newline at CR+LF
- Send on enter: NULL
- Set transmit and recieve on "Ascii"
- Click the "connect" button (In HTerm, disconnect should be shown once connect is pressed)
To run the project for development:
- Clone the repo
- Open Code Composer Studio at the directory the repository is located in such as
C:\MyProjects\FunctionGenerator\
- Import the project
- Link "common" folder and link "headers" folder (C:\ti\c2000\C2000Ware_5_02_00_00\device_support\f2806x\common and C:\ti\c2000\C2000Ware_5_02_00_00\device_support\f2806x\headers)
- Exclude three files from build from common/source (files shown in picture below)
\F2806x_CSMPasswords.asm, \F2806x_SWPrioritizedDefaultIsr.c, and \F2806x_SWPrioritizedPieVect.c)
The first wave comes out of P0, Second P2, third P4
Connect the pins like this (each output having its own low pass filter):
Here are the components used in each filter:
(you can switch the 100k to a bigger resistor, the bigger the better)
To run the project for development:
- Open and setup serial terminal
- From Code Composer Studio, click Build (hammer icon).
- Attach a XDS510USB debugger to the development board.
- Click Debug (bug icon).
- After the target has been flashed, click the start button (play icon).
- This screen should show up in the serial terminal, follow directions to change wave.
Unit tests currently aren't integrated into this project.
The development workflow used to develop this project is GitHub Flow.
In summary:
- Create a branch.
- Make changes.
- Create a Pull Request.
- Address Review Comments.
- Merge your Pull Request.
- Delete your branch.
The PWM (Pulse Width Modulation) creates the waveform by generating a sinusoidal signal modulated by a triangular carrier signal. Here’s a breakdown of how this logic works:
- Basic PWM Setup A higher PWM frequency means the ISR is triggered more frequently (smaller amout of clocks), allowing for more updates to the PWM duty cycle, which can improve accuracy and resolution of the output signal. Adjusting the sin frequency changes the rate at which the angle increments in the ISR. A higher sin frequency results in faster angle increments, which increases the frequency of the generated sinusoidal waveform.
The smallest value for the PWM frequency is 687 because the pwm counter is only 16 bits, 2^(16) > 90 * 10^6 / (pwmWavFreq * 2).
-
Sinusoidal Signal Generation Angle Calculation: An angle is incremented in each ISR call to simulate the sinusoidal waveform. Angle Increment: This value determines how fast the angle progresses based on the sinusoidal frequency. float angleincrement = 2 * M_PI * (liveEpwmParams.sinWavFreq / liveEpwmParams.pwmWavFreq); Wrap-around Logic: If the angle exceeds 2 * M_PI, it wraps around to keep it within the range of 0 to 2 * M_PI.
-
Duty Cycle Calculation Sine Calculation: The sine of the current angle, adjusted by a phase shift (phaseLead1, phaseLead2, phaseLead3), is used to create a sinusoidal modulation. float duty_cycle = (sinf(angle + liveEpwmParams.phaseLead1 * M_PI / 180.0) * liveEpwmParams.modulation_depth + 1) * 0.5 - liveEpwmParams.offset;
-
Compare The one minus the duty cycle (calculated as a percentage) is then multiplied by the period and stored in the compare register (one minus just makes the math a little better to follow)
This project has been developed by Ethan Robotham.