Baudrate setting

Status
Not open for further replies.

lelox93

Active member
Why the serial communication baudrate (UART0) cannot be set?
Is there any way to unlock this?
I tried also by setting registers, but i did not succeed.
Code:
const int led = 13;
static volatile uint8_t  rx_buffer_head = 0;
static volatile uint8_t  rx_buffer_tail = 0;
static volatile uint8_t  tx_buffer_head = 0;
static volatile uint8_t  tx_buffer_tail = 0;
static volatile uint8_t  transmitting = 0;

void setup() {
  serial_begin_115200();
  pinMode(led, OUTPUT);
}

void loop() {
  delay(1000);
  Serial.write(0xC2);
  Serial.write(0xB5);
  Serial.write(0x0A);
  blinkLed(100);
}



void blinkLed(int delay_ms) {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(delay_ms);           // wait for some milliseconds
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
}

void serial_begin_115200(void)
{
  SIM_SCGC4 |= 0x0400;  // UART0 clock gate enabled
  rx_buffer_head = 0;
  rx_buffer_tail = 0;
  tx_buffer_head = 0;
  tx_buffer_tail = 0;
  transmitting = 0;
  PORTB_PCR16 = 0x0313; // configuration of RX pin
  PORTB_PCR17 = 0x0344; // configuration of TX pin

  // SBR([BDH BDL]) + (BRFA (C4[4:0]))/32 = (module_clock)/(16*Baudrate)
  // SBR([BDH BDL]) + (BRFA (C4[4:0]))/32 = (96000000)/(16*115200)
  // SBR([BDH BDL]) + (BRFA (C4[4:0]))/32 = 52.0833333
  // SBR = 52 = [b00000000 b00110100] = [0x00 0x36]
  // BRFA / 32 = 0.08333... -> ceil[BRFA] = 3 = b00000011 = 0x03
  UART0_BDH = 0x00 & 0x1F;
  UART0_BDL = 0x36 & 0xFF;
  UART0_C4 = 0x03 & 0x1F;

  UART0_C1 = 0x04;  // idle line type select
  UART0_TWFIFO = 2; // tx watermark, causes S1_TDRE to set
  UART0_RWFIFO = 4; // rx watermark, causes S1_RDRF to set
  UART0_PFIFO = 0x88; // FIFO Enable (TX & RX)
  UART0_C2 = 0x3C; // reciever full interrupt or DMA transfer enable
  // idle line interrupt enable
  // transmitter enable, reciever enable
  NVIC_SET_PRIORITY(45, 64);
  NVIC_ENABLE_IRQ(45);
}
I would like to have control over this.
Thank you, Leonardo
 
I would like to have a communication between teensy and LabVIEW VISA, which needs as parameters baudrate, parity bit ... so to me it's magic how LabVIEW receives data not knowing the baudrate.
My point is, if I send a message at 115200 bps, and I expect to receive a 9600 bps on LabVIEW I should not receive the correct data.
Instead Teensy ignores the baudrate setting (as told in many threads) and no-matter-which baudrate I set on LabVIEW I still receive data. I mean, this is not magic, there is something behind of course, but my project of data logging cannot rely on a non-clear full controlled serial communication.
I still need an explanation.
 
As far as I understand, it is the PC-Teensy USB interface will always be as fast as possible, independent of what Labview/teensy require.
this is also true for Teensy to say Putty terminal program. Baudrate setting in Putty are only relevant if you are using HW serial (i.e. true UARTS) and not USB. That PC does not differentiate USB-Serial from UART serial, is a PC issue, not a Teensy/Labview issue

If you NEED fixed data rate, use HW serial (e.g. Serial1) and set Baudrate.
 
Ok, and why in Arduino if you read in the serial monitor with a different baudrate of that one set in
Code:
Serial.begin(baudrate);
it reads wrong data?
 
Ok, and why in Arduino if you read in the serial monitor with a different baudrate of that one set in
Code:
Serial.begin(baudrate);
it reads wrong data?

I never use "Serial.begin". Maybe it is a legacy issue, without harm.
We are talking about Teensy 3.x and not Arduino boards or Teensy 2.x, right?
 
Yes I'm using Teensy3.2

If your PC has still an UART port and not UART to USB adapter, then I would use Serial1 or other HW Serial to generate Fixed rate Serial data.
Obviously, you may have fight PC internal Buffering.
Example: In earlier times, I encountered the situation that on a busy CPU (did some other display work) my GPS reading on UART was 1h behind true position.
 
Since on old outdated 8bit Arduino hardware, Serial was the single and only hardware UART, the Serial.begin(baudrate) has been kept for compatibility reasons to not break existing code.
But on the Teensy processors, Serial maps to a virtual UART over USB which communicates with the computers virtual COM ports, mapped to USB by the OS (be it Linux, macOs, or worst case Windows). Thus, the real communication speed of these virtual com ports depends on how the OS implement and handle these. The Teensy will always try to send data at the maximal USB speed (12MBit/s).
 
Maybe this lengthy explanation I wrote some time ago about how serial communication works can help?

https://forum.pjrc.com/threads/4626...not-responding?p=152868&viewfull=1#post152868

Regarding this question:

why in Arduino if you read in the serial monitor with a different baudrate of that one set in

Only some Arduino boards, like Uno & Mega (the most popular ones), actually use the baud rate. Those boards have a dedicated chip which turns USB into actual hardware serial communication, using the baud rate you set in the serial monitor.

Other Arduino boards, like Leonardo, Micro, MKR1000 have native USB serial. When using those boards, the baud rate is ignored and communication always happen at the full USB speed, exactly the same way as Teensy (well, except their drivers may not be as efficient as the code on Teensy....)

Some Arduino boards, like Zero and Due, actually have 2 USB ports. Arduino calls them "Native" and "Programming". On those Arduino boards, the native port always ignores the baud rate and works the same way as Teensy, at full USB speed. The programming port on those boards does use the baud rate, and works the same way as Uno & Mega.


USB is a very sophisticated protocol with many complex details implemented in hardware and low-level drivers. When we talk of the virtual serial using 12 Mbit/sec speed, you should know what's actually happening involves quite a lot of extra stuff done by the USB protocol. You will not ever get 1.5 Mbyte/sec transfer (12 Mbit / 8 bits/byte) due to this overhead. The best case scenario is approx 1.1 to 1.2 Mbyte/sec.

One of the many great things all that USB overhead does is true end-to-end flow control. Conceptually it's similar to RTS/CTS flow control for actual hardware serial, but no extra wires are used. Unlike RTS/CTS, you can't turn it on/off (and because it's not configurable, few people even really know this exists). It's all part of the complex USB protocol running in the drivers and hardware. The net result is both Teensy and your PC will automatically detect how fast the other side is capable of actually using the incoming data and pace themselves to send at that speed. This is very valuable, since it means you won't lose data, like you could with regular serial when the baud rate is too fast.

Some PC-based software, especially Labview, has a tremendous amount of overhead and can not handle very fast data. While the USB will prevent data loss, it will not protect you from sending far too much data to a very heavy Labview system that consumes a tremendous amount of CPU usage on your computer. Several people have run into this with Teensy and Labview. You might not imagine a 64 bit, 3+ GHz CPU with gigabytes of RAM at its disposal would be the limiting factor, but with certain software (especially Labview) the PC side can really bog down and run very slowly. For Labview use, I recommend having Teensy send data at a very slow rate while writing & testing your code, perhaps only 1 or 2 pieces of data per second. Get your Labview side working properly, and then only increase the speed on Teensy when you know the Labview side is working properly.
 
Status
Not open for further replies.
Back
Top