Comunicaciones serialesc#2010 ccs

62
Autor: Andrés Gerardo Fuentes Covarrubias 1 Comunicaciones seriales Caso: Visual C# 2010 Express PIC18F4550 - CCS – PICC M.C. ANDRÉS GERARDO FUENTES COVARRUBIAS Materia: Sistemas Embebidos y Control – SEPTIMO SEMESTRE Ingeniero en Sistemas Computacionales Universidad de Colima Facultad de Ingeniería Mecánica y Eléctrica Academia de Arquitectura de Computadoras

Transcript of Comunicaciones serialesc#2010 ccs

Page 1: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 1

Comunicaciones seriales

Caso: Visual C# 2010 Express PIC18F4550 - CCS – PICC

M.C. ANDRÉS GERARDO FUENTES COVARRUBIAS

Materia: Sistemas Embebidos y Control – SEPTIMO SEMESTRE Ingeniero en Sistemas Computacionales Universidad de Colima Facultad de Ingeniería Mecánica y Eléctrica Academia de Arquitectura de Computadoras

Page 2: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 2

Metodología

Creación de una nueva aplicación

Instalación de Virtual Serial Port

toolStrip y componentes básicos

Manejo de los puertos seriales

Apertura de un puerto

Transmisión

Recepción

Page 3: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 3

Virtual Serial Port

Forma comoda de depurar las aplicaciones al crear puertos seriales virtuales pareados

Un puerto serial para la simulación en ISIS Proteus

Un puerto serial para el programa en Visual C# 2010

Page 4: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 4

Creación de una nueva aplicación

Abrir VC# 2010 y elegir “Archivo”->”Nuevo Projecto”

Después “Aplicación de Windows Forms y el botón “Aceptar” después de darle nombre al nuevo proyecto

Page 5: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 5

Manejo de los puertos seriales • Elegir dos controles:

1. Para manejo de los puertos

seriales: “SerialPort”, será el

encargado de manejar todas las propiedades, métodos y eventos relacionados con el puerto o los puertos seriales de la aplicación, crear tantos como puertos seriales se necesite.

• Elegir dos controles:

2. Para manejo de los controles básicos de las comunicaciones seriales, asi como mensajes e indicadores, elija el control “ToolStrip”

Estos controles no son visibles en la forma principal, por lo tanto se colocan en el “Status Strip”

Page 6: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 6

Manejo de puertos seriales

Controles en la aplicación, ToolStrip.

Observe que para .Net el control para puerto serial contiene todas las propiedades para las características de la trama en tiempo de diseño

ComboBox

TextBox Boton Label

Page 7: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 7

Manejo de puertos seriales

Controles en la aplicación, área de trabajo

TabControl

OvalShape

Botones

Label

Page 8: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 8

Código fuente inicial

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.IO.Ports; using System.Threading; using Microsoft.VisualBasic.PowerPacks; namespace consolaSerialCDC { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } }

El código fuente inicial solo describe las librerías a ser utilizadas al momento y el esqueleto inicial para el “namespace” correspondiente a nuestra aplicación.

Agregar estas referencias externas

Page 9: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 9

Manejo de los puertos seriales

if(!serialPort1.IsOpen) { try { serialPort1.Open(); } catch (System.Exception ex) { MessageBox.Show(ex.ToString()); } }

La apertura de un puerto serial en Visual C# es tan sencillo como agregar el siguiente código al botón “Conectar” del ToolStrip:

Las propiedades del control SerialPort se pueden establecer en tiempo de diseño mediante el cuadro de propiedades.

Page 10: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 10

Apertura de un puerto

serialPort1.BaudRate = 9600; // Velocidad de transmisión serialPort1.Parity = Parity.None; //Tipo de paridad serialPort1.DataBits = 8; //Número de bits de datos serialPort1.StopBits = StopBits.One; //Número de bits de parada serialPort1.PortName = toolStripTextBox1.Text; //Use el control adecuado para el usuario serialPort1.Open(); //Abrir el puerto

Siempre se puede abrir un puerto con el código siguiente y tambien establecer las caracteristicas de la trama:

Vincule el código anterior con un botón y podrá abrir el puerto serial capturado en el control “toolStripTextBox1” al presionar el botón “Conectar”

Page 11: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 11

