<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn">
		<id>http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=HardwareSerial.cpp</id>
		<title>HardwareSerial.cpp - 版本历史</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=HardwareSerial.cpp"/>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=HardwareSerial.cpp&amp;action=history"/>
		<updated>2026-05-14T11:39:45Z</updated>
		<subtitle>本wiki的该页面的版本历史</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://wiki.ywrobot.net/index.php?title=HardwareSerial.cpp&amp;diff=61&amp;oldid=prev</id>
		<title>YWrobot WM：创建页面，内容为“&lt;pre style=&quot;color:blue&quot;&gt; /*   HardwareSerial.cpp - Hardware serial library for Wiring   Copyright (c) 2006 Nicholas Zambetti.  All right reserved.    This library is...”</title>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=HardwareSerial.cpp&amp;diff=61&amp;oldid=prev"/>
				<updated>2016-04-25T02:01:50Z</updated>
		
		<summary type="html">&lt;p&gt;创建页面，内容为“&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt; /*   HardwareSerial.cpp - Hardware serial library for Wiring   Copyright (c) 2006 Nicholas Zambetti.  All right reserved.    This library is...”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
  HardwareSerial.cpp - Hardware serial library for Wiring&lt;br /&gt;
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.&lt;br /&gt;
&lt;br /&gt;
  This library is free software; you can redistribute it and/or&lt;br /&gt;
  modify it under the terms of the GNU Lesser General Public&lt;br /&gt;
  License as published by the Free Software Foundation; either&lt;br /&gt;
  version 2.1 of the License, or (at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
  This library is distributed in the hope that it will be useful,&lt;br /&gt;
  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
  Lesser General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
  You should have received a copy of the GNU Lesser General Public&lt;br /&gt;
  License along with this library; if not, write to the Free Software&lt;br /&gt;
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA&lt;br /&gt;
  &lt;br /&gt;
  Modified 23 November 2006 by David A. Mellis&lt;br /&gt;
  Modified 28 September 2010 by Mark Sproul&lt;br /&gt;
  Modified 14 August 2012 by Alarus&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#include &amp;quot;Arduino.h&amp;quot;&lt;br /&gt;
#include &amp;quot;wiring_private.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// this next line disables the entire HardwareSerial.cpp, &lt;br /&gt;
// this is so I can support Attiny series and any other chip without a uart&lt;br /&gt;
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;HardwareSerial.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * on ATmega8, the uart and its bits are not numbered, so there is no &amp;quot;TXC0&amp;quot;&lt;br /&gt;
 * definition.&lt;br /&gt;
 */&lt;br /&gt;
#if !defined(TXC0)&lt;br /&gt;
#if defined(TXC)&lt;br /&gt;
#define TXC0 TXC&lt;br /&gt;
#elif defined(TXC1)&lt;br /&gt;
// Some devices have uart1 but no uart0&lt;br /&gt;
#define TXC0 TXC1&lt;br /&gt;
#else&lt;br /&gt;
#error TXC0 not definable in HardwareSerial.h&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Define constants and variables for buffering incoming serial data.  We're&lt;br /&gt;
// using a ring buffer (I think), in which head is the index of the location&lt;br /&gt;
// to which to write the next incoming character and tail is the index of the&lt;br /&gt;
// location from which to read.&lt;br /&gt;
#if (RAMEND &amp;lt; 1000)&lt;br /&gt;
  #define SERIAL_BUFFER_SIZE 16&lt;br /&gt;
#else&lt;br /&gt;
  #define SERIAL_BUFFER_SIZE 64&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
struct ring_buffer&lt;br /&gt;
{&lt;br /&gt;
  unsigned char buffer[SERIAL_BUFFER_SIZE];&lt;br /&gt;
  volatile unsigned int head;&lt;br /&gt;
  volatile unsigned int tail;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#if defined(USBCON)&lt;br /&gt;
  ring_buffer rx_buffer = { { 0 }, 0, 0};&lt;br /&gt;
  ring_buffer tx_buffer = { { 0 }, 0, 0};&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRRH) || defined(UBRR0H)&lt;br /&gt;
  ring_buffer rx_buffer  =  { { 0 }, 0, 0 };&lt;br /&gt;
  ring_buffer tx_buffer  =  { { 0 }, 0, 0 };&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRR1H)&lt;br /&gt;
  ring_buffer rx_buffer1  =  { { 0 }, 0, 0 };&lt;br /&gt;
  ring_buffer tx_buffer1  =  { { 0 }, 0, 0 };&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRR2H)&lt;br /&gt;
  ring_buffer rx_buffer2  =  { { 0 }, 0, 0 };&lt;br /&gt;
  ring_buffer tx_buffer2  =  { { 0 }, 0, 0 };&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRR3H)&lt;br /&gt;
  ring_buffer rx_buffer3  =  { { 0 }, 0, 0 };&lt;br /&gt;
  ring_buffer tx_buffer3  =  { { 0 }, 0, 0 };&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
