Issuu on Google+

Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

PIC18F14K50: EUSART (SERIAL) El módulo EUSART (Enhanced Universal Synchronous Asynchronous Receiver Transmitter) se utiliza para protocolos de comunicación en serie como: RS-232, RS-485 y LIN (Local Interconnect Network) 2.0. Diferencias entre los diferentes protocolos de comunicación:

Características: Línea: Distancia: Comunicación: Relación: Velocidad: Voltajes: Software Adicional: Hardware Adicional:

RS-232:

RS-485:

LIN:

Sin balance/ No diferencial 15m Full-Dúplex Punto a Punto (1 Driver – 1 Receptor) 19.2 Kbps (12m) +/- 3 a15v No Si (MAX232)

Balance/Diferencial 1200m Half-Duplex Multipunto (32 Drivers – 32 Receptores) 10 Mbps (12m) -7v a +12v Si (Stack) Si (MAX485)

Sin balance/ No diferencial 40m Full-Dúplex Multipunto (1 Driver – 16 Receptores) 19.2 Kbps (40m) +12v Si (Stack) Si (¿?)

Las características del módulo EUSART son:         

Full-Dúplex Asíncrono (Receptor y Transmisor). Half-Duplex Maestro/Esclavo Síncrono. 8 a 9 bits de longitud (Programable). 2 caracteres de buffer de entrada. 1 carácter de buffer de salida. Detección de dirección en modo 9 bits. Reloj programable y polaridad de datos. Detección automática del baud rate. Auto-Wake-Up en modo asíncrono.

El diagrama de bloque del transmisor EUSART es:


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

El diagrama de bloque del receptor EUSART es:

Para configurar la velocidad de transmisi贸n y recepci贸n se debe calcular el valor de n para el baud rate que se necesite con las siguientes formulas:

[

]


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

En la hoja de datos pรกgina 194 vienen varias tablas con varios baud rates y configuraciones con todo y el % de error para facilitar obtener el dato n. Ejemplo:


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

1. Comunicación RS-232 Este método de comunicación serial es algo antiguo pero aún es muy utilizado por ser barato y fácil de utilizar. Se utiliza de modo asíncrono para reducir la cantidad de cables. No entrare en mucho detalle sobre el protocolo para ir directo a la práctica. Se utilizaran las librerías que ofrece microchip en C18 para el manejo del USART, son 12 funciones en total:

La descripción y ejemplo completo se pueden consultar en este link, en la sección de “Hardware Peripherial Functions >> USART Functions, Pagina 66”.

1.1. RS-232: LoopBack uC Para este ejemplo se busca realizar una comunicación serial rs-232 entre el mismo uC, mandando datos y recibiéndolos el mismo para verificar la comunicación. La velocidad será de 115.2k. Las entradas serán:   

Un botón para iniciar la prueba. El número de paquetes a enviar (constante). El tiempo límite para regresar el paquete (constante).

Debe mostrar los siguientes datos en un LCD 20x4:   

Paquetes enviados. Paquetes recibidos. Paquetes perdidos, tanto por Overrun y por Frame.

Para generar un baud rate de 115, 200 para un oscilador interno de 32MHz debemos:   

SYNC = 0 (Asíncrono) BRGH = 1 (Velocidad alta) Para calcular el valor de n para BRG16 = 0 (8 bits) es: o o o

= 0.02124 = 2.1241 %


Omar Gurrola 

09/29/13

http://www.proprojects.wordpress.com

Para calcular el valor de n para BRG16 = 1 (16 bits) es: o o o

= 0.00644 = 0.644 %

Con BRG16 = 1 y n = 68 se tiene el menor error por lo que se utilizara como configuración. main.c /* * * * * * * * * * * * * * * * * * * * * * */

Copyright (c) 2011-2013, http://www.proprojects.wordpress.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1.- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2.- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/23/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include "pic18f14k50_timers.h" #include <stdio.h> #include <usart.h> /** DECLARATIONS ***************************************************/ #define PACKAGE 0b10101010 #define NUMBER_PACKAGES 200 #define TIMEOUT_US 200 /** VARIABLES ******************************************************/ /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

#pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ s8 String[21]; u8 RxOK; u8 RxFail, FE, OE; u8 TO; u8 Ctr; SetIntClockTo32MHz(); // LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" Pro Projects lcd_goto(2,1); lcd_write_pgm(" RS232: LoopBack

"); ");

// Inputs Config OpenInRA5(); OpenInRB5(); OpenOutRB7(); // EUSART Config baudUSART(

OpenUSART(

// Timer Config OpenTmrT0(); StopT0(); Set16BitsT0(); UsePSAT0(); SetPST0(2); INTT0Disable();

BAUD_IDLE_CLK_HIGH & BAUD_16_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF ); USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 68 );

// // // //

High on idle 16b Disable auto-wake-up Disable auto-baud-rate

// // // // // // //

Tx Int off Rx Int off Asynchronous 8bit Cont High baud rate for 115,200 bps ~ 0.644% Error

// 1:8

while(true){ if(ReadRA5() == 1){ Waitmsx(25); if(ReadRA5() == 1){ RxFail = FE = OE = RxOK= TO = 0; for(Ctr = 0; Ctr < NUMBER_PACKAGES; Ctr++){ // Send package to test WriteUSART(PACKAGE); // Wait to send complete while(BusyUSART()); // Wait for data or timeout to complete StartT0(); Write16bT0(65536-TIMEOUT_US); while(!DataRdyUSART() && INTT0Flag == 0); StopT0(); if(INTT0Flag == 1){ TO++; INTT0FlagClear(); } else { if(ReadUSART() == PACKAGE){ RxOK++; } else{


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

if(USART_Status.OVERRUN_ERROR){ OE++; // Clear overrun error before continue // Reseting the RX RCSTAbits.CREN = 0; RCSTAbits.CREN = 1; } else if(USART_Status.FRAME_ERROR){ FE++; } else{ RxFail++; } } } // Update data sprintf(String, "T: %.3hhu OK: %.3hhu",NUMBER_PACKAGES,RxOK); lcd_goto(3,1); lcd_write(&String[0]); sprintf(String, "E%.3hhu O%.3hhu F%.3hhu T%.3hhu",RxFail,OE,FE,TO); lcd_goto(4,1); lcd_write(&String[0]); } } } } // end while } // end main()

Diagrama Esquematico:


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

Circuito Armado:

1.2.

RS-232: Comunicación PC <-> uC (LoopBack)

Utilizaremos una velocidad de 9,600 bps, pero esta vez el uC se convertirá en un LoopBack para la PC, de tal manera que cualquier dato que mande la PC el uC lo regresara. Los niveles lógicos del uC son TTL de 0v-5v y los del puerto serie de la PC son +/- 3v-15v por lo que necesitamos un IC que se encargue de esta conversión y el MAX232 es perfecto para esta tarea. También se puede utilizar un adaptador USB a TTL para facilitar la conexión principalmente en computadoras que ya no disponen de puerto serial.


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

El diagrama de c贸mo conectar el max232 es el siguiente para m谩s informaci贸n lo puedes consultar aqu铆:

main.c /* * * * * * * * * * * * * * * * * * * * * * */

Copyright (c) 2011-2013, http://www.proprojects.wordpress.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1.- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2.- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/24/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h"


Omar Gurrola #include #include #include #include

09/29/13

http://www.proprojects.wordpress.com

"pic18f14k50_io.h" "stdvars.h" "wait.h" <usart.h>

/** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ u8 t; SetIntClockTo32MHz(); // Inputs Config OpenInRB5(); OpenOutRB7(); // EUSART Config baudUSART(

BAUD_IDLE_CLK_LOW & BAUD_16_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF ); OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 832 ); BAUDCONbits.DTRXP = 0; while(true){ while(!DataRdyUSART()); WriteUSART(ReadUSART()); while(BusyUSART()); } // end while } // end main()

// Idle // 16b // Disable auto-wake-up // Disable auto-baud-rate // Tx Int off // Rx Int off // Asynchronous // 8bit // Cont // High baud rate // for 9,600 bps // We need to define polarity of RX, 0 = Low idle

// Wait for data // Read and send // Wait for send to finish


Omar Gurrola Diagrama Esquematico:

Circuito Armado:

09/29/13

http://www.proprojects.wordpress.com


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

1.3. RS-232: Control de LCD por PC Este ejemplo es m谩s complicado ya que se busca controlar el LCD desde la PC, utilizando el uC por serial. Se tiene que implementar un peque帽o protocolo de comunicaci贸n entre PC y uC para garantizar su correcto funcionamiento. La aplicaci贸n de la PC se desarrollara en C# con una clase e interfaz grafica.

main.c /* * * * * * * * * * * * * * * * * * * * * * */

Copyright (c) 2011-2013, http://www.proprojects.wordpress.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1.- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2.- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/28/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "pic18f14k50_int.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include "pic18f14k50_timers.h" #include <stdio.h> #include <usart.h> /** DECLARATIONS ***************************************************/ #define VERSION "ProProjects_PC_LCD_v1_0" // 30 chars max enum { Found=1, GetVersion, GoToYX, WriteText, AddNewChar, Received,


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

ClearScreen=7, CursorReturnHome, DisplayOn, DisplayOff, CursorOn, CursorOff, CursorBlinkingOn, CursorBlinkingOff, BackLightOn, BackLightOff }; /** VARIABLES ******************************************************/

/** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); void SerialRespond(void); void ReadStringUSART(s8 *); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ u8 r,x,y; s8 String[21]; SetIntClockTo32MHz(); // LCD lcd_initialize(); // Inputs Config OpenInRB5(); OpenOutRB7(); // EUSART Config baudUSART(

BAUD_IDLE_CLK_LOW & BAUD_16_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF ); OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 832 ); BAUDCONbits.DTRXP = 0; while(true){ while(!DataRdyUSART()); r = ReadUSART(); if(r > 0 && r < 17) { SerialRespond();

// Wait for data // Cmd received?

// // // //

Idle 16b Disable auto-wake-up Disable auto-baud-rate

// // // // // // //

Tx Int off Rx Int off Asynchronous 8bit Cont High baud rate for 9,600 bps

// We need to define polarity of RX, 0 = Low idle


Omar Gurrola

09/29/13 switch(r){ case GetVersion: putrsUSART(VERSION); break; case GoToYX: while(!DataRdyUSART()); y = ReadUSART(); while(!DataRdyUSART()); x = ReadUSART(); SerialRespond(); lcd_goto(y,x); break; case WriteText: ReadStringUSART(&String[0]); SerialRespond(); lcd_write(&String[0]); break; case ClearScreen: lcd_clear(); break; case CursorReturnHome: lcd_return_home(); break; case DisplayOn: lcd_display_on(); break; case DisplayOff: lcd_display_off(); break; case CursorOn: lcd_cursor_on(); break; case CursorOff: lcd_cursor_off(); break; case CursorBlinkingOn: lcd_blinking_on(); break; case CursorBlinkingOff: lcd_blinking_off(); break; case BackLightOn: lcd_backlight_on(); break; case BackLightOff: lcd_backlight_off(); break; } } }

} void SerialRespond(void){ WriteUSART(Received); while(BusyUSART()); }

// Respond // Wait

void ReadStringUSART(s8 *Str){ do{ while(!DataRdyUSART()); *Str = getcUSART(); Str++; }while(*(Str-1) != '\0'); } C# - LCD.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Ports; using System.Threading; namespace PP_PC_LCD { class LCD { SerialPort LCDSerial; const int ByteDelayMS = 10; public enum LCDCommand { ClearScreen=7, CursorReturnHome,

http://www.proprojects.wordpress.com


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

DisplayOn, DisplayOff, CursorOn, CursorOff, CursorBlinkingOn, CursorBlinkingOff, BackLightOn, BackLightOff }; private enum CTRCommand { Found=1, GetVersion, GoToYX, WriteText, AddNewChar, Received }; public LCD(){ LCDSerial = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One); } public LCD(SerialPort sp){ LCDSerial = sp; } public LCD(int baudrate, Parity p, int bits, StopBits sb){ LCDSerial = new SerialPort("COM1", baudrate, p, bits, sb); } public void FindDevice(ref String Port){ // Serial ports detected? if (SerialPort.GetPortNames().Count() != 0) { foreach (String PortName in SerialPort.GetPortNames()) { // Find LCD Device LCDSerial.PortName = PortName; try { LCDSerial.Open(); SendCommand(CTRCommand.Found); Port = PortName; LCDSerial.NewLine = "\0"; return; } catch (Exception ex) { LCDSerial.Close(); } } throw new Exception("Can't detect LCD device on any serial port!!"); } else { throw new Exception("Can't detect any serial port on this computer!!"); } } public void CloseSerialPort(){ LCDSerial.Close(); } public String GetVersion(){ SendCommand(CTRCommand.GetVersion); Thread.Sleep(ByteDelayMS * 30); // Max 30 chars to read if(LCDSerial.BytesToRead > 0) { return LCDSerial.ReadLine(); } else { throw new Exception("Can't get version!!"); } } public void CursorGoTo(Byte y, Byte x) { if ((y > 0 && y < 5) && (x > 0 && y < 21)) { SendCommand(CTRCommand.GoToYX); // Send cmd first LCDSerial.Write(new Byte[] { y, x }, 0, 2); Thread.Sleep(ByteDelayMS * 3); // Wait ReceivedOK(); } else { throw new Exception("Incorrect Coordinates (y = 1-4, x = 1-20)"); }


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

} public void SendText(String Txt) { SendCommand(CTRCommand.WriteText); // Send write cmd first LCDSerial.WriteLine(Txt); // Send text with newline Thread.Sleep(ByteDelayMS * (Txt.Length + 1)); // Wait for text to be send and receive response ReceivedOK(); } public void SendCommand(LCDCommand cmd) { if(LCDSerial.IsOpen){ LCDSerial.Write(new Byte[] {(Byte)cmd},0,1); // Send command Thread.Sleep(ByteDelayMS * 2); // Wait for 2 bytes time ReceivedOK(); } else { throw new Exception("No serial port defined!!"); } } private void SendCommand(CTRCommand cmd) { if(LCDSerial.IsOpen){ LCDSerial.Write(new Byte[] {(Byte)cmd},0,1); // Send command Thread.Sleep(ByteDelayMS * 2); // Wait for 2 bytes time ReceivedOK(); } else { throw new Exception("No serial port defined!!"); } } private void ReceivedOK() { if(LCDSerial.BytesToRead > 0 && LCDSerial.ReadByte() == (Byte)CTRCommand.Received) //Read response return; // TX and RX OK else throw new Exception("No response from device!!"); } } }

Diagrama Esquematico:


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

Circuito Armado:

1.4. RS-232: Registro de Eventos con printf() Utilizar el puerto serial como registro de eventos o debug es algo muy practico, ya que nos permite enviar texto y datos a una termina o programa en la PC. Esto nos permite debugear el programa o utilizar la PC como pantalla en caso necesario. Primero se debe configurar el puerto serie y en lugar de utilizar putrsUSART o putsUSART para enviar datos utilizamos printf(). Por default la función printf() envía los datos al puerto serial, por lo que no hay que realizar ningún ajuste adicional. main.c /* * * * * * * * * * * * * * * * * * * * * *

Copyright (c) 2011-2013, http://www.proprojects.wordpress.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1.- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2.- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Omar Gurrola

09/29/13

http://www.proprojects.wordpress.com

*/ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 05/29/13 Initial version *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <usart.h> #include <stdio.h> #include <string.h> /** DECLARATIONS ***************************************************/ /** VARIABLES ******************************************************/ s8 StrTmp[81]; /** PROTOTYPES *****************************************************/ void HighPriorityISR(void); void LowPriorityISR(void); void CharFill(s8,u8,s8*); void CenterString(u8,rom s8*,s8*); /** Interrupt Service Routines (ISR)********************************/ #pragma code HP_ISR=0x0008 void HighInterruptVector(void){ _asm goto HighPriorityISR _endasm } #pragma code LP_ISR=0x0018 void LowInterruptVector(void){ _asm goto LowPriorityISR _endasm } #pragma code // Forces the code below this line to be put into the code section #pragma interrupt HighPriorityISR void HighPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR(void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section void main(void){ SetIntClockTo32MHz(); // Inputs Config OpenInRB5(); OpenOutRB7(); // EUSART Config baudUSART(

OpenUSART(

BAUD_IDLE_CLK_LOW & BAUD_16_BIT_RATE & BAUD_WAKEUP_OFF & BAUD_AUTO_OFF ); USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,

// // // //

High on idle 16b Disable auto-wake-up Disable auto-baud-rate

// // // // // //

Tx Int off Rx Int off Asynchronous 8bit Cont High baud rate


Omar Gurrola

09/29/13 832 );

http://www.proprojects.wordpress.com

// for 9,600 bps

while(true){ #define FRAME_SIZE 40 CharFill('*',FRAME_SIZE,&StrTmp[0]); printf("%s\n\r",StrTmp); CenterString(FRAME_SIZE,"www.proprojects.wordpress.com",&StrTmp[0]); printf("%s\n\r",StrTmp); CenterString(FRAME_SIZE,"Log Application Using RS-232",&StrTmp[0]); printf("%s\n\r",StrTmp); CenterString(FRAME_SIZE,"05/29/13",&StrTmp[0]); printf("%s\n\r",StrTmp); CharFill('*',FRAME_SIZE,&StrTmp[0]); printf("%s\n\r",StrTmp); // Conversiones para printf(), fprintf(), sprintf(), vfprintf(), vprintf() y vsprintf() printf("%% \\ \' \" \? \t \n \0"); // \t = TAB, \r = Retorno, \n = Nueva línea, \0 = Nulo printf("%c, %c, %c\n\r",0,255,'A'); // Carácter, unsigned char printf("%d, %i\n\r",(int)-32767,(int)32767); // Decimal con signo, int printf("%u, %u\n\r",(unsigned int)0,(unsigned int)65535);// Decimal sin signo, unsigned int printf("%o, %o\n\r",(unsigned int)0,(unsigned int)65535);// Octal, unsigned int printf("%b, %B\n\r",(unsigned int)0,(unsigned int)65535);// Binario, unsigned int printf("%x, %X\n\r",(unsigned int)0,(unsigned int)65535);// Hex, x = min, X = may, unsigned int printf("%p, %P\n\r",(unsigned int)0,(unsigned int)65535);// Puntero a NRAM o ROM, p = x, P = X, 16-b printf("%Hp, %HP\n\r",(unsigned short long)0,(unsigned short long)16777215);// Pun. FRAM o ROM, 24-b printf("%hhd, %hhi\n\r",(char)-127,(char)127); // hhd, hhi = signed char printf("%hhu, %hhu\n\r",(unsigned char)0,(unsigned char)255); // hhu = unsigned char printf("%hho, %hho\n\r",(unsigned char)0,(unsigned char)255); // hho = unsigned char printf("%hhb, %hhB\n\r",(unsigned char)0,(unsigned char)255); // hhb, hhB = unsigned char printf("%hhx, %hhX\n\r",(unsigned char)0,(unsigned char)255); // hhx, hhX = unsigned char printf("%hhp, %hhP\n\r",(unsigned int)0,(unsigned int)65535); // hhp, hhP = unsigned int (pon. uc) // h,[t,z] (16b) espera que el valor a convertir sea int o unsigned int (por default es así es) printf("%hd, %hi\n\r",(int)-32767,(int)32767); // hd, hi = signed int printf("%hu, %hu\n\r",(unsigned int)0,(unsigned int)65535); // hu = unsigned int printf("%ho, %ho\n\r",(unsigned int)0,(unsigned int)65535); // ho = unsigned int printf("%hb, %hB\n\r",(unsigned int)0,(unsigned int)65535); // hb, hB = unsigned int printf("%hx, %hX\n\r",(unsigned int)0,(unsigned int)65535); // hx, hX = unsigned int printf("%hp, %hP\n\r",(unsigned int)0,(unsigned int)65535); // hp, hP = unsigned int (0-FFFF) // H,[T,Z] (24b) espera que el valor a convertir sea short long o unsigned short long printf("%Hd, %Hi\n\r",(short long)-8388607,(short long)8388607); // Hd, Hi = sl printf("%Hu, %Hu\n\r",(unsigned short long)0,(unsigned short long)16777215); // Hu = usl printf("%Ho, %Ho\n\r",(unsigned short long)0,(unsigned short long)16777215); // Ho = usl printf("%Hb, %HB\n\r",(unsigned short long)0,(unsigned short long)16777215); // Hb, HB = usl printf("%Hx, %HX\n\r",(unsigned short long)0,(unsigned short long)16777215); // Hx, HX = usl printf("%Hp, %HP\n\r",(unsigned short long)0,(unsigned short long)16777215); // Hp, HP = usl // l,[j] (32b) espera que el valor a convertir sea long o unsigned long printf("%ld, %li\n\r",(long)-2147483647,(long)2147483647); // ld, li = long printf("%lu, %lu\n\r",(unsigned long)0,(unsigned long)4294967295); // lu = unsigned long printf("%lo, %lo\n\r",(unsigned long)0,(unsigned long)4294967295); // Ho = unsigned long printf("%lb, %lB\n\r",(unsigned long)0,(unsigned long)4294967295); // Hb, HB = unsigned long printf("%lx, %lX\n\r",(unsigned long)0,(unsigned long)4294967295); // Hx, HX = unsigned long // Ancho del campo para printf(), fprintf(), sprintf(), vfprintf(), vprintf() y vsprintf() // Constante para definir el ancho (Se rellena con espacio) printf("%16c, %16c\n\r", 'a','b'); // Carácter printf("%16d, %16i\n\r",(int)-32767,(int)32767); // Entero con signo printf("%16u, %16u\n\r",(unsigned int)0,(unsigned int)65535); // Entero sin signo printf("%16o, %16o\n\r",(unsigned int)0,(unsigned int)65535); // Octal printf("%16b, %16B\n\r",(unsigned int)0,(unsigned int)65535); // Binario printf("%16x, %16X\n\r",(unsigned int)0,(unsigned int)65535); // Hexadecimal printf("%16p, %16P\n\r",(unsigned int)0,(unsigned int)65535); // Puntero RAM o NROM printf("%16Hp, %16HP\n\r",(unsigned short long)0,(unsigned short long)4294967295);// Puntero FROM // * Para definir el ancho durante la ejecución printf("%*c, %*c\n\r",16,'a',16,'b'); // Carácter printf("%*d, %*i\n\r",16,(int)-32767,16,(int)32767); // Entero con signo printf("%*u, %*u\n\r",16,(unsigned int)0,16,(unsigned int)65535); // Entero sin signo printf("%*o, %*o\n\r",16,(unsigned int)0,16,(unsigned int)65535); // Octal printf("%*b, %*B\n\r",16,(unsigned int)0,16,(unsigned int)65535); // Binario printf("%*x, %*X\n\r",16,(unsigned int)0,16,(unsigned int)65535); // Hexadecimal printf("%*p, %*P\n\r",16,(unsigned int)0,16,(unsigned int)65535); // Puntero RAM o NROM printf("%*Hp, %*HP\n\r",16,(unsigned short long)0,16,(unsigned short long)4294967295); // Pun. FROM CharFill(' ',FRAME_SIZE,&StrTmp[0]); printf("%s\n\r",StrTmp); CharFill(' ',FRAME_SIZE,&StrTmp[0]); printf("%s\n\r",StrTmp); while(true); // Lock } // end while } // end main() void CharFill(s8 Char,u8 Number, s8* String){ u8 t; for(t = 0; t < Number; t++){ *String = Char; String++; } *String = '\0'; // Null }


Omar Gurrola

09/29/13

void CenterString(u8 Frame, rom s8* romString, s8* pString){ u8 Spc = (Frame-strlenpgm(romString))/2; CharFill(' ',Spc,pString); strcatpgm2ram(pString,romString); }

Diagrama Esquematico:

http://www.proprojects.wordpress.com


Omar Gurrola

09/29/13

Circuito Armado:

Referencias 

Microchip, “PIC18F/LF1XK50 Data Sheet”, 2010, http://ww1.microchip.com/downloads/en/DeviceDoc/41350E.pdf

http://www.proprojects.wordpress.com


PIC18F14K50: EUSART (SERIAL)