Transmisión •Siempre que haya un puerto serial abierto se puede enviar datos por ese puerto.

•En el TabControl “Terminal”

•Agregue dos controles

•TextBox

•Botón

private void button1_Click(object sender, EventArgs e)

{ if (conectado == true) { if (tbTerminalEnviar.Text.Length > 0) { serialPort1.WriteLine("@" + tbTerminalEnviar.Text + "\r"); } else { MessageBox.Show("MENSAJE VACIO"); } } else { MessageBox.Show("Puerto Serial NO CONECTADO"); } }

Agregue el código del botón

Page 12: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 12

Transmisión

byte[] miBuffer= new byte[1]; miBuffer[0] = 0x62; //Carácter a enviar por el puerto. SP1.Write(miBuffer, 0, miBuffer.Length);

Siempre es posible enviar también un solo caracter por el puerto serial:

// Enviar trama byte[] miBuffer= new byte[3]; // Tres caracteres máximo. miBuffer[0] = 0x74; miBuffer[1] = 0x54; miBuffer[2] = 0x13; SP1.Write(miBuffer, 0, miBuffer.Length);

Por ejemplo, si lo que se desea es enviar una trama completa, entonces:

Page 13: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 13

Transmisión

Tambien se puede vincular código a otros controles de usuario:

strBufferOut = "1"; //Buffer de transmisión serialPort1.DiscardOutBuffer(); //Limpiamos el buffer de transmisión serialPort1.Write(strBufferOut); //Enviar caracteres

Cada control incluye código:

Indicadores con el control Ovalshape para simular leds.

Salidas por botón

Page 14: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 14

Recepción

El proceso de recepción de datos es un proceso un poco mas complejo, ya que es necesario instalar el vector de interrupción del evento “DataReceived” y crear un nuevo Thread (hilo) que atienda al manejador de ese evento.

Page 15: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 15

Recepción Crear un nuevo control TextBox, que sea multilinea, con ScrollBar vertical y ajustado a la parte inferior del formulario. Este control va a operar como nuestra consola del usuario, para desplegar mensajes de la aplicación, los datos enviados y los recibidos.

Page 16: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 16

Recepción

1. Codigo de al cargar el formulario:

public Form1() {

txtRecibidos.Text = ""; strBufferIn = ""; serialPort1.DataReceived += new SerialDataReceivedEventHandler( serialPort1_DataReceived);

}

Para crear un manejador, se debe agregar un nuevo manejador de eventos, y vincularlo con el método apropiado del control “serialPort”, el procedimiento consta de tres pasos:

Page 17: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 17

Recepción 2. El codigo del manejador de eventos private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