inline void store_char(unsigned char c, ring_buffer *buffer)&lt;br /&gt;
{&lt;br /&gt;
  int i = (unsigned int)(buffer-&amp;gt;head + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
&lt;br /&gt;
  // if we should be storing the received character into the location&lt;br /&gt;
  // just before the tail (meaning that the head would advance to the&lt;br /&gt;
  // current location of the tail), we're about to overflow the buffer&lt;br /&gt;
  // and so we don't write the character or advance the head.&lt;br /&gt;
  if (i != buffer-&amp;gt;tail) {&lt;br /&gt;
    buffer-&amp;gt;buffer[buffer-&amp;gt;head] = c;&lt;br /&gt;
    buffer-&amp;gt;head = i;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#if !defined(USART0_RX_vect) &amp;amp;&amp;amp; defined(USART1_RX_vect)&lt;br /&gt;
// do nothing - on the 32u4 the first USART is USART1&lt;br /&gt;
#else&lt;br /&gt;
#if !defined(USART_RX_vect) &amp;amp;&amp;amp; !defined(USART0_RX_vect) &amp;amp;&amp;amp; \&lt;br /&gt;
    !defined(USART_RXC_vect)&lt;br /&gt;
  #error &amp;quot;Don't know what the Data Received vector is called for the first UART&amp;quot;&lt;br /&gt;
#else&lt;br /&gt;
  void serialEvent() __attribute__((weak));&lt;br /&gt;
  void serialEvent() {}&lt;br /&gt;
  #define serialEvent_implemented&lt;br /&gt;
#if defined(USART_RX_vect)&lt;br /&gt;
  ISR(USART_RX_vect)&lt;br /&gt;
#elif defined(USART0_RX_vect)&lt;br /&gt;
  ISR(USART0_RX_vect)&lt;br /&gt;
#elif defined(USART_RXC_vect)&lt;br /&gt;
  ISR(USART_RXC_vect) // ATmega8&lt;br /&gt;
#endif&lt;br /&gt;
  {&lt;br /&gt;
  #if defined(UDR0)&lt;br /&gt;
    if (bit_is_clear(UCSR0A, UPE0)) {&lt;br /&gt;
      unsigned char c = UDR0;&lt;br /&gt;
      store_char(c, &amp;amp;rx_buffer);&lt;br /&gt;
    } else {&lt;br /&gt;
      unsigned char c = UDR0;&lt;br /&gt;
    };&lt;br /&gt;
  #elif defined(UDR)&lt;br /&gt;
    if (bit_is_clear(UCSRA, PE)) {&lt;br /&gt;
      unsigned char c = UDR;&lt;br /&gt;
      store_char(c, &amp;amp;rx_buffer);&lt;br /&gt;
    } else {&lt;br /&gt;
      unsigned char c = UDR;&lt;br /&gt;
    };&lt;br /&gt;
  #else&lt;br /&gt;
    #error UDR not defined&lt;br /&gt;
  #endif&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(USART1_RX_vect)&lt;br /&gt;
  void serialEvent1() __attribute__((weak));&lt;br /&gt;
  void serialEvent1() {}&lt;br /&gt;
  #define serialEvent1_implemented&lt;br /&gt;
  ISR(USART1_RX_vect)&lt;br /&gt;
  {&lt;br /&gt;
    if (bit_is_clear(UCSR1A, UPE1)) {&lt;br /&gt;
      unsigned char c = UDR1;&lt;br /&gt;
      store_char(c, &amp;amp;rx_buffer1);&lt;br /&gt;
    } else {&lt;br /&gt;
      unsigned char c = UDR1;&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(USART2_RX_vect) &amp;amp;&amp;amp; defined(UDR2)&lt;br /&gt;
  void serialEvent2() __attribute__((weak));&lt;br /&gt;
  void serialEvent2() {}&lt;br /&gt;
  #define serialEvent2_implemented&lt;br /&gt;
  ISR(USART2_RX_vect)&lt;br /&gt;
  {&lt;br /&gt;
    if (bit_is_clear(UCSR2A, UPE2)) {&lt;br /&gt;
      unsigned char c = UDR2;&lt;br /&gt;
      store_char(c, &amp;amp;rx_buffer2);&lt;br /&gt;
    } else {&lt;br /&gt;
      unsigned char c = UDR2;&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(USART3_RX_vect) &amp;amp;&amp;amp; defined(UDR3)&lt;br /&gt;
  void serialEvent3() __attribute__((weak));&lt;br /&gt;
  void serialEvent3() {}&lt;br /&gt;
  #define serialEvent3_implemented&lt;br /&gt;
  ISR(USART3_RX_vect)&lt;br /&gt;
  {&lt;br /&gt;
    if (bit_is_clear(UCSR3A, UPE3)) {&lt;br /&gt;
      unsigned char c = UDR3;&lt;br /&gt;
      store_char(c, &amp;amp;rx_buffer3);&lt;br /&gt;
    } else {&lt;br /&gt;
      unsigned char c = UDR3;&lt;br /&gt;
    };&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
void serialEventRun(void)&lt;br /&gt;
{&lt;br /&gt;
#ifdef serialEvent_implemented&lt;br /&gt;
  if (Serial.available()) serialEvent();&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef serialEvent1_implemented&lt;br /&gt;
  if (Serial1.available()) serialEvent1();&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef serialEvent2_implemented&lt;br /&gt;
  if (Serial2.available()) serialEvent2();&lt;br /&gt;
#endif&lt;br /&gt;
#ifdef serialEvent3_implemented&lt;br /&gt;
  if (Serial3.available()) serialEvent3();&lt;br /&gt;
#endif&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#if !defined(USART0_UDRE_vect) &amp;amp;&amp;amp; defined(USART1_UDRE_vect)&lt;br /&gt;
// do nothing - on the 32u4 the first USART is USART1&lt;br /&gt;
#else&lt;br /&gt;
#if !defined(UART0_UDRE_vect) &amp;amp;&amp;amp; !defined(UART_UDRE_vect) &amp;amp;&amp;amp; !defined(USART0_UDRE_vect) &amp;amp;&amp;amp; !defined(USART_UDRE_vect)&lt;br /&gt;
  #error &amp;quot;Don't know what the Data Register Empty vector is called for the first UART&amp;quot;&lt;br /&gt;
#else&lt;br /&gt;
#if defined(UART0_UDRE_vect)&lt;br /&gt;
ISR(UART0_UDRE_vect)&lt;br /&gt;
#elif defined(UART_UDRE_vect)&lt;br /&gt;
ISR(UART_UDRE_vect)&lt;br /&gt;
#elif defined(USART0_UDRE_vect)&lt;br /&gt;
ISR(USART0_UDRE_vect)&lt;br /&gt;
#elif defined(USART_UDRE_vect)&lt;br /&gt;
ISR(USART_UDRE_vect)&lt;br /&gt;
#endif&lt;br /&gt;
{&lt;br /&gt;
  if (tx_buffer.head == tx_buffer.tail) {&lt;br /&gt;
	// Buffer empty, so disable interrupts&lt;br /&gt;
#if defined(UCSR0B)&lt;br /&gt;
    cbi(UCSR0B, UDRIE0);&lt;br /&gt;
#else&lt;br /&gt;
    cbi(UCSRB, UDRIE);&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // There is more data in the output buffer. Send the next byte&lt;br /&gt;
    unsigned char c = tx_buffer.buffer[tx_buffer.tail];&lt;br /&gt;
    tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
	&lt;br /&gt;
  #if defined(UDR0)&lt;br /&gt;
    UDR0 = c;&lt;br /&gt;
  #elif defined(UDR)&lt;br /&gt;
    UDR = c;&lt;br /&gt;
  #else&lt;br /&gt;
    #error UDR not defined&lt;br /&gt;
  #endif&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#ifdef USART1_UDRE_vect&lt;br /&gt;
ISR(USART1_UDRE_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (tx_buffer1.head == tx_buffer1.tail) {&lt;br /&gt;
	// Buffer empty, so disable interrupts&lt;br /&gt;
    cbi(UCSR1B, UDRIE1);&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // There is more data in the output buffer. Send the next byte&lt;br /&gt;
    unsigned char c = tx_buffer1.buffer[tx_buffer1.tail];&lt;br /&gt;
    tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
	&lt;br /&gt;
    UDR1 = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#ifdef USART2_UDRE_vect&lt;br /&gt;
ISR(USART2_UDRE_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (tx_buffer2.head == tx_buffer2.tail) {&lt;br /&gt;
	// Buffer empty, so disable interrupts&lt;br /&gt;
    cbi(UCSR2B, UDRIE2);&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // There is more data in the output buffer. Send the next byte&lt;br /&gt;
    unsigned char c = tx_buffer2.buffer[tx_buffer2.tail];&lt;br /&gt;
    tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
	&lt;br /&gt;
    UDR2 = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#ifdef USART3_UDRE_vect&lt;br /&gt;
ISR(USART3_UDRE_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (tx_buffer3.head == tx_buffer3.tail) {&lt;br /&gt;
	// Buffer empty, so disable interrupts&lt;br /&gt;
    cbi(UCSR3B, UDRIE3);&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // There is more data in the output buffer. Send the next byte&lt;br /&gt;
    unsigned char c = tx_buffer3.buffer[tx_buffer3.tail];&lt;br /&gt;
    tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
	&lt;br /&gt;
    UDR3 = c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Constructors ////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,&lt;br /&gt;
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,&lt;br /&gt;
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,&lt;br /&gt;
  volatile uint8_t *ucsrc, volatile uint8_t *udr,&lt;br /&gt;
  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)&lt;br /&gt;
{&lt;br /&gt;
  _rx_buffer = rx_buffer;&lt;br /&gt;
  _tx_buffer = tx_buffer;&lt;br /&gt;
  _ubrrh = ubrrh;&lt;br /&gt;
  _ubrrl = ubrrl;&lt;br /&gt;
  _ucsra = ucsra;&lt;br /&gt;
  _ucsrb = ucsrb;&lt;br /&gt;
  _ucsrc = ucsrc;&lt;br /&gt;
  _udr = udr;&lt;br /&gt;
  _rxen = rxen;&lt;br /&gt;
  _txen = txen;&lt;br /&gt;
  _rxcie = rxcie;&lt;br /&gt;
  _udrie = udrie;&lt;br /&gt;
  _u2x = u2x;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Public Methods //////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
void HardwareSerial::begin(unsigned long baud)&lt;br /&gt;
{&lt;br /&gt;
  uint16_t baud_setting;&lt;br /&gt;
  bool use_u2x = true;&lt;br /&gt;
&lt;br /&gt;
#if F_CPU == 16000000UL&lt;br /&gt;
  // hardcoded exception for compatibility with the bootloader shipped&lt;br /&gt;
  // with the Duemilanove and previous boards and the firmware on the 8U2&lt;br /&gt;
  // on the Uno and Mega 2560.&lt;br /&gt;
  if (baud == 57600) {&lt;br /&gt;
    use_u2x = false;&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
try_again:&lt;br /&gt;
  &lt;br /&gt;
  if (use_u2x) {&lt;br /&gt;
    *_ucsra = 1 &amp;lt;&amp;lt; _u2x;&lt;br /&gt;
    baud_setting = (F_CPU / 4 / baud - 1) / 2;&lt;br /&gt;
  } else {&lt;br /&gt;
    *_ucsra = 0;&lt;br /&gt;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if ((baud_setting &amp;gt; 4095) &amp;amp;&amp;amp; use_u2x)&lt;br /&gt;
  {&lt;br /&gt;
    use_u2x = false;&lt;br /&gt;
    goto try_again;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)&lt;br /&gt;
  *_ubrrh = baud_setting &amp;gt;&amp;gt; 8;&lt;br /&gt;
  *_ubrrl = baud_setting;&lt;br /&gt;
&lt;br /&gt;
  transmitting = false;&lt;br /&gt;
&lt;br /&gt;
  sbi(*_ucsrb, _rxen);&lt;br /&gt;
  sbi(*_ucsrb, _txen);&lt;br /&gt;
  sbi(*_ucsrb, _rxcie);&lt;br /&gt;
  cbi(*_ucsrb, _udrie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HardwareSerial::begin(unsigned long baud, byte config)&lt;br /&gt;
{&lt;br /&gt;
  uint16_t baud_setting;&lt;br /&gt;
  uint8_t current_config;&lt;br /&gt;
  bool use_u2x = true;&lt;br /&gt;
&lt;br /&gt;
#if F_CPU == 16000000UL&lt;br /&gt;
  // hardcoded exception for compatibility with the bootloader shipped&lt;br /&gt;
  // with the Duemilanove and previous boards and the firmware on the 8U2&lt;br /&gt;
  // on the Uno and Mega 2560.&lt;br /&gt;
  if (baud == 57600) {&lt;br /&gt;
    use_u2x = false;&lt;br /&gt;
  }&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
try_again:&lt;br /&gt;
  &lt;br /&gt;
  if (use_u2x) {&lt;br /&gt;
    *_ucsra = 1 &amp;lt;&amp;lt; _u2x;&lt;br /&gt;
    baud_setting = (F_CPU / 4 / baud - 1) / 2;&lt;br /&gt;
  } else {&lt;br /&gt;
    *_ucsra = 0;&lt;br /&gt;
    baud_setting = (F_CPU / 8 / baud - 1) / 2;&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if ((baud_setting &amp;gt; 4095) &amp;amp;&amp;amp; use_u2x)&lt;br /&gt;
  {&lt;br /&gt;
    use_u2x = false;&lt;br /&gt;
    goto try_again;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)&lt;br /&gt;
  *_ubrrh = baud_setting &amp;gt;&amp;gt; 8;&lt;br /&gt;
  *_ubrrl = baud_setting;&lt;br /&gt;
&lt;br /&gt;
  //set the data bits, parity, and stop bits&lt;br /&gt;
#if defined(__AVR_ATmega8__)&lt;br /&gt;
  config |= 0x80; // select UCSRC register (shared with UBRRH)&lt;br /&gt;
#endif&lt;br /&gt;
  *_ucsrc = config;&lt;br /&gt;
  &lt;br /&gt;
  sbi(*_ucsrb, _rxen);&lt;br /&gt;
  sbi(*_ucsrb, _txen);&lt;br /&gt;
  sbi(*_ucsrb, _rxcie);&lt;br /&gt;
  cbi(*_ucsrb, _udrie);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HardwareSerial::end()&lt;br /&gt;
{&lt;br /&gt;
  // wait for transmission of outgoing data&lt;br /&gt;
  while (_tx_buffer-&amp;gt;head != _tx_buffer-&amp;gt;tail)&lt;br /&gt;
    ;&lt;br /&gt;
&lt;br /&gt;
  cbi(*_ucsrb, _rxen);&lt;br /&gt;
  cbi(*_ucsrb, _txen);&lt;br /&gt;
  cbi(*_ucsrb, _rxcie);  &lt;br /&gt;
  cbi(*_ucsrb, _udrie);&lt;br /&gt;
  &lt;br /&gt;
  // clear any received data&lt;br /&gt;
  _rx_buffer-&amp;gt;head = _rx_buffer-&amp;gt;tail;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int HardwareSerial::available(void)&lt;br /&gt;
{&lt;br /&gt;
  return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer-&amp;gt;head - _rx_buffer-&amp;gt;tail) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int HardwareSerial::peek(void)&lt;br /&gt;
{&lt;br /&gt;
  if (_rx_buffer-&amp;gt;head == _rx_buffer-&amp;gt;tail) {&lt;br /&gt;
    return -1;&lt;br /&gt;
  } else {&lt;br /&gt;
    return _rx_buffer-&amp;gt;buffer[_rx_buffer-&amp;gt;tail];&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int HardwareSerial::read(void)&lt;br /&gt;
{&lt;br /&gt;
  // if the head isn't ahead of the tail, we don't have any characters&lt;br /&gt;
  if (_rx_buffer-&amp;gt;head == _rx_buffer-&amp;gt;tail) {&lt;br /&gt;
    return -1;&lt;br /&gt;
  } else {&lt;br /&gt;
    unsigned char c = _rx_buffer-&amp;gt;buffer[_rx_buffer-&amp;gt;tail];&lt;br /&gt;
    _rx_buffer-&amp;gt;tail = (unsigned int)(_rx_buffer-&amp;gt;tail + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
    return c;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void HardwareSerial::flush()&lt;br /&gt;
{&lt;br /&gt;
  // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY &amp;amp;&amp;amp; SENT&lt;br /&gt;
  while (transmitting &amp;amp;&amp;amp; ! (*_ucsra &amp;amp; _BV(TXC0)));&lt;br /&gt;
  transmitting = false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
size_t HardwareSerial::write(uint8_t c)&lt;br /&gt;
{&lt;br /&gt;
  int i = (_tx_buffer-&amp;gt;head + 1) % SERIAL_BUFFER_SIZE;&lt;br /&gt;
	&lt;br /&gt;
  // If the output buffer is full, there's nothing for it other than to &lt;br /&gt;
  // wait for the interrupt handler to empty it a bit&lt;br /&gt;
  // ???: return 0 here instead?&lt;br /&gt;
  while (i == _tx_buffer-&amp;gt;tail)&lt;br /&gt;
    ;&lt;br /&gt;
	&lt;br /&gt;
  _tx_buffer-&amp;gt;buffer[_tx_buffer-&amp;gt;head] = c;&lt;br /&gt;
  _tx_buffer-&amp;gt;head = i;&lt;br /&gt;
	&lt;br /&gt;
  sbi(*_ucsrb, _udrie);&lt;br /&gt;
  // clear the TXC bit -- &amp;quot;can be cleared by writing a one to its bit location&amp;quot;&lt;br /&gt;
  transmitting = true;&lt;br /&gt;
  sbi(*_ucsra, TXC0);&lt;br /&gt;
  &lt;br /&gt;
  return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
HardwareSerial::operator bool() {&lt;br /&gt;
	return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Preinstantiate Objects //////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
#if defined(UBRRH) &amp;amp;&amp;amp; defined(UBRRL)&lt;br /&gt;
  HardwareSerial Serial(&amp;amp;rx_buffer, &amp;amp;tx_buffer, &amp;amp;UBRRH, &amp;amp;UBRRL, &amp;amp;UCSRA, &amp;amp;UCSRB, &amp;amp;UCSRC, &amp;amp;UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);&lt;br /&gt;
#elif defined(UBRR0H) &amp;amp;&amp;amp; defined(UBRR0L)&lt;br /&gt;
  HardwareSerial Serial(&amp;amp;rx_buffer, &amp;amp;tx_buffer, &amp;amp;UBRR0H, &amp;amp;UBRR0L, &amp;amp;UCSR0A, &amp;amp;UCSR0B, &amp;amp;UCSR0C, &amp;amp;UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);&lt;br /&gt;
#elif defined(USBCON)&lt;br /&gt;
  // do nothing - Serial object and buffers are initialized in CDC code&lt;br /&gt;
#else&lt;br /&gt;
  #error no serial port defined  (port 0)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(UBRR1H)&lt;br /&gt;
  HardwareSerial Serial1(&amp;amp;rx_buffer1, &amp;amp;tx_buffer1, &amp;amp;UBRR1H, &amp;amp;UBRR1L, &amp;amp;UCSR1A, &amp;amp;UCSR1B, &amp;amp;UCSR1C, &amp;amp;UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRR2H)&lt;br /&gt;
  HardwareSerial Serial2(&amp;amp;rx_buffer2, &amp;amp;tx_buffer2, &amp;amp;UBRR2H, &amp;amp;UBRR2L, &amp;amp;UCSR2A, &amp;amp;UCSR2B, &amp;amp;UCSR2C, &amp;amp;UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(UBRR3H)&lt;br /&gt;
  HardwareSerial Serial3(&amp;amp;rx_buffer3, &amp;amp;tx_buffer3, &amp;amp;UBRR3H, &amp;amp;UBRR3L, &amp;amp;UCSR3A, &amp;amp;UCSR3B, &amp;amp;UCSR3C, &amp;amp;UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#endif // whole file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>YWrobot WM</name></author>	</entry>

	</feed>