Pregunta:
¿Cómo funciona la comunicación del puerto serie bajo el capó?
denis_choe
2014-05-04 14:33:20 UTC
view on stackexchange narkive permalink

Solo estoy buscando cómo enviar / escribir la fecha a la PC a través del puerto serie desde arduino .. viceversa.

Tengo pocas preguntas que hacer después de tomarme tanto tiempo y no pude resolverlo yo mismo. Espero que puedan guiarme por favor.

Primero, descubrí que puedo usar la función Serial.println () para enviar algunos datos y luego, en el lado de la PC, solo verifica y lee el puerto (/ dev / tty ..). Pero, ¿cómo funciona este proceso bajo el capó? Entonces, si usa serial.println (), ¿sabe dónde escribir?

En segundo lugar, también descubrí que tiene algo que ver con la comunicación UART ... Pero, dentro del archivo Hardware.cpp, no pude encontrar cualquier llamada de función a la de UART.

En tercer lugar, está el código como extern HardwareSerial Serial; Entonces, ¿dónde está la definición de este Serial?

Cuarto Parece haber un búfer circular para el búfer serial. Entonces, cuando se envían datos, ¿qué y quién llena los datos en este búfer dentro de Hardware.cpp?

Por favor, perdone mi pregunta tonta ... tengo tanta curiosidad por esto ...

Consulte el [capítulo 19 de la hoja de datos] (http://www.atmel.com/Images/doc8161.pdf).
Los sitios de Stackexchange son para preguntas específicas e individuales. Edite su publicación para hacer una sola pregunta que pueda tener una respuesta específica, preferiblemente una que le quede después de leer la documentación.
Puede encontrar esto interesante sobre los búferes en ambos lados de un Nano conectado a un sistema Raspian que ejecuta un registrador de datos Python, usando solo un cable de programación USB normal entre los dos: https://arduino.stackexchange.com/questions/11710/does -data-vino-en-puerto-serie-almacenar-por-algún-tiempo
Dos respuestas:
#1
+3
Edgar Bonet
2015-02-24 16:34:02 UTC
view on stackexchange narkive permalink

La primera pregunta ya obtuvo una respuesta perfectamente buena. Estoy respondiendo a las otras.

No pude encontrar ninguna llamada de función a la de UART.

No hay "funciones UART" en la MCU. El UART se controla leyendo y escribiendo en registros especiales. Estos vienen con nombres como UCSR0A , UCSR0B , UCSR0C (USART 0 Control and Status Registers A, B y C), UBRR0L , UBRR0H (bytes bajos y altos del registro de velocidad en baudios USART 0) y UDR0 (registro de datos USART 0). Todos estos registros están referenciados en HardwareSerial.cpp. Puede comprobar su significado en la hoja de datos.

¿Dónde está la definición de esta serie?

En HardwareSerial.cpp, al final del archivo, justo después del comentario "Objetos preinstalados".

Parece haber un búfer en anillo para el búfer en serie. Entonces, cuando se envían datos, ¿qué y quién llena los datos en este búfer dentro de Hardware.cpp?

En realidad, hay dos búferes de anillo: el de recepción El búfer ( _rx_buffer ) se llena mediante una rutina de servicio de interrupción y se vacía llamando a Serial.read () . El búfer de transmisión ( _tx_buffer ) se llena llamando a Serial.write () , Serial.print () o Serial.println () (la línea _tx_buffer->buffer [_tx_buffer->head] = c; en HardwareSerial :: write () ), y se vacía mediante un servicio de interrupción rutina.

Estas rutinas de servicio de interrupciones están definidas en HardwareSerial.cpp. Empiezan con líneas como ISR (SOMETHING_vect) . Son activados por el hardware UART. El ISR de transmisión se activa cuando el UART está listo para aceptar un nuevo byte para transmitir (cuando termina de transmitir el byte n , comienza a transmitir el byte n +1 y está listo para aceptar el byte n +2 en su búfer TX). El ISR de recepción se activa cuando se recibe un nuevo byte.

¿Cuándo se inicializa?

Cuando llama a Serial.begin ( ) .

Tenga en cuenta que si el IDE está en un Raspbian, HardwareSerial.cp se encuentra en / usr / share / arduino / hardware / arduino / cores / arduino - vaya a HardwareSerial.cpp y observe dónde detecta que tiene más de 1000 bytes de memoria (El Rpi tiene 2048) y ahí es donde la configuración del búfer de anillo es 64. No he encontrado ninguna necesidad de expandirlo, pero se puede hacer.
#2
+2
EternityForest
2014-05-05 05:02:13 UTC
view on stackexchange narkive permalink

Serial.println sabe dónde escribir porque Serial es un objeto. En placas con más de un puerto también habrá un Serial1, Serial2, etc. Cada objeto corresponde a un puerto.

Los búferes de anillo se llenan de interrupciones. Cuando entra un nuevo byte, desencadena una interrupción que coloca el byte en el búfer. Cuando un byte termina de enviarse, activa otra interrupción que lee el siguiente byte del búfer y lo envía.

En algún lugar hay un archivo fuente que configura el UART. Está lleno de escribir valores especiales en registros y cosas de bajo nivel como esa. No estoy seguro de en qué archivos se definen las cosas, pero si usa la función de búsqueda en github, hay toneladas de cosas interesantes.

Gracias por tu respuesta. ahora que sé que el serial es un objeto, ¿cuándo se inicializa? Y, cuando ocurren las interrupciones, ¿entonces de alguna manera el código para esa interrupción sabe sobre el objeto Serial para que pueda jugar con ese búfer de anillo?
Si bien hay una interrupción para "transmisión completa", esa no es la que la mayoría de las bibliotecas usarían para llenar el búfer de anillo. En su lugar, usarían la interrupción "USART Data Register Empty" para indicar que puede cargar nuevos valores en el _transmit register_, que contiene el siguiente byte que se enviará después de que USART haya terminado de enviar el byte actual en el _shift register_. En otras palabras, la interrupción ocurre cuando la MCU _comienza_ a enviar un byte, lo que puede ser importante en algunas aplicaciones. (Sección 24.7.3 de la hoja de datos).


Esta pregunta y respuesta fue traducida automáticamente del idioma inglés.El contenido original está disponible en stackexchange, a quien agradecemos la licencia cc by-sa 3.0 bajo la que se distribuye.
Loading...