{ strBufferIn = ""; //Debemos hacer una pausa, para que el buffer se llene por completo //y pueda cargar todos los datos. //Si esta pausa no se realiza, no carga las lineas por completo y solo //nos muestra parte del mensaje enviado. Thread.Sleep(250); strBufferIn += serialPort1.ReadExisting(); if (serialPort1.BytesToRead > 0) strBufferIn += serialPort1.ReadExisting(); String Linea; Linea = strBufferIn; //Guardamos la cadena original para "Split" //Posterior this.Invoke(new EventHandler(Actualiza_textbox)); }

Page 18: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 18

Recepción

2. El codigo del “delegado” private void Actualiza_textbox(object s, EventArgs e) { txtRecibidos.Text += strBufferIn + "\r\n"; }

Page 19: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 19

Status Strip

Siempre es posible manejar la barra de estado de nuestro formulario:

•Barra de estado

•Menú de opciones

Page 20: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 20

Status strip

Agregue un control “timer”

Para agregar el reloj del sistema a la barra de estado:

Configure las propiedades

Page 21: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 21

Status strip

Ejecute los siguientes pasos en el orden indicado:

Agregar el código al control del timer:

private void timer1_Tick(object sender, EventArgs e) { statusStrip1.Items[0].Text = DateTime.Now.ToLongTimeString(); }

1 2 3

Cambie la propiedad “Text” a “hh:mm:ss”

Page 22: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 22

Caso de estudio

Interfaz serial RS232C Max232

Circuito LM35z a °C

Registrador de temperaturas

Graficador de 2 canales

Base de datos sqlServer

Page 23: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 23

ESQUEMATICO VERSION 1

Page 24: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 24

Controles para el modelado en Proteus ISIS

ComPim: Para salida de datos por medio de un Virtual Port

Monitoreo por medio de la Terminal Virtual

Page 25: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 25

LoopBack serial Isis Proteus

Interconecta por “cable cruzado” la terminal virtual y el control ComPim

Por medio de un programa de hiperterminal se puede monitorear la actividad serial RS232C

No se necesita convertidor de protocolo MAX232

Page 26: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 26

Modelo de programación del microcontrolador PIC18F4550 para comunicaciones seriales

Comunicaciones Full-Duplex

Compatibilidad 9600, 8 , N, 1

Programable en ensamblador y lenguaje de alto nivel

BaudRate totalmente configurable

Capaz de manejar e identificar paridad

Page 27: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 27

Pinout del Pic18F4550

Page 28: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 28

Comunicaciones en CCS

La inicialización de interfases seriales, tanto Hardware como Software se llevan a cabo por medio de la instrucción:

#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)

La salida de datos y caracteres ahora pueden llevarse a cabo por medio de la instrucción printf(), respetando todos los formatos de dicha instrucción.

Tambien se puede usar la instrucción putchar() para sacar un carácter individual en cualquier momento

La lectura de caracteres se puede llevar a cabo por medio de la instrucción getchar()

Page 29: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 29

Ejemplo de salida de datos

Page 30: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 30

Codigo de salida de datos

lcd_putc("Terminal Serial "); printf("Terminal Serial %c%c",13,10); while(1) // Ciclo infinito { lcd_gotoxy(1,2); // Posicionamos cursor renglon 2 printf(lcd_putc,"%u",a); // Desplegar el valor de a printf("%u %c %c",a,13,10); // Sacamos por el puerto serial + CrLf output_bit(LED,1); // Encendemos el Led delay_ms(500); // Retardo de 500 milisegundos prendido output_bit(LED,0); // Apagamos el Led delay_ms(500); // Retardo de 500 milisegundos apagado a++; // Incrementamos en 1 la variable if(input(Boton)==0) // Se presiono el Boton? { delay_ms(100); // Retardo para quitar el rebote if(input(Boton)==0) // Todavia esta presionado? procesar { lcd_gotoxy(1,1); // Posicionamos cursos renglon 1 printf(lcd_putc,"Presiono Boton"); // Desplegamos el mensaje while(input(Boton)==0); // Ahi esperamos hasta que se suelte el Boton output_bit(LED,0); // Apagamos el Led lcd_putc('\f'); // Borramos la pantalla a=0; // Limpiamos la variable } printf(lcd_putc,"Hola Mundo"); // Dejamos el LCD como estaba antes del Boton } if(valor=="1") output_toggle(LED1); }

Page 31: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 31

Entrada de datos en CCS

Recomendable usar interrupciones para el puerto serial

Por cada carácter recibido, meterlo a un buffer y procesar cuando sea necesario

Page 32: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 32

Ejemplo de entrada de datos • Monitorear por medio de Terminal Virtual.

• Entrada de datos por medio del control ComPim

Page 33: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 33

Tipos de interrupciones en CCS #INT_xxx - Indica que la función que le sigue (en el código fuente CCS) es una

función de interrupción. Estas funciones no deben tener parámetros. Por supuesto,

no todos los PICs soportan todas las directivas disponibles:

INT_AD Conversión A/D finalizada. I NT_ADOF Conversión A/D timeout. INT_BUSCOL Colisión en bus. INT_BUTTON Pushbutton. INT_CCP1 Unidad CCP1. INT_CCP2 Unidad CCP2. INT_COMP Comparador. INT_EEPROM Escritura finalizada. INT_EXT Interrupción externa. INT_EXT1 Interrupción externa #1. INT_EXT2 Interrupción externa #2. INT_I2C Interrupción por I2C. INT_LCD Actividad en el LCD.

INT_LOWVOLT Bajo voltaje detectado. INT_PSP Ingreso de datos en el Parallel

Slave Port. INT_RB Cambios en el port B (B4-B7). INT_RC Cambios en el port C (C4-C7). INT_RDA Datos disponibles en RS-232. INT_RTCC Desbordamiento del Timer 0

(RTCC). INT_SSP Actividad en SPI o I2C. INT_TBE Buffer de transmisión RS-232

vacío. INT_TIMER0 Desbordamiento del Timer 0

(RTCC). INT_TIMER1 Desbordamiento del Timer 1. INT_TIMER2 Desbordamiento del Timer 2. INT_TIMER3 Desbordamiento del Timer 3.

Page 34: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 34

Las interrupciones por el puerto serie

Cada que llega un carácter al puerto serie por medio de la linea [RC7/RX/DT/SDO (26)] el microcontrolador, mediante la lógica de interrupciones, transfiere el control del flujo del programa a la primera instrucción

despues de la etiqueta #int_rda

Por medio de las interrupciones no es necesario sondear en la función main() el estado de la linea de recepción de datos seriales.

Page 35: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 35

Código de la rutina de servicio a interrupción (ISR)

#int_rda //Rutina de servicio a interrupcion void serial_isr() { valor=getchar(); //Leer el carácter recibido del buffer //de recepcion }

• Activar la recepción de interrupciones globales y por el puerto serial:

//------------------------------------------------------------------------------------------------ //Inicialización del microcontrolador //----------------------------------- enable_interrupts(global); //Habilitar las interrupciones globales enable_interrupts(int_rda); //Habilitar la interrupcion por recepcion //de caracteres en el puerto serial setup_adc_ports(NO_ANALOGS); //Las entradas analogicas configuradas como digitales set_tris_b(0); //Todas salidas puerto B set_tris_d(0b00000001); //RD0 salida de led de estado output_b(0); //Apagamos todos los leds

Page 36: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 36

Ejemplo de entrada de datos Consulte el código siguiente, para

recepción de datos por medio del método de interrupción:

#include "18f4550.h" #device adc=10 //Resolucion del ADC 8/10 bits //---------------------------------------------------------------------------------------------------- //Bits de configuración #fuses HSPLL,NOWDT,NOBROWNOUT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,MCLR,NOPBADEN, WRTB,CPB //---------------------------------------------------------------------------------------------------- //USES de configuracion de perifericos //Configuración del oscilador del CPU #use delay(clock=48000000) #include <stdlib.h> #include <LCD.c> //Configuracion de la USART1 #use rs232(baud=9600,parity=N,RCV=PIN_C7,XMIT=PIN_C6,bits=8) #use standard_io(e) #use standard_io(d) #use standard_io(c) #use standard_io(b) #use standard_io(a)

Page 37: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 37

//---------------------------------------------------------------------------------------------------- //Redireccionamiento de los vectores de interrupción para adaptarlos al HidBootloader //#build(reset=0x1000,interrupt=0x1008) //#org 0x0000,0x0FFF {} //---------------------------------------------------------------------------------------------------- //Definición de simbolos y variables globales #define LED1 PIN_B0 #define LED2 PIN_B1 #define LED3 PIN_B2 #define LED4 PIN_B3 #define LED5 PIN_B4 #define LED6 PIN_B5 #define LED7 PIN_B6 #define LED8 PIN_B7 #define LED PIN_E0 char valor; char flagIsr; char flagAnalogo; int muestra; float voltaje; float temperatura; int canal=1; int ADC_ACQT_2TAD=0x1;

Page 38: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 38

//---------------------------------------------------------------------------------------------------- //Rutinas de servicio a interrupcion #int_rda void serial_isr() { valor=getc(); /Leemos el caracter recibido del buffer de recepcion output_toggle(LED); //Mostramos mediante un Led que hay actividad en el delay_ms(100); //canal de datos output_toggle(LED); flagIsr=1; //Activamos la bandera de recepcion //-Segun el caracter recibido activamos la alarma correspondiente switch(valor) { case '1': output_toggle(LED1); break; case '2': output_toggle(LED2); break; case '3': output_toggle(LED3); break; case '4': output_toggle(LED4); break; case '5': output_toggle(LED5); break;

Page 39: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 39

case '6': output_toggle(LED6); break; case '7': output_toggle(LED7); break; case '8': output_toggle(LED8); break; case '0': output_b(0); break; case '@': output_b(255); break; case '#': flagAnalogo=1; break; } }

