Autor Tema: Comunicacion Serie FTDI 18f4550  (Leído 5160 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado c4_esp_VR

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
    • www.muchotrasto.com
Comunicacion Serie FTDI 18f4550
« en: 07 de Enero de 2007, 07:12:53 »
Hola compañeros:

Llevo 3 dias atascado por una cosa tan simple como una comunicación serie entre dos PIC...pero esta vez algo diferente de lo que la gente suele preguntar, una comunicación entre el FTD232BM y un microcontrolador de microchip, vamos a hacer una breve introducción para que todos aprendamos con mi duda:

El FTD232BM es un microcontrolador de la empresa FTDI, este mediante un par de resistencias es capaz de realizar un VCP (Virtual Com Port) o lo que es lo mismo es un transciever que emula un puerto USB pero se maneja como un puerto RS232, en conclusión, sacamos la información por el puerto USB pero realizamos la programación de nuestra interface en el PC como si fuese un 232 que de eso hay información a cantidad, de hecho el código es algo tan simple como esto:


Clase PortCOM de C++

#include "PortCOM.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

PortCOM::PortCOM()
{
   idCom=NULL;
}

PortCOM::~PortCOM()
{

}

int PortCOM::Init(CString port)
{
   idCom=CreateFile(port,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
   if(idCom==INVALID_HANDLE_VALUE )
      {   
         idCom=NULL;
         return(PORT_ERROR_CREATEFILE);
      }
   else
      {
      
         GetCommState(idCom, &dcb);
         if(!fSuccess)
         {
           MessageBox(hWnd, "Inicialización puerto serie",
            "ERROR: GetCommState", MB_ICONINFORMATION | MB_OK);
           return false;
         }
         //dcb.BaudRate = CBR_19200;
       dcb.BaudRate = CBR_115200;
         //dcb.BaudRate = CBR_921600;
         dcb.ByteSize = 8;
         dcb.Parity =   NOPARITY;
         dcb.StopBits = ONESTOPBIT;
 
         dcb.fBinary=1;
         dcb.fOutxCtsFlow=0;
         dcb.fOutxDsrFlow=0;
         dcb.fDtrControl=DTR_CONTROL_DISABLE;
         dcb.fDsrSensitivity=0;
         dcb.fTXContinueOnXoff=1;
         dcb.fOutX=0;
         dcb.fInX=0;
         dcb.fErrorChar=0;
         dcb.fNull=0;
         dcb.fRtsControl=RTS_CONTROL_DISABLE;
         dcb.fAbortOnError=1;
         dcb.XonLim=2048;
         dcb.XoffLim=512;
         dcb.XonChar=17;
         dcb.XoffChar=19;
         dcb.ErrorChar=0;
         dcb.EofChar=0;
         dcb.EvtChar=0;

         dcb.DCBlength=sizeof(dcb);
         int ret=SetCommState(idCom,&dcb);
         if(ret==0)
            {
               int err=GetLastError();
               CloseHandle(idCom);
               idCom=NULL;
               return(PORT_ERROR_SETDCB);
            }
         timeouts.ReadIntervalTimeout=PORT_COMMS_INTERVAL_TIMEOUT;
         timeouts.ReadTotalTimeoutMultiplier=PORT_COMMS_TOTAL_TIMEOUT_MULTIPLIER;
         timeouts.ReadTotalTimeoutConstant=PORT_COMMS_TOTAL_TIMEOUT_CONSTANT;
         timeouts.WriteTotalTimeoutMultiplier=0;
         timeouts.WriteTotalTimeoutConstant=0;
         SetCommTimeouts(idCom,&timeouts);
         return(PORT_OK);
      }
}

int PortCOM::Close()
{
   if(CloseHandle(idCom)!=0)return(PORT_OK);
   else return(PORT_ERROR_CLOSE_HANDLE);
   idCom=NULL;
}

int PortCOM::Send(unsigned long num,/*unsigned char **/PVOID pmessage)
{
   unsigned long written=0;
   if(WriteFile(idCom,pmessage,num,&written,NULL)==0)    return(PORT_ERROR_WRITEFILE);
   if(written!=num) return(PORT_ERROR_WRITENUM);
   //flush(idCom);
   return(PORT_OK);
}

int PortCOM::Receive(unsigned long num, /*unsigned char **/PVOID pmessage)
{
   unsigned long read=0;
   unsigned long read2=0;
   ///LEo un primer cararcter
   if(ReadFile(idCom,pmessage,1,&read2,NULL)==0) return PORT_ERROR_READFILE;
   if(read2!=1)return PORT_ERROR_TIMEOUT;
   //SI lo he leido bien sigo leyendo los que me piden
   if(num>1)//intento leer el resto si lo hay
   {
      if(ReadFile(idCom,pmessage+1,num-1,&read,NULL)==0) return PORT_ERROR_READFILE;
   }
   return(read+1);
}

bool PortCOM::IsPortValid()
{
   if(idCom!=NULL)return(true);
   else return(false);
}

int PortCOM::SetBaud(int baud)
{
   if(baud<1||baud>2)return PORT_ERROR_BAD_PARAMETER;
   if(baud==PORT_COMMS_BAUDS_115200)dcb.BaudRate=CBR_115200;
   if(baud==PORT_COMMS_BAUDS_38400)dcb.BaudRate=CBR_38400;
   if(SetCommState(idCom,&dcb)==0)
      return(PORT_ERROR_SETDCB);
   return(PORT_OK);
}

Donde para enviar datos, pondremos la siguiente función:
Si pulsamos el boton Inicio se inicia el puerto COM3 virtual creado por el FTDI:

void CPrueba1Dlg::OnButtonInicio()
{
   // TODO: Add your control notification handler code here
   com3.Init("COM3");
   com3.IsPortValid();
   com3.SetBaud(115200);   
}

Y cuando le demos a enviar, enviaremos lo que tengamos en el texto

void CPrueba1Dlg::OnButtonEnviar()
{
   // TODO: Add your control notification handler code here

   CString strEnviar;
   int longitudStringEnviar;

   m_Enviar.GetWindowText(strEnviar);

   longitudStringEnviar = strEnviar.GetLength();

   const char* EnviarChar = (LPCTSTR) strEnviar;

   int err1 = com1.Send(1,(unsigned char*) EnviarChar);

   UpdateData(FALSE);

   
}

Los datos recibidos se actualizan cada 1 seg gracias a la función OnTimer:
Dicho tiempo de actualización se adquiere de la función SetTimer(1,1000, NULL);

void CPrueba1Dlg::OnTimer(UINT nIDEvent)
{
   // TODO: Add your message handler code here and/or call default

   CString strRecibir;
   //char RecibirChar[179];
   unsigned char RecibirChar[5];   
   int longitudStringRecibir;

   int err2 = com1.Receive((BYTE)4,RecibirChar);

   strRecibir = RecibirChar;
   m_Recibir.SetWindowText(strRecibir); //Saca en un texto lo recibido

   UpdateData(FALSE);
}

donde com3 es una objeto que adquiere las propiedades de ComPORT:
PortCOM com3;

Bueno esta es la parte de Visual C++

Ahora toca la parte del PIC 18f4550, realizada con CCS:

#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,PLL3,CPUDIV1,VREGEN
#use delay(clock=12000000)

#define use_portb_lcd TRUE         //definir portb lcd
#include<lcd.c>

#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8) //Hay que ponerlo debajo de la instrucción de LCD sino el LCD no funciona
//RTS del FTDI va a dar al RD4 del uc
//CTS del FTDI va a dar al RD5 del uc

int8 recibido=0;

void main(void) {

   lcd_init();
   printf(lcd_putc,"ESPERANDO DATOS");

   while (TRUE)
   {
      if (kbhit())          //si el endpoint de salida contiene datos del host
      {
         recibido=(int8)getch();
         lcd_putc("\f");//LCD en blanco
         printf(LCD_PUTC,"RECIBIDO");
         //printf ("hola");//Envia al PC una cadena de caracteres
         putc(recibido);//Envia al PC un caracter
         if(recibido==0x00)
         {
            printf(LCD_PUTC," DATOS");
         }
      }
   }
}

Con lo que al enviar un dato del PC al PIC, este lo envió pues se enciende el led de enviado y aparece en el LCD RECIBIDO, con lo que algo se ha enviado, y el PIC también responde enviando datos pero son cosas raras como ppIIII…

Con lo que imagino que el error está en el tipo de datos que estoy enviando, pues no se que tipo de dato envía el putc, si es un unsigned char, un char, un BYTE…

Espero que alguien puede echarme una mano pues si esto sale bien realizaré pdf de cómo lo he hecho todo, desde el esquemático de la placa, pasando de cómo configurar el FTDI hasta el programa en Visual C++.

Un saludete C4_ESP.

P.D Si tenéis alguna duda y respecto a esto porque tb estéis interesados no dudéis en postear

Os dejo una foto del cacharrito que nos costó un ojo realizar la placa a doble cara con pistas tan finitas...
« Última modificación: 07 de Enero de 2007, 10:05:33 por c4_esp_VR »

Desconectado Sispic

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1700
    • winpic800
Re: Comunicacion Serie FTDI 18f4550
« Respuesta #1 en: 08 de Enero de 2007, 06:44:51 »
Pero el PIC18F4550 puede funcionar directo al puerto USB y que quede configurado como un puerto virtual tambien , como no lo has aprovechado ?

Desconectado c4_esp_VR

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 735
    • www.muchotrasto.com
Re: Comunicacion Serie FTDI 18f4550
« Respuesta #2 en: 08 de Enero de 2007, 16:50:26 »
Porque la cuestión está en programar como puerto seríe y no como un usb con las librerias mpuslab o como se llamen, por lo principal se debe a que programación en serie lo sabe hacer todo el mundo por su sencillez y por el otro lado porque el micro va a realizar otros procesos como CAD, PWM etc... y sería recargar con muchas interrupciones y muchas aplicaciones a un sólo micro...

Por USB ya sé utilizarlo y estoy probando esto que veo que a la hora de vender algún módulo en las tiendas usan el FTDI y por algo será, además de así probar algo nuevo para luego compartir mi información con los demás.

La solución está clara y es mirar lo que envía con el osciloscopio para ver si lo está haciendo bien, pero ya llevo un mes entre diseño, placa, soldar y programación y ya es mucho tiempo gastado, así que lo dejaré aparcado hasta después de los examenes.

Gracias por tu interes maestro sispic  :-/ :-/ :-/ :-/ :-/ :-/ :-/

Un saludete a la gran comunidad de todopic.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7918
Re: Comunicacion Serie FTDI 18f4550
« Respuesta #3 en: 02 de Marzo de 2007, 13:27:15 »
Pero el PIC18F4550 puede funcionar directo al puerto USB y que quede configurado como un puerto virtual tambien , como no lo has aprovechado ?

Puedes explicar como se hace SISCO?? :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado 5GTT

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 915
Re: Comunicacion Serie FTDI 18f4550
« Respuesta #4 en: 02 de Marzo de 2007, 22:29:11 »
MGLSOFT busca el post de RedPIC sobre el CDC, alli explica como solo el sabe, como emular un puerto serie con la conexion USB.
« Última modificación: 02 de Marzo de 2007, 23:37:25 por 5GTT »

Tutoriales y proyectos de electrónica

Desconectado 5GTT

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 915
Re: Comunicacion Serie FTDI 18f4550
« Respuesta #5 en: 02 de Marzo de 2007, 23:36:59 »

Tutoriales y proyectos de electrónica