Accuracy of STM32L496 generated square wave - stm32

I have an STM32L496 MCU, and I want to generate a 3MHz square wave. I would like to know what would be the accuracy of this signal.
The system clock frequency of this MCU is 80MHz. If I use a prescaler of 80MHz / 3MHz = 26.667 (can I do that?), then the timer will tick at a rate of 3MHz. If I use a 16-bit timer (TIMER16), it would count to 65 535 maximum, which means it would increment once every 0.33 microseconds.
That is how far I understood, but I am not sure how to calculate the accuracy of this signal. Any help would be much appreciated!

If the core is 80MHz you can't make 3MHz exactly with a timer clocked from the same source as the core.
You can make 3.076923 MHz with even mark space ratio (prescaler 1, compare value 13 reset value 26), or you can make 2.962962 MHz (which is slightly closer) with a 13:14 mark space ratio (prescaler 1, compare value 13 or 14, reset value 27).
To get 3MHz you would have to underclock your core down to 78MHz.
I don't know the exact part you are using. You might be able to get it exactly using one of the clock outputs or a PLLs other than the one that drives the core, eg: if you have a 12MHz crystal you can output 3MHz easily on an MCO pin.

Related

STM32 generate 22Mhz clock on gpio out from SystemCoreClock 110Mhz

I want to generate clock for PCA9959 LED driver with my STM32L552. The LED driver needs an external clock at 20 MHz (+/- 15%). I'm trying to generate a 22 MHz clock on port PA8 on STM32L552. I managed to generate a PWM on port PA8, but I can't reach the frequency of ~22Mhz. I arrive at a maximum of 8Mhz.
Here are the PWM parameters:
I'm not sure I filled in the pwm parameters correctly. Normally with his settings I guess I should have a 22 MHz PWM with a 20% duty cycle.
PWM (MHz) = SystemCoreClock (MHz) / Prescaler => 22MhZ = 110MHz / 5
My clock configuration:
Thanks for your help.
The easiest way to output a high speed clock like this is with the MCO peripheral, rather than a timer. Fortunately for you the MCO pin is PA8. Perhaps the person who designed your board knew this and intended you to use MCO. Read the reference manual to see how.
If you do want to use a timer to do 22MHz, then as you have correctly identified you cannot get a 50% duty-cycle on your PWM. I would recommend starting with a 40% or 60%, with an output-compare value of 2-out-of-5 or 3-out-of-5, not 1 as you have above.
There is no detail in the PCA9959 datasheet about what the required mark-space ratio of the clock is, but I guess anything other than 50% could be a problem. You would be better to divide the clock by an even number. Either just divide 110MHz by 6 and output 18.33MHz, or else slow your core down a bit and divide by 4 (reduce the N parameter of your PLL).
Whether you use MCO or PWM don't forget to set the GPIO pin mode to the fastest slew rate available. Maybe the 8MHz you are measuring is the result of aliasing a faster clock that has been through the wrong GPIO mode. You could test this using a scope with at least 100MHz bandwidth.

HC-SR-04 with STM32

SR04 ultrasonic distance sensor with stm32.
When I use it with STM32 I use it as bothedge with input capture. I measure the HIGH time of the Echo pin.
I thought it was a mistake
When I used Ardiuno with pulsein, I was dividing the time by 29.1 .My measurement was accurate enough, but when I divide it by 29.1 when using STM32, the measurement is very wrong. I did it by dividing by 58.2. This time I got more accurate values. What is the difference?
Thanks a lot.
It's right to divide the duration of the echo pulse by 58, as described in the datasheet as follows.
You can calculate the range through the time interval between sending trigger signal and
receiving echo signal. Formula: uS / 58 = centimeters or uS / 148 =inch; or: the
range = high level time * velocity (340M/S) / 2;
I tried to find an Arduino code which divides pulse duration with 29.1 or 29, I couldn't find it. Some posts computes the range by range=(duration/2)/29.1. I guess you've missed dividing duration by two. Double check your Arduino code, or post it if you want to be assured.

How to detect ultrasonic range sensor is out of range or not?

I am using jsn-srf04t ranging sensor (25cm to 5m range) I want to know when it is going out of range(when under 25cm)
The problem is when it goes under 25 cm, the sensor output sometimes goes to (90cm to 95cm or 100cm to 120cm) and this cause undetectability of that it is really out of range or not!
Is there any solution?
This question is not directly related, but I thought I post a suggestion/answer anyway.
SRF04's can detect the distances as small as 3 cms. Please measure the width of the output echo pulse using an oscilloscope. It can be from 100uS to 18mS and if there is no object within its range, the echo pulse is 36ms.
If the measured pulse width from the oscilloscope is agreeing with what you say, then presumably the SRF04 is faulty, or there is a problem with its mounting etc.
If the width of the pulse is measured in uS, then dividing by 58 will give you the distance in cm, or dividing by 148 will give the distance in inches.
The SRF sensors can be triggered as fast as every 50mS, or 20 times each second. You should wait 50ms before the next trigger to ensure the ultrasonic "beep" has faded away and will not cause a false echo on the next ranging.
Otherwise, check your timer configuration. Ensure that it can measure a pulse in the order of hundreds of microseconds with at least a resolution of tens of microseconds.
If you are using this, then perhaps you are at the lowest possible level.