Page 40: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 40

//---------------------------------------------------------------------------------------------------- //Programa principal void main(void) { //------------------------------------------------------------------------------------------------ //Variables y constantes del programa //------------------------------------------------------------------------------------------------ //Inicialización del microcontrolador //----------------------------------- enable_interrupts(global); //Habilitar las interrupciones globales enable_interrupts(int_rda); //Habilitar la interrupcion por recepcion //de caracteres en el puerto serial setup_vref(FALSE); setup_adc_ports( AN0 || VSS_VDD ); //Inicializamos el puerto analogico AN0 setup_adc(ADC_CLOCK_DIV_64 || ADC_ACQT_2TAD ); set_tris_b(0); //Todas salidas puerto B set_tris_e(0b00000001); //RD0 salida de led de estado output_b(0); //Apagamos todos los leds lcd_init(); //Inicializamos el lcd lcd_putc('\f'); //Borramos la pantalla del lcd

Page 41: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 41

//------------------------------------------------------------------------------------------------ //Rutina principal //------------------- printf("Terminal Serial %c%c",13,10); while(1) // Ciclo infinito { if(flagIsr==1) { //printf("Recibido:%c %c %c",valor,13,10); //Desplegamos el caracter recibido por la consola para //monitorear la recepcion correcta+ CrLf flagIsr=0; //Preparamos la bandera de entrada a ISR para solo //desplegar el valor cuando haya caracter recibido } if(flagAnalogo==1) { disable_interrupts(global);//Habilitar las interrupciones globales disable_interrupts(int_rda);//Habilitar la interrupcion por recepcion set_adc_channel(0); //Seleccionamos el canal a muestrear muestra= read_adc(); //Una lectura por el ADC delay_us(10); //Delay para espera termino de conversion

