stm32: PWM generator with 1/20 pulses - timer

I'm struggeling on setting up a STM32-F429ZI MCU (Nucleo 144 board) to generate following PWM pattern:
First channel with a variable frequency and 50% duty cycle - at least I've got this working -
Second channel giving a pulse with each 20th pulse of channel 1.
This is not primary a coding problem but a understanding problem of timer settings i guess (working with STM32CubeIDE). I would bet there is real simple solution...
I Think there is no way to do this with only 1 timer?
I'm pleased for any suggestion...
I already tried with TIM2 as clock source for TIM3 and 4 but couldn't manage to make them synchonize.
For better illustration of what I want to do:

I't not sure, if it could be done with two timer synchronization (the pitfall is variable frequency of the first timer). But you can use single timer+DMA to rewrite configuration of the second channel:
Create in-memory array of 20 values, where one value enables the second channel and other 19 disables it
Setup DMA to trigger on the timer update and to move data from the array to CCMRx (or CCRx) register. Of cource, DMA should be in circular mode

Related

Increase count value of hardware timer (on µC) more than one at each timer tick

Has anyone heard of a hardware-timer which can count by different values with one timer tick?
Normally a timer of a µC counts up or down by one. But I have a challenge where I need to add e.g. 500 each timer tick.
There are multiple options for your question. Depending on your microcontroller and timer you could:
Use the interrupt generation of the timer to manually up a variable by a set amount. 500 in your case.
Change the timer prescalers such that instead of 500 times in an expected period, the timer only triggers once during the expected period.
I personally don't know of a timer that has a variable increase amount but that doesn't mean that it doesn't exist. Maybe creating such a timer in VHDL or verilog may be a option.

Control WVGA display with stm32f429-discovery LTDC

I am trying to output some data on the 7 inch TFT-LCD display (MCT070PC12W800480LML) using LCD-TFT display controller (LTDC 18 bits) on STM32F4.
LTDC interface setting are configured in CubeMx. In the program lcd data buffer is created with some values and it's starting address is mapped to the LTDC frame buffer start address.
At this moment display doesn't react to data sent by the LTDC. It only shows white and black strips, after i connect ground and power for digital circuit to the 3 volts source. VLED+ is connected to the 9 volts source. The VSYNC, HSYNC and CLOCK signals are generated by the LTDC and they match with specified values. I measured them on LCD strip, so the connection should be right. I also tried putting pulse on the LCD reset pin, but that doesn't make any sense.
The timing setting might be wrong.
LTDC clock is 33 MHz.
Here is the link to the diplay datasheet http://www.farnell.com/datasheets/2151568.pdf?_ga=2.128714188.1569403307.1506674811-10787525.1500902348 I saw some other WVGA displays using the same timing for synchronization signals, so i assume that timings are standard for that kind of displays.
Maybe signal polarity is wrong or i am missing something else. The program i am using now, worked on stm32f429-discovery build in LCD i just changed the timings. Any suggestions?
Thank you.
It could be something else, but I can see a problem with your timing values.
The back porch for both horizontal and vertical includes the sync pulses, but there must be a sync pulse width. My observation is that you have tried to get the total clocks for h = 1056 and v = 525 as per the data sheet by setting the sync pulses to 0. That won't work.
I would make the hsync pulse 20 and vysnc 10. The total clocks will be the same, but it is not critical that they match the spec sheet.

Stm32 PWM sampling

I have a timer set up in the cube to make a PWM... Just setting ARR and CCR to different values.
I'm using the callback functions for both events that HAL set up for me, I think one is for the CCR compare event and the other is for the ARR compare event.
Anyway, in both of those I'm toggling a GPIO port like this:
GPIOC->ODR = foo;
Anyway, I want to sample the values of 3 ADC1 channels during the high pulse, but I'm not sure how to do that accurately. I'm using DMA in circular mode with the ADC1 right now.
I don't want to sample immediately after setting the pins, because there's propagation delay, noise, etc.
So, I want to:
Set the pins, wait a very short and constant amount of time, sample all the channels and then do some math on the results.
This is for a Bldc motor controller, by the way... Im trying to sample the BEMF on the positive side of the PWM drive signal, and I'm driving it at 18khz, 5% duty cycle, so my pulse lasts for 2.7us.
I'm not sure how to handle or debug this because it's so timing related and I need the motor to deliver the signal that I'm using... If the motor isn't spinning, then there's no feedback signal to work on. It sure seems like I'm trying to do too much in the timer ISRs, though.
Sorry I can't post any code right now... Im at the grocery store, but I'll put some up when I get back.

STM32 - TIM2_ETR pin, connected to pin PA0 (button), incrementing the timer in strange way

I am trying to implement PWM LED dimming in 6 stages, where each stage in more bright, based on clicking button, which increments external pin, which serves the value to timer.
I am facing a problem, that sometimes, value variable is too large than it should be and skips some levels of brightness. For example, value increments: 1,2,3, then jumps to 6,7, etc.
Can anybody pinpoint where is the mistake I am making.
Here is the code:
//EDIT: code removed, because it is a school assignment
This looks like contact bouncing. When input is processed by the CPU, a simple way to solve it is to disable input for a certain duration after an event is detected. Since you directly control timer input from a button, you may not have much control. However, I would experiment with the ETF field of the SMCR register (which in your case is likely set by the sClockSourceConfig.ClockFilter field) and the clock divisor CKD of the CR1 register (which seems like htim2.Init.ClockDivision in your code) (sorry, I am not familiar with STM libraries).

Programming Timer0 on PIC16F882 for a value greater than maximum PRESCALER

I'm using the PIC16F88X which has a 200ns internal clock period and I want to program the TIMER0 to make 4 measurements per second.
According to microchip tutorial on programming timer 0 (page 10) I can use PS0, PS1 and PS2 to assign TMR0 RATE to 1:256 but this only makes my clock period scale to 51,2 micro seconds.
There is also the possibility to program an initial value for TMR0 but I don't think it will affect the clock I want to reach. Is there anything on the big picture that I'm missing?
It is expected that timer prescaler can't cover any range that user may want. In order to achieve larger intervals you have to add additional logic in yours timer interrupt routine. Basically you have to add additional variable/counter which you have to increment, let's say on 50us (you will tune timer from 51,2us to 50us by adding initial value to TMR0). When your counter reaches 5000 then you have wanted 1/4s resolution.
Hope it helps...
Looking at the specification sheet (http://ww1.microchip.com/downloads/en/DeviceDoc/41291D.pdf) page 76 we see that the timer1 available on this micro-controller is 16bit and has up to 8 pre-scaler. My own approach would be to use timer1 with a prescaller of 8. Without seeding the value manually, this gives :
<osc speed>/(4*<prescaller>*2^16)
5MHz/(4*8*2^16) = 2.38Hz
To get exactly 4Hz, you can seed the counter on every rollover to a value of :
2^16-<osc speed>/(<desired speed>*4*<prescaller>)
2^16-5MHz/(4Hz*4*8) = 26474

Resources