Why In Manchester encoding, the bit rate is half of the baud rate?

I think baud rate is the rate of the symbols, and if each symbol contains n bit, then the bit rate should be n x baud rate
In Ethernet( Manchester encoding) ,if bit rate is half of the baud rate, then a symbol contains 1/2 bit ? As far as I know, bit rate should at least not less than symbol rate (baud rate).
About the relationship of baud rate and bit rate, my understanding have no problems, yet when it comes to the Manchester code, it's totally counterintuitive, could anyone explain about these?
Bit rate is related to the speed of the transmission of the digital bit, while baudrate is related to the speed of change of symbols, which are significancies in analog signal. These can be either in amplitude, frequency or phase or more complex modulation methods. In manchester encoding, one bit is reprsented by two different levels of voltage. Therefore, lets say if you want to transfer 1Mbit digital data in one second, then you will need to make ~ 2 million changes in the level of the analogous signal. That is why, your bit rate will be 1Mbs, while your baud rate will be 2M bauds.
In NRZ encoding, one bit is represented by one symbol. Therfore rates will be equal.
The Wikipedia article for Baud says that it can be defined as pulses per second. In the case of Manchester Encoding, this results in the baud rate being defined as "clock transitions".
A transition is what occurs when the signaling voltage goes from a low voltage to a high voltage, or vice versa. If you look at this diagram:
You will notice that the Manchester wave always makes a transition from either low to high or high to low when the clock transitions from high to low. The bits are encoded in that transition; a transition from low to high indicates a 1, and a transition from high to low indicates a 0. The low-to-high clock transitions are used to get the Manchester wave in a position where it can make the correct transition for the next bit. As you can see, there are never more than two clock transitions between one Manchester transition and the next; the clock is effectively encoded in the Manchester wave itself.
If the bits were encoded in a single clock transition (i.e. high being 1 and low being 0), then the clock (baud) rate and the bit rate would be the same, but then you would have to run a separate line for the clock. Because Manchester guarantees a transition every
You can think of Manchester encoding not only transmitting the actual data, but also the clock (meta data) due to its self clocking characteristic.
http://en.wikipedia.org/wiki/Self-clocking_signal
All you need to understand is that WITHIN any ONE state in Manchester encoding ( i.e either 1 or 0 )
there would be a transition . . as depicted in DIAGRAM above. . .the sole reason for transition
being for reciever to synchronize
This being said, it means if we compare this encoding scheme to others. . Like NRZ. there would be double the transitions in manchester encoding as compared to other techniques ( for a sequence of 10101
manchester will have 10 transitions while NRZ would have 5 ). . there may be exceptions. This means baud rate for manchester would be 10 while for NRZ would be 5. .
In designing we use to say that if any recvr is capable of syncing to baud rate of 10 . . . that means with manchester it transmts five Bits while with NRZ it would transmit 10 bis

Sine LUT VHDL wont simulate below 800 hz

I made a sine LUT for VHDL, using 256 elements.
Im using MIDI input, so values range 8.17Hz (note #0) to 12543.85z (note #127).
I have another LUT that calculates how many value must be sent to my 48 kHz codec in order to play the sound (the 8.17Hz frequency will need 48000/8.17 = 5870 values).
I have another LUT that contains an index factor, which is 256/num_Values, which is used to call values from the sin table (ex: 100*256/5870 = 4 (with integer rounding)).
I send this index factor to another VHDL file, which is used to calculate which value should be sent back. (ex: index = index_factor*step_counter)
When I get this index, I divide it by 100, and call sineLUT[index] to get the value that I need to generate a sine wave at the desired frequency.
The problem is, only the last 51 notes seem to work for me, and I do not know why. It seems to get stuck on a constant note at anything below that frequency (<650 hz) , and just decrease in volume every time I try to lower the note.
If you need parts of my code, let me know.
Just guessing, I suspect your step_counter isn't going through enough cycles, so your index (into the sine lut) doesn't go through a full 360 degrees for the lower frequencies.
For anything more helpful, you'll probably have to post code.
As an aside, why aren't you using something more like a conventional DDS? Analog Devices has a nice write-up on the basics: DDS Tutorial