Page 42: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 42

voltaje = 5.0*muestra / 1024.0; //Convertimos a voltaje otra vez temperatura=voltaje/0.010; //Ahora a temperatura 10mV/°C lcd_putc('\f'); //Borramos la pantalla primero lcd_gotoxy(1,1); printf(lcd_putc,"v=%01.2f", voltaje); lcd_gotoxy(1,2); printf(lcd_putc,"%04d",muestra); printf("1,%01.2f,%01.2f;",temperatura,voltaje); //Enviar al datalogger flagAnalogo=0; enable_interrupts(global);//Habilitar las interrupciones globales enable_interrupts(int_rda);//Habilitar la interrupcion por recepcion } } }

Page 43: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 43

Principales mandatos para manejar el puerto serial CCS

Inicialización del puerto serial

#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)

Recepción de datos c = GETC() //Todas son equivalentes y básicamente esperan por un carácter c = GETCH() // a ser recibido por la patilla RC6/RX del puerto serial c = GETCHAR() Ejemplo:

printf("Continuar (s,n)?");

do

{

respuesta=getch();

} while(respuesta!='s'&& respuesta!='n');

GETS(char *string) //Esta función lee caracteres (usando GETC()) de la cadena (string) //hasta que encuentra un retorno de carro(valor ASCII 13). La cadena //se termina con un 0.

Page 44: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 44

Principales mandatos para manejar el puerto serial CCS

KBHIT()

Esta función devuelve TRUE si el bit que se está enviando al pin RCV de un dispositivo RS232, es el bit de inicio de un carácter. Es preciso utilizar la directiva #USE RS232 antes de la llamada a esta función para que el compilador pueda determinar la velocidad en baudios y la patilla utilizada.

Ejemplo: keypress=' '; while ( keypress!='Q' ) //Entramos al bucle while { if ( kbhit () ) keypress=getc(); //En la variable keypress se guardan los

//caracteres if (keypress==‘1’) //Inicio del envío de un byte output_high(PIN_B3); else output_low(PIN_B3) }

Page 45: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 45

Principales mandatos para manejar el puerto serial CCS

Transmisión serial

PUTC() //Ambas instrucciones son equivalentes, basicamente

PUTCHAR() //envían un carácter a la patilla XMIT(RC7/TX) de //del dispositivo RS232 del microcontrolador.

Ejemplo:

if (checksum==0)

putchar(ACK);

else

putchar(NAK); // NAK carácter de respuesta negativa

PUTS(string) //Esta función envía cada carácter de string a la //patilla XMIT del dispositivo RS232. Una

//vez concluido el envío de todos los caracteres la //función envía un retorno de carro CR o RETURN (ASCII 13)

//y un avance de línea LF o LINE-FEED (ASCII 10).

