Use timer for generating sine waveform in CodeVisionAVR - c

Can anybody help me about CodeVisionAVR? I want to write a program for
ATMega16L microcontroller to generate sine waveform using the timer feature
in CodeVisionAVR, but I don't know how to use OCR with sine wave.

Ouptut Compare (OC) timer outputs can only generate square wave. However they can be used for pulse-width modulation (PWM) where the width of the pulse can be varied; if a PWM waveform output is low-pass filtered, the output will be a voltage proportional to the mark-space ratio of the PWM waveform. By modifying the pulse width sinusoidally and with suitable filtering you can generate a sine wave output.
So at each timer re-load interrupt you need to modify the pulse-width. I suggest that you pre-calculate the pulse widths into an array of values and feed them cyclically to the timer on each re-load interrupt. There are however a number of trade-offs between PWM frequency, pulse-width resolution, analogue filtering and wave-form frequency which would affect the accuracy of the waveform. You need to balance these variables to suit your requirements with respect to frequency and bandwidth.

You can also use the timer to trigger an interrupt where you write the waveform data out of other GPIO pins (using a resistor ladder as a DAC or similar), you could put the waveform data in a lookup table and step through the table every time an interrupt fires.
Alternatively if you have a suitable PWM output pin, you could use the timer interrupt to de/increment the duty cycle value to give a sine or any other shape wave output. This does require the PWM timer to be going much faster than the required sine wave so you can filter it, but that depends a bit on how accurate you need to be.

Related

How to control the rate of LED blinking

I am using STM32 board to control the color and blinking rate of the RGB LED. For varying the color of RGB LED I have configured a timer in PWM mode and by varying the duty cycle of three signals on three channels of this timer, the LED changes the color. How can I control the blinking rate of LED with another timer? Which mode of second timer and technique should be used to control the on and off time?
Thanks in advance.
There are many ways that you can do this.
The simplest is in the main loop of your application to read some clock or free running timer. If it is time for the next LED colour then update the PWM duty cycle.
A more complicated approach that does not require code in the main loop would use a DMA whose source is an array of PWM values and whose destination is the duty cycle register of the output timer. You can then use a different timer to periodically trigger the DMA.

STM32F4xx phase shift of carrier wave (timers)

I just want to generate PWM signals for single phase cascade H bridge inverter.
Theortically speaking, I need to shift carrier wave (triangular or sawtooth) in order to get sinusoidal PWM (see picture). I don't know how to obtain these shifted waves with stm32 (also I need complementary output so using TIM1 is obvious choice).
My idea is to use TIM1 and check in interrupt actual value of TIM1 and start another timer, but STM32F11 has only one timer with complementary output (TIM1).
Thx for any help
Picture is from "Pulse Width Modulation for Power Converters - principles and practice"

stm32f446 When using dma to control PWM duty cycle, the PWM wave has abnormal waveform

MCU: f446rct6
System: freertos
Library: hal
Program logic:
Initialize the timer to output the PWM wave and initialize the DMA and connect to the Capture/Compare register
Start the timer
When data needs to be updated, start a dma transmission
Phenomenon: There is no problem with the frequency and duty cycle of the PWM wave, but a strange triangular waveform often appears in the first or second waveform of DMA transmission.
Ask everyone, do you encounter similar waveforms when using pwm? Please give me a hint to locate this problem, thank you
Potential causes include:
You're switching the pin to DAC mode (if your MCU has a DAC) and driving it with an increasing value.
The pin is disabled, and what you see is the drift of the voltage on the pin's and probe's combined capacitance.
You're inadvertently switching the PWM to a very high frequency and the scope is set to too low sample rate. Make sure you set the scope to highest possible sample rate / sample depth / sampling length, and decrease the horizontal scale (i.e. decrease the time per division by 2x or 5x).

Generate a fixed number of pulses on the STM32F4 PWM

