This device must output, using IDAC, a biharmonic signal with two different central frequencies (100 and 200 Hz), the frequency of the second harmonic is equal to the frequency of the central frequencies / 3.
At first there should be a clean oscillation (sine wave), then after pressing the button a parasitic harmonic oscillation appears and lasts for 2 seconds, then the signal returns to the initial value.
Before and after:
During the test, I used a different frequency ratio of parasitic to normal oscillation for the second mode (not 3, but 2). Only to monitor the correctness of the mode change.
Based on the fact that the frequency changes (100 or 200 Hz), it is necessary to change the period of the output of the signal counts using interruptions (Period Timer).
It is also obvious that the call period will vary from the sampling frequency (the number of counts per period).
As a result, the formula for calculating the call step looks like this:
As can be seen from the above attached figure, the period is set to 24000 (1ms). The device works according to its described functionality (changing the waveform according to the mode) but with one problem, I could not change the timer period (Timer_Samples).
I tried to find something similar, but using the solutions given there, I could not get it to work. I also want to emphasize that it not only did not change, but in general stopped outputting anything when changing the mode (for the first time, everything worked, but probably most likely using the uncalculated value of "Step" in Timer_WritePeriod() and what was entered into the timer, namely 24000 (1ms ).
I will be grateful for your help, I am also attaching an archive with the project.
P.S. I did that, but the period still doesn't seem to change:
Attached is a demo project, showing generation of the Sine wave using PSoC4200 micro on the Pioneer Board (CY8CKIT-042). I drafted new project to demonstrate a software DDS approach to generating any repeatable waveshape of any amplitude and frequency while keeping IDAC sampling rate constant. It uses custom component (the Voice), which calculates phase increment based on IDAC update clock and needed output frequency, and advances the position in the lookup table on each clock. This is how the music is synthesized in synth, so it is called a "Voice". You can add or mix as many Voices as processor is able to handle in the time allocated between the IDAC sampling clocks.
The project works as following: on startup only the primary tone is generated at 100Hz. When the button SW2 is pressed, the 3-rd harmonic (300Hz) is admixed to the output for the duration of the delay Timer (2sec). When timer expires, the 3-rd harmonic is disabled.
The amplitude and the frequency of the Wave_1 and Wave_2 can be modiied at runtime. When using a signed sine wavetable, the output is centered around 128 (approx. 1.5V). To obtain 0-3V sine output, attach a 10k resistor between the Pin_3 and the GND as shown in the project annotation.
Project is attached
Figure 1. Project schematic. IDAC is updated on interrupt at 10kHz rate. The IDAC set value is calculated using sine wave table and phase increment produced by the Wave_1 and Wave_2
Figure 2. Pressing onboard button SW2 rises interrupt, which enables 3-rd harmonic generation for the duration of the delay Timer_1 (2sec). Once the Timer expires, the 3-rd harmonic is disabled. The Timer_1 is configured for 1-shot operation and re-started on button SW2 press event. The onboard Red LED will flash for the duration of the Timer_1.
Figure 3. Project annotation created using PSoC Annotation Library and KIT-042 library. The onboard SW2 button is connected to the Pin_0 internally. To produce voltage output from the IDAC in the 0-3V range, use external 10k resistor, attached between Pin 3 and the GND.
Figure 4. IDAC output of 100Hz sine wave at max amplitude (255).
Figure 5. IDAC output after button is pressed. Mix of 1-st and 3-rd harmonics with same amplitudes 127:127
It's an interesting solution, although I haven't fully understood it yet, but as I understand it, the component you use is not standard. I, in turn, was waiting for a decision on changing the Period parameter, because as I wrote, after changing the Timer mode, it seems that the subroutine from IDAC did not start to be called.
The example above shows a technique of generating output frequency with 32-bit accuracy, which is not possible by simply changing IDAC sampling rate. It is called Direct Digital Synthesis (DDS).
Changing sampling clock by updating the Timer period is not a good idea - to update the period the Timer must be stopped, period updated, and then started again. This will inevitably introduce some jitter/delay in the output.
The other pitfall of changing the sampling frequency is that the project has to be optimized out to run at 2x frequency. That means the output waveform data needs to be precalculated in some buffer prior to the waveform output.
Better way would be not using the Timer at all: just connect the interrupt to a clock and change the clock divider at run-time Clock_1_SetDivider(...).