Ejemplo: puts( " | HOLA |" );

Page 46: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 46

Principales mandatos para manejar el puerto serial CCS Función printf() y modificadores

La función de impresión formateada printf() saca una cadena de caracteres al puerto serie RS-232 (previamente inicializado mediante #use rs232…), o a una función especificada (por ejemplo lcd_putc()). El formato está relacionado con el argumento que ponemos dentro de la cadena (string).

Sintaxis: printf([function], string, [values])

Los modificadores de formato se incluyen dentro de “string” e inician con el carácter %, opcionalmente se puede redirigir la salida de printf() hacia una función de manejo de flujo de caracteres como lcd_putc() que envia flujo de caracteres hacia un lcd alfanumérico o gráfico.

Ejemplos:

byte x,y,z; printf (" Hola "); printf("RTCCValue=>%2x\n\r",get_rtcc()); printf("%2u %X %4X\n\r",x,y,z); printf(lcd_putc, "n=%c",n);

Page 47: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 47

Manejo del buffer de recepción en Visual C#

Control mas efectivo sobre los caracteres delimitadores

Posibilidad de hacer parsing en línea

Page 48: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 48

Manejo del buffer de recepción (código)

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

recibidos = "";

carSerial = (char) 0;

while(carSerial!=';')

{

carSerial = (char) serialPort1.ReadChar();

if (carSerial == ';')

break;

recibidos += carSerial.ToString();

}

this.Invoke(new EventHandler(Actualiza_textbox));

}

Page 49: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 49

Split Tokens en C#

Use un delimitador de campo, por lo general es el caracter “,”

Use un delimitador de cadena, por lo general es el caracter “;”

Use el método Split

Procese los tokens encontrados

Page 50: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 50

Código