I am trying to control a servo motor (link). It is a brushless DC motor with an interface similar to a stepper motor.
The motor rotates for a defined distance based on the number of pulses it receives from the PWM. The speed is determined by the pulse frequency of the PWM, like a stepper motor.
To control this motor I am using a microcontroller STM32F407ZET6. I can easily change the frequency and Duty Cycle of PWM, but my doubt is the following:
How do I generate a fixed number of pulses in the PWM? For example, I want the PWM to send 1000 pulses at a certain time with a frequency of 20KHz and a Duty Cycle of 50%. 20KHz and 50% Duty Cycle are easy to define, but I can't determine how to generate the 1000 fixed pulses.
One of the solutions I tried was to connect the PWM back to a timer in counter mode and stop the PWM when the required number of pulses has been generated. But the number of pulses is not always fixed, sometimes ranging from 998 to 1005 (for example).
Is it possible to do this without the need for feedback?
Simpest way:
UG interrupt = count cycles. After n cycles disable the timer.
In the memory create a buffer with the timer register values and use timer burst mode.
Configure DMA mem-mem with n cycles same source and destination address. After n cycles end of transaction interrupt will be generated - disable the timer.
Use slave timer counting when the PWM is updating (overflowing). Set the overflow interrupt and disable the PWM timer.
many other methods.
This can be easily achieved by combining the so called "One-pulse mode" (reference manual page 551) with the repetition counter (page 529). All you've got to do is enabling this mode (OPM bit in CR1), set the repetition counter (RCR) and start the timer. IIRC you also have to force an update event in order to get RCR loaded. The reference manual will have more information on that.

Generating a tone with PWM signal to a speaker on a PIC32 microcontroller

I'm currently working on generating a tone on a PIC32 device. The information I've found has not been enough to give me a complete understanding of how to achieve this. As I understand it a PWM signal sends 1's and 0's with specified duty cycle and frequency such that it's possible to make something rotate in a certain speed for example. But that to generate a tone this is not enough. I'm primarily focusing on the following two links to create the code:
http://umassamherstm5.org/tech-tutorials/pic32-tutorials/pic32mx220-tutorials/pwm
http://www.mikroe.com/chapters/view/54/chapter-6-output-compare-module/#ch6.4
And also the relevant parts in the reference manual.
One of the links states that to play audio it's necessary to use the timer interrupts. How should these be used? Is it necessary to compute the value of the wave with for example a sine function and then combine this with the timer interrupts to define the duty cycle after each interrupt flag?
The end result will be a program that responds to button presses and plays sounds. If a low pass filter is necessary this will be implemented as well.
If you're using PWM to simulate a DAC and output arbitrary audio (for a simple and dirty tone of a given frequency you don't need this complexity), you want to take audio samples (PCM) and convert them each into the respective duty cycle.
Reasonable audio begins at sample rates of 8KHz (POTS). So, for every (every 1/8000th of second) sample you'll need to change the duty cycle. And you want these changes to be regular as irregularities will contribute to audible distortions. So you can program a timer to generate interrupts at 8KHz rate and in the ISR change the duty cycle according to the new audio sample value (this ISR has to read the samples from memory, unless they form a simple pattern and may be computed on the fly).
When you change the duty cycle at a rate of 8KHz you generate a periodic wave at the frequency of 4KHz. This is very well audible. Filtering it well in analogue circuitry without affecting the sound that you want to hear may not be a very easy thing to do (sharp LPF filters are tricky/expensive, cheap filters are poor). Instead you can up the sample rate to either above twice what the speaker can produce (or the human ear can hear) or at least well above the maximum frequency that you want to produce (in this latter case a cheap analogue filter can help rid the unwanted periodic wave without much effect on what you want to hear, you don't need as much sharpness here).
Be warned, if the sample rate is higher than that of your audio file, you'll need a proper upsampler/sample-rate converter. Also remember that raising the sample rate will raise CPU utilization (ISR invoked more times per second, plus sample rate conversion, unless your audio is pre-converted) and power consumption.
[I've done this before on my PC's speaker, but it's now ruined, thanks to SMM/SMIs used by the BIOS and the chipset.]
For playing simple tones trough PWM you first need a driver circuit since the PIC cannot drive a speaker directly. Typically a push-pull is used as actively driving both high and low results in better speaker response. It also allows for a series capacitor, acting as a simple high-pass filter to protect the speaker from long DC periods.
This, for example, should work: http://3.bp.blogspot.com/-FFBftqQ0o8c/Tb3x2ouLV1I/AAAAAAAABIA/FFmW9Xdwzec/s400/sound.png
(source: http://electro-mcu-stuff.blogspot.be/ )
The PIC32 has hardware PWM that you can program to generate PWM at a specific frequency and duty cycle. The PWM frequency controls the tone, thus by changing the PWM frequency at intervals you can play simple music. The duty cycle affects the volume, but not linearly. High duty cycles come very close to pure DC and will be cut off by the capacitor, low duty cycles may be inaudible. Some experimentation is in order.
The link mentions timer interrupts because they are not talking about playing simple notes but using PWM + a low pass filter as a simple DAC to play real audio. In this case timer interrupts would be used to update the duty cycle with the next PCM sample to be played at regular intervals (the sampling rate).

Resources