Can I change OCR1B on the fly? - timer

I want to solve a very particular problem with an Arduino, running on a ATmega328
I have timer1 run in fast PWM mode for generating a PWM Signal with given Period an duty cycle. The duty cycle is set by OCR1A: So at timer restart the level of the output pin gets high and after the duty period it gets low. This works.
Additionally I want to carry out an analog measurement exactly some time after the rising signal. So I enabled the OCR1B interrupt and define the time by writing to OCR1B. When the timer reaches the value in OCR1B the interrupt handler is invoked and the measurement done. This works.
Now I want to do this ADC conversion twice at different counter times, say my_OCRB1 and my_OCRB2. But there is only on OCR1B Register I can use. Is it ok to prepare the content of OCR1B to the next value my_OCRB2 after the first ADC conversion at is finished? Will it work and again rise an interrupt, when the timer is still counting up?
Is there a better solution?

Related

STM32: How to configure timer to trigger interrupt in every increments in quadrature encoder mode?

I have a rotary encoder with STM32F4 and configured TIM4 in "Encoder Mode TI1 and TI2". I want to have an interrupt every time the value of timer is incremented or decremented.
The counting works but I only can configure an interrupt on every update event, not every changes in TIM4->cnt. How can I do this?
In other words: My MCU+Encoder in quadrature mode could count from 0 to 99 in one revolution. I want to have 100 interrupts in the revolution but if I set TIM4->PSC=0 and TIM4->ARR=1, results 50 UPDATE_EVENTs, so I should set ARR=0 but it does not work. How can I sole that?
To get 100 interrupts per revolution keep PSC=0, ARR=1, setup the two timer channels in output compare mode with compare values 0 and 1 and interrupts on both channels.
Or even use ARR=3 and setup all four channels, with compare values of 0,1,2 and 3. This will allow to detect the direction.
Normally, the whole point of using the quadrature encoder mode is counting the pulses while avoiding interrupts. You can simply poll the counter register periodically to determine speed and position.
Getting interrupts on every encoder pulse is extremely inefficient, especially with high resolution encoders. Yours seems to be a low resolution one. If you still think you need them for some reason, you can connect A & B into external interrupts and implement the counting logic manually. In this case, you don't need quadrature encoder mode.

How to synchronize two timers on PIC16F1827

I just got into PIC-programming on Microchips MPLAB X IDE. My programm requires two timers. TMR4 has an interrupt interval of 500ms and TMR2 interrupts every second. When starting the program, the two timers are synced up, so within a small margin of error, when the TMR4 interrupts for the second time, TMR2 also executes the interrupt code. But when I stop TMR2 for a period of time and then start it again, the two timers are completely out of Sync.
Is there a way to resynchronize the two timers or to restart them?
Why are you stopping the timers?
There is no need to be stopped when interrupt happened. TMR2 and TMR4 are functional identical. When the interrupt is triggered the TMR2IF or TMR4IF is set. If also set TMR2IE or TMR4IE then the interrupt is triggered.
The registers PR2 and PR4 (also prescaler) must be set according to desired frequency. The value of TMR2 or TMR4 is compared to that of the period register, PR2 or PR4, on
each clock cycle. When the two values match, the comparator generates a match signal as the timer output and trigger interrupt, TMR2IF or TMR4IF is set. If also set TMR2IE or TMR4IE then the interrupt is triggered. This signal also resets the value of TMR2 orTMR4 counters to 0 and timers continue running. When you finish your interrupt program just clear TMR2IF or TMR4IF to enable next timer interrupt.
If you wont to resynchronize the timer then just reset the TMR2 and TMR4 registers value to 0. If you wont to resynchronize in main program then first disable interrupts clear TMR2 and TMR4 and enable interrupts again.

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.

ARMv7 stm32-L476G How to set a specific pitch of sound to play for a specific duration

I am new to ARMv7 assembly programming (using the stm32-L476G) and I am lost on how to produce a specific-pitched sound (e.g 110 hz) to play for 15 seconds. I have done my research and reached a dead end. Can anybody help me?
method A
Configure the timer to generate 110Hz PWM 50% signal.
Configure another timer to overflow after 15 seconds.
In the second timer interrupt deactivate the PWM signal generation by the first timer
method B
1 configure the timer to overflow every 1/220 sec.
In the timer interrupt toggle the pin
count the number the interrupts when the number reaches the 220*15 disable timer
method C
1 create the sine tabue table in the memory.
confiure the timer to trigger DMA transfer to DAC every
1/(110*nsamples_per_period)
configure DMA in the circular mode
in the DMA end transfer interrupt increase the counter
when the counter is >= 110*15 disable the triggering timer

Timer reading when postscalar turned ON

I have read that the postscalar of a timer specifies how many times the counter has to overflow inorder to get an interrupt.
But i have a doubt there.
So what i understand is if i put 0x55 and start timer with postscalar as 2, then timer will count from 0x55 to 0xFF and then again 0x55 to 0xFF and generate an interrupt.
Consider a case that i start the timer in an external inetrrupt. My requyirement may be to get the timegap between two interrupt. I start the timer in first interrupt, then read the timer in the next interrupt.
but if i have put postscalar then i will get the wrong time right.
I just used this as an example to make my question clear.
Edit: So will there be any issue if a timer value is read when postscalar turned ON
Usage Context: To get time difference between two interrupts
No. PostScale - Pre-Scale divide the clock input/output so you can sample at lower frequencies or intervals, depending on the application where you need more count than available. Let's say you have a XTAl of 8MHz with a Pre-Scaler of 1:8 (found on many PICS), you won't sample at 8MHz but at 1MHz.
Addind a pre-scaler - Post-Scaler will change the time between your 2 interrupts, surely. But that won't affect the reading of the counter value, assuming you count a variable each time there's one of the 2 interrupts on. You will simply count slower, or faster, depending on which timer you are using (most of them only have a pre-scaler option).

Resources