public Form1() { InitializeComponent(); } private void btSplit_Click(object

sender, EventArgs e) { str = txtCadena.Text; string[] parts = str.Split(seps); for (int i = 0; i < parts.Length;

i++) cadenaSplit +=

parts[i]+"\r\n"; txtConsola.Text = cadenaSplit; } } }

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace splitCampos { public partial class Form1 : Form { string str; char[] seps={','}; string cadenaSplit;

Page 51: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 51

Manejo del buffer de recepción (código para separar tokens)

private void Actualiza_textbox(object s, EventArgs e)

{ string[] parts = recibidos.Split(seps); //Tokenizamos la trama if (parts.Length == 3) //Validamos numero de //tokens encontrdos, deben ser 3 { lblTemp.Text = parts[1]; //Actualizamos etiquetas lblVolt.Text = parts[2]; } lblRecibido.Text = recibidos; //Visualizamos trama actual txtRecibidos.Text += recibidos+"\r\n"; //Actualizamos el textBox consola }

Page 52: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 52

Principales mandatos para manejar el puerto serial

'Definir las características de la comunicación Serie.BaudRate = 19200 'Fijar velocidad de comunicaciones Serie.DataBits = 8 'Longitud en bits para Byte de datos Serie.Parity = Parity.Even 'Asignar paridad(enumeration parity) Serie.StopBits = StopBits.Two 'Bits parada después byte de datos 'Abrir/Control/Liberar Puerto Serie.Open() 'Abrir el puerto Serie Serie.Close() 'Cerrar el Puerto Serie Serie.Dispose() 'Liberar objeto Dim SiNo As Integer SiNo = Serie.IsOpen 'El Puerto esta abierto? Dim Puerto As String Puerto = Serie.PortName 'Nombre del puerto

Page 53: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 53

Principales mandatos para manejar el puerto serial

'Manejo y Control de señales

Dim Estado As Boolean 'True=Activa / False=Inactiva

Estado = Serie.CDHolding 'Estado de la señal carrier detect Estado = Serie.CtsHolding 'Señal Clear to Send Estado = Serie.DsrHolding 'Señal Data Set Ready Serie.DtrEnable = True 'Activar de Data Terminal Ready Serie.RtsEnable = True 'Activar Request To Send

'Control Transmission/Recepcion Serie.ReadBufferSize = 1024 'Dimensionar tamaño buffer recepción Serie.WriteBufferSize = 1024 'Dimensionar tamaño buffer envío Serie.ReadTimeout = 10 'Fuera de tiempo para las lecturas Serie.WriteTimeout = 10 'Fuera de tiempo para las escrituras Serie.Handshake = Handshake.XOnXOff 'Tipo control para recepción/envío Serie.DiscardInBuffer() 'Borrar el buffer de entrada Serie.DiscardOutBuffer() 'Borrar el buffer de salida

Page 54: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 54

Principales mandatos para manejar el puerto serial Visual C#

'Enviar datos Contador = Serie.BytesToWrite 'Bytes en espera de ser escritos Serie.Write("Hola Mundo") 'Enviar una cadena de caracteres Serie.WriteLine("Hola Mundo") 'Enviar una línea 'Leer datos Contador = Serie.BytesToRead 'Bytes en espera de ser leídos Serie.ReadByte() 'Leer un byte Serie.ReadChar() 'Leer un char Serie.ReadLine() 'Leer una línea Serie.ReadExisting() 'Leer los datos existentes en buffer

Page 55: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 55

Uso de ZedGraph

ZedGraph es uno de los controles mas utilizados en ingeniería para desplegar gráficos de puntos o líneas.

Como es un control externo es necesario instalarlo como un componente adicional.

Page 56: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 56

Uso de ZedGraph

La primera parte consiste en su inicialización

La segunda parte ocurre tambien en tiempo de ejecución y consiste en la impresión de los puntos recibidos y unirlos mediante lineas.

Page 57: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 57

1. Creación del control:

Page 58: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 58

2. Inicialización

Consiste en la inicialización del control

Generalmente se efectua al cargar la forma principal por primera vez

Se puede usar una función de usuario

1. Definir un objeto tipo lista:

PointPairList list1 = new PointPairList();

2. Crear la función de usuario:

private void inicializaGrafico(ZedGraphControl zgc)

{

GraphPane myPane = zgc.GraphPane;

// Titulos

myPane.Title.Text = "Gráfico de temperaturas";

myPane.XAxis.Title.Text = "Muestra";

myPane.YAxis.Title.Text = "Temperatura";

myPane.YAxis.Scale.Max = 150;

// Inicializa una curva con diamantes en cada muestra

// la palabra "temperatura" como titulo de la muestra

LineItem myCurve = myPane.AddCurve("Temperatura",

list1, Color.Red,

SymbolType.None);

}

3. Inicializarla dentro de Form_Load1

4. No olvidar referenciar el NameSpace ZedGraph con el Using correspondiente

Page 59: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 59

3. Código del usuario private void Form1_Load(object sender, EventArgs e) { UpdateSerialPorts(); inicializaGrafico(graficoTemp); }

private void inicializaGrafico(ZedGraphControl zgc) { GraphPane myPane = zgc.GraphPane; // Titulos myPane.Title.Text = "Gráfico de temperaturas"; myPane.XAxis.Title.Text = "Muestra"; myPane.YAxis.Title.Text = "Temperatura"; myPane.YAxis.Scale.Max = 150; // Inicializa una curva con diamantes en cada muestra tomada // la palabra "temperatura" como titulo de la muestra LineItem myCurve = myPane.AddCurve("Temperatura", list1, Color.Red,

SymbolType.None); }

Page 60: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 60

4. Función de recepción con Split campos

La recepción debe cambiar ya que tradicionalmente se procesa el buffer de recepción en conjunto.

Ahora deberá procesarse carácter a carácter hasta obtener un carácter de fin de trama = “;”

Despues de recibir el fin de trama deberá separarse los campos con el método Split

Page 61: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 61

private void Actualiza_textbox(object s, EventArgs e) { string[] parts = strBufferIn.Split(seps); if (parts.Length == 3) { lblTemp.Text = parts[1]; temperaturaCanal1 = Convert.ToSingle(parts[1]); numMuestra++; float x = (float)numMuestra; float y = (float)temperaturaCanal1; list1.Add(x, y); graficoTemp.AxisChange(); graficoTemp.Refresh(); lblVolt.Text = parts[2]; } txtConsola.Text += strBufferIn + "\r\n"; }

Page 62: Comunicaciones serialesc#2010 ccs

Autor: Andrés Gerardo Fuentes Covarrubias 62

RESOLUCIÓN DE DUDAS

[email protected]

[email protected]

[email protected]

Facebook: /Andres.FuentesCovarrubias