USB to RS232 adapter


Closed Thread
Results 1 to 20 of 20
  1. #1
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default USB to RS232 adapter

    Is it possible to use a PIC18F2550 as a USB to RS232 adapter with PBP by using the CDC mode?

  2. #2
    Join Date
    Jan 2007
    Posts
    70

    Default

    the microchip site has firmware to make a USB PIC into a serial convertor. It is fairly well documented. somewhere on the site

    www.microchip.com

    it is one of the first things i learned about when i began investigating PIC USB

    -R

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Or, if you wanted to stick with PicBasic, you could try the usbcdc.bas example in the USB18 folder.

    DT

  4. #4
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    I have looked at booth but they are incomplete.

    I have tried to capture data from the RS232 port on the pic and output it to the USB and also from the USB to the RS232 with no sucess.

    All examples are just on how to emulate the CDC.

    I basically need a USB to RS232 adapter like those you can buy in any store.

    I have tons of these 18F2550 chips and would rather use them to convert my exsisting projects instead of going and buying some.

  5. #5
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Ok, I got it to go from USB to the RS232 but I still cannot get the RS232 to USB to work. Here is the code I have so far.

    Code:
    DEFINE  OSC 48
    
    INCLUDE "modedefs.bas"
    
    Buffer   VAR BYTE[16]
    Cnt      VAR BYTE
    B0       VAR BYTE
    
    PIC_TX   VAR PORTC.6     ' Transmit Pin
    PIC_RX   VAR PORTC.7     ' Receive Pin
    
    ADCON1 = 15              ' Set all I/Os to Digital
    INTCON2.7 = 1            ' Disable PortB Pullups         
    CMCON = 7                ' Disable Comparators
    
    USBInit
    
    ' Main Program Loop
    MainLoop:
        USBService           ' Must service USB regularly
        cnt = 16
        USBIn 3, Buffer, Cnt, MainLoop
    
        SEROUT2 PIC_TX,84,[STR Buffer\Cnt]
        
    Get_RS232_Data:
        SERIN PIC_RX,T9600,100,Get_RS232_Data_Timeout,B0
        Buffer[0] = B0
        Cnt = 1
        GOTO OutLoop
        	
    Get_RS232_Data_Timeout:
        Buffer[0] = 0
        Cnt = 0
        
    OutLoop:
        USBService          ' Must service USB regularly
    	
        IF Cnt > 0 Then
            USBOut 3, Buffer, Cnt, OutLoop
        ENDIF
    
        GOTO Mainloop

  6. #6
    skimask's Avatar
    skimask Guest

    Default

    Using a MAX232 type chip in the circuit?
    Depending, you might have to use N9600 instead of T9600

  7. #7
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Yes, I am using the MAX232 between the PIC18F2550 and the RS232 port.

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    At a quick glace, there's a couple problems. Maybe more, but haven't tested it yet.

    With the first USBIN, if there isn't any incoming data from USB, it just loops back to MainLoop. It never makes it to SERIN, unless it receives data from USB at the same time.

    You really should use HSERIN. The RS232 data may start while the program is sending or receiving USB data, in which case you would not be able to catch it with SERIN.

    Added: And the 100ms timeout on the SERIN will cause it to lose the USB connection, since it isn't servicing it anymore.

    DT

  9. #9
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Ok, I got it all working now. I took Darrel's advice and switched to using HSERIN and HSEROUT but added the use of hardware interrupts to capture the RS232 data.

    Here's the new code:

    Code:
    DEFINE    OSC 48
    DEFINE    HSER_RCSTA   90h
    DEFINE    HSER_TXSTA   20h
    DEFINE    HSER_BAUD    9600
    DEFINE    HSER_CLROERR 1
    
    INCLUDE "modedefs.bas"
    
    Buffer    VAR BYTE[16]
    Cnt       VAR BYTE
    B0        VAR BYTE
    PIC_TX    VAR PORTC.6     ' Transmit Pin
    PIC_RX    VAR PORTC.7     ' Receive Pin
    LED1A     VAR PORTB.0     ' 2 Color LED #1
    LED1B     VAR PORTB.1
    LED2A     VAR PORTB.2     ' 2 Color LED #2
    LED2B     VAR PORTB.3
    
    ADCON1 = 15               ' Set all I/Os to Digital
    INTCON2.7 = 1             ' Disable PortB Pullups         
    CMCON = 7                 ' Disable Comparators
    
    '-------------------------------------------------------------------------------
    ' Interrupt Settings
    '-------------------------------------------------------------------------------
    RCON.7 = 0                ' Disable Priority Interrupts, 1 to Enable
    
    ' Enable/Disable Interrupts
    INTCON.4 = 0              ' Disable INT0 (PORTB.0)
    INTCON3.3 = 0             ' Disable INT1 (PORTB.1)
    INTCON3.4 = 0             ' Disable INT2 (PORTB.2)
    INTCON.5 = 0              ' Disable TMR0 (Timmer 0)
    INTCON.6 = 1              ' Enable Peripheral Interrupts
    INTCON.7 = 1              ' Enable Global Interrupt Handler
    PIE1.4 = 0                ' Disable USART Transmit Interrupt
    PIE1.5 = 1                ' Enable USART Receive Interrupt
    PIE2.5 = 0                ' Disable USB Interrupt
    
    LOW LED1A                 ' Turn LED #1 Green
    HIGH LED1B
    LOW LED2A                 ' Turn LED #2 Off
    LOW LED2B
    
    PAUSE 500
    
    USBInit
    
    ON INTERRUPT GOTO Main_Interrupt_Handler
    ENABLE INTERRUPT
    
    ' Main Program Loop
    MainLoop:
        USBService            ' Must service USB regularly
        Cnt = 16
        USBIn 3, Buffer, Cnt, MainLoop
    
        HIGH LED2A
        PAUSE 25
    
        HSEROUT [STR Buffer\Cnt]
    
        LOW LED2A
        
        GOTO Mainloop
    	
    	
    '-------------------------------------------------------------------------------
    ' Interrupt Handler
    '-------------------------------------------------------------------------------
        DISABLE INTERRUPT     ' No Interrupts past this point
    Main_Interrupt_Handler:
    
        '---------------------------------------------------------------------------
        ' USART Transmit Interrupt
        '---------------------------------------------------------------------------
        IF PIR1.4 = 1 THEN
            PIR1.4 = 0
        ENDIF
        '---------------------------------------------------------------------------
    
        
        '---------------------------------------------------------------------------
        ' USART Receive Interrupt
        '---------------------------------------------------------------------------
        IF PIR1.5 = 1 THEN
            HIGH LED2B
            PAUSE 25
            
            HSERIN [B0]
            Buffer[0] = B0
            Cnt = 1
        
    OutLoop:
            USBService        ' Must service USB regularly
            USBOut 3, Buffer, Cnt, OutLoop
    
            LOW LED2B
    
            PIR1.5 = 0
        ENDIF
        '---------------------------------------------------------------------------
    
    IntDone:
        RESUME                ' Return to main program
        ENABLE INTERRUPT
    '-------------------------------------------------------------------------------
    
        END

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    That was pretty quick!

    I've been playing with the program here and can say that the two PAUSE 25 statements, have to GO.

    Of course that messes up the LED's, but with the pauses in there, it only picks up every 7 or 8th character when sending continuous data.

    Without them, it works pretty good, but it's still a bit slow.
    Test data of about 1500 bytes takes nearly 3 times as long as it should. Around 1.2 sec.

    I think circular buffers would help speed it up, since it has to wait till it's finished sending the HSEROUT before in can receive more data from the USB. But I guess that depends on how fast you need it to be.

    DT

  11. #11
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Thanks Darrel. I have eliminated the LEDs all together because there is really no need for them. I was testing it by just using a terminal program on 2 computers so I never noticed the speed problem till now. How do I impliment the circular buffers you mentioned?

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Me and my big mouth.

    I wish I had time to work something up, but I've got too many things going on already.

    You might take a look at this post by Joe S.
    http://www.picbasic.co.uk/forum/showthread.php?p=28233

    He's got a buffer in there for serial RX. Should give you a start.
    But you really need to buffer both RX and TX.

    busy busy,
    DT

  13. #13
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Default

    Hi Guys I've been working on the same - I can get a Half duplex data communication going but not full duplex (rs232-> usb and vice versa).

    This program seems to do the trick, but even with the pauses removed I still only achieve a stable data rate at 9600 when sending large text files.

    I'll try using the DT method (DT_int_18) interrupts and see if this speeds things up.

    Circular buffers? The mind boggles!

    Cheers

  14. #14
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898

    Default

    i doubt it would be if you used the EUSART but may worth to try..

    PicMultiCalc gaves me...
    Code:
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_SPBRG 225 ' 9600 Baud @ 48MHz, 0.0%
    SPBRGH = 4
    BAUDCON.3 = 1         ' Enable 16 bit baudrate generator
    mixing INT_18 and asm would certainly have some great effect.
    Last edited by mister_e; - 26th February 2007 at 03:33.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  15. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    I can get a Half duplex data communication going but not full duplex
    USB is a Half-Duplex protocol. There's no way to have TRUE full-duplex. 2-wires, differential levels, can only do one thing at a time.

    However, with the proper buffers in place, you can make it seem like it's "FULL", in that you can send and receive at the same time from the USART. But it never truely will be Full-duplex for the USB.

    DT

  16. #16
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Default

    Yeah your right,

    I guess what I should have said was this.

    I can transmit in only one direction usb->usart, or usart->usb, not in the same program. Never mind now. I'm confused... ;(

    Using Int_18 has def. sped things up!

    Now I can transfer from USB->Usart successfully at 57600 baud, however Usart->Usb still only good enough at 9600 when sending text file. (Sending single key strokes is fine both directions at any speed).

    I figure that the usart buffer needs to be increased as this is the bottle neck.


    Cheers

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    I think you'll find that while from USB to USART works fine. It's massively buffered by the PC. If you were to send the same text file directly to a com port at 57600, it would take 1/3 as long to transmit.

    This is because the PIC waits untill the last buffer full of data is sent via HSEROUT, before allowing it to receive more from the USB. The PC does the buffering, instead of the PIC.

    And on the other side of it. This program is only sending 1 byte at a time to the USB. You can send up to 64. If it were buffered at the PIC, it could save incomming 232 data while it's busy sending to USB, then send a larger packet on the next time around. I think this would greatly improve the overall speed.

    Theoretically, you should be able to run quasi-full-duplex at 250kbaud, without any problems.

    DT

  18. #18
    Join Date
    Jan 2006
    Location
    Toronto
    Posts
    109

    Default

    Squibcakes: Is it possible to get a copy of the source you have working with the DT interrupts? I greatly apreciate all the help you guys are giving me.

    Thanks.

  19. #19
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Talking

    Sure thing brother,

    Play around with the baud rates and see what max data speed you get. 250K would be awesome! but I think some sought of hardware hand shaking is needed to get up to those speeds. Hahaha

    Anyway, first step I think is to increase the buffer size form 1 char to as DT said, about 64 Chars.

    Code:
    '****************************************************************
    
        INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
        INCLUDE "ReEnterPBP-18.bas"     ; Include if using PBP interrupts
    
    '   USB sample program for PIC18F4550 CDC serial port emulation
    
    '   Compilation of this program requires that specific support files be
    '   available in the SOURCE DIRECTORY!!  
    
    '   18F*.BAS	Device header files that use the USB libraries
    '	CDCDESC.ASM	Descriptor file	for CDC	serial demo
    '	JADESC.ASM	Descriptor file	for Jan	Axelson	demo
    '	MOUSDESC.ASM	Descriptor file	for mouse demo
    '	PBPCDC.INF	INF file for the CDC serial driver
    '	USB.TXT		This file
    '	USB18.ASM	USB assembler file
    '	USB18.INC	USB definitions	file
    '	USB18MEM.ASM	USB memory allocation file
    '	USBCDC.BAS	CDC serial demo	BASIC program file
    '	USBDESC.ASM	Include	file for descriptor file
    
    '   You WILL also need to modify the
    '   file USBDESC.ASM so that the only line used is -> include "CDCDESC.ASM"
    
    '   MUST use the 4 MHz xtal for this.
    '   this program receives data via usb virtual port then sends out via serial
    '   usart.
       
        
        '   USART module
        '   ------------
        Define    OSC     48
        DEFINE    HSER_RCSTA   90h
        DEFINE    HSER_TXSTA   20h
        DEFINE    HSER_BAUD    4800
        DEFINE    HSER_CLROERR 1
        
        '   USB module
        '   ----------    
        UCFG    var byte EXT        ' include UCFG register... Yeah Melabs didn't :o(
        ucfg    =   %00010100       ' enable internal USB pull-up, Full speed USB 
        
        '   ANALOG I/O CONFIG
        '   -----------------
        ADCON1 = 15               ' Set all I/Os to Digital         
        CMCON = 7                 ' Disable Comparator
        
        Buffer    VAR BYTE[16]
        Cnt       VAR BYTE
        B0        VAR BYTE
           
    ASM
        INT_LIST  macro    ; IntSource,Label,Type,ResetFlag?
            INT_Handler    RX_INT,_SendUsB,PBP,yes
        endm
        INT_CREATE               ; Creates the interrupt processor
        INT_ENABLE   RX_INT     ; enable external (RX) interrupts
    ENDASM
    
        USBInit
        
        ' Main Program Loop
    
    MainLoop:
        USBService            ' Must service USB regularly
        Cnt = 16
        USBIn 3, Buffer, Cnt, MainLoop
        
        HSEROUT [STR Buffer\Cnt]
        GOTO Mainloop
    	
    '---[RX_INT - interrupt handler]------------------------------------------------
    ' PROGRAM COMES HERE WHEN DATA ENTERS THE USART PORT
    SendUsB:                        
            HSERIN [B0]
            Buffer[0] = b0
            cnt = 1
        
    OutLoop:
            USBService        ' Must service USB regularly
            USBOut 3, Buffer, Cnt, OutLoop
            
    @ INT_RETURN
    Cheers

  20. #20
    Join Date
    Sep 2006
    Location
    Venezuela - Caracas
    Posts
    48

    Default i don't send to pc data recived from pc

    Data of hserin is ok

    ............
    USBService ' Must service USB regularly

    Cnt = 10
    USBIn 3, Buffer, Cnt, MainLoop

    ' Send to pc data recived from pc
    GOTO OutLoop <---------not work, not send buffer

    GOTO Mainloop
    .........

    Code:
    INCLUDE "modedefs.bas"
    
       ' Configuração
       asm
          __CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L  
                             ;              ;                      ; USB clock source comes from the 96 MHz PLL divided by 2
                             ;              ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
                             ; No prescale (4 MHz oscillator input drives PLL directly)
    
    
          __CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H 
                                   ;                  ;               ; Oscillator Switchover mode disabled
                                   ;                  ; Fail-Safe Clock Monitor disabled
                                   ; XT oscillator, PLL enabled, XT used by USB
          __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L  & _BORV_2_2L  & _VREGEN_ON_2L   
          __CONFIG _CONFIG2H, _WDT_OFF_2H 
          __CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H 
          __CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L 
          __CONFIG _CONFIG5L, _CP0_ON_5L & _CP1_ON_5L & _CP2_ON_5L & _CP3_ON_5L
          __CONFIG _CONFIG5H, _CPB_ON_5H      
       endasm
    
       DEFINE    OSC 48
       
       DEFINE    HSER_RCSTA   90h
       DEFINE    HSER_TXSTA   20h
       DEFINE    HSER_BAUD    9600
       DEFINE    HSER_CLROERR 1
    
       Buffer    VAR BYTE[16]
       Cnt       VAR BYTE
       A         VAR BYTE
       B         VAR BYTE
       C         VAR BYTE
    
    
       PIC_TX    VAR PORTC.6     ' Transmit Pin
       PIC_RX    VAR PORTC.7     ' Receive Pin
    
       ADCON1 = 15               ' Set all I/Os to Digital
       INTCON2.7 = 1             ' Disable PortB Pullups         
       CMCON = 7                 ' Disable Comparators
    
       ' Interrupt Settings
       RCON.7 = 0                ' Disable Priority Interrupts, 1 to Enable
    
       ' Enable/Disable Interrupts
       INTCON.4 = 0              ' Disable INT0 (PORTB.0)
       INTCON3.3 = 0             ' Disable INT1 (PORTB.1)
       INTCON3.4 = 0             ' Disable INT2 (PORTB.2)
       INTCON.5 = 0              ' Disable TMR0 (Timmer 0)
    
       INTCON.6 = 1              ' Enable Peripheral Interrupts
       INTCON.7 = 1              ' Enable Global Interrupt Handler
    
       PIE1.4 = 0                ' Disable USART Transmit Interrupt
       PIE1.5 = 1                ' Enable USART Receive Interrupt
       PIE2.5 = 0                ' Disable USB Interrupt
    
       PAUSE 1000
    
       USBInit
    
       ON INTERRUPT GOTO Main_Interrupt_Handler
       ENABLE INTERRUPT
    
    ' Main Program Loop
    MainLoop:
       USBService            ' Must service USB regularly
       
       Cnt = 10
       USBIn 3, Buffer, Cnt, MainLoop
       
       ' Send to pc data recived from pc
       GOTO OutLoop    
       
    GOTO Mainloop
    	
    ' Interrupt Handler
    '-------------------------------------------------------------------------------
       DISABLE INTERRUPT     ' No Interrupts past this point
    Main_Interrupt_Handler:
       ' USART Transmit Interrupt
       IF PIR1.4 = 1 THEN
          PIR1.4 = 0
       ENDIF
    
       ' USART Receive Interrupt
       IF PIR1.5 = 1 THEN
          HSERIN [A, B, C]
     
          Buffer[0] = A
          Buffer[1] = B
          Buffer[2] = C
          Buffer[3] = 13
          Buffer[4] = 10
          Cnt = 4
        
    OutLoop:
          USBService        ' Must service USB regularly
          USBOut 3, Buffer, Cnt, OutLoop
    
          PIR1.5 = 0
       ENDIF
    
    '-------------------------------------------------------------------------------
    IntDone:
       RESUME                ' Return to main program
       ENABLE INTERRUPT
       
    '-------------------------------------------------------------------------------
    END
    ..: Don't worry, be happy :..

Similar Threads

  1. USB CDC Communications for Dummies!
    By Squibcakes in forum USB
    Replies: 104
    Last Post: - 15th January 2014, 13:43
  2. USB to rs232 emulator
    By Pic2008 in forum USB
    Replies: 0
    Last Post: - 5th March 2010, 15:54
  3. Simple USB Comms Problem
    By awmt102 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 6th January 2010, 20:17
  4. Bafo USB to serial adapter
    By ardhuru in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 29th July 2006, 18:48
  5. USB to Serial Adapter with 9.6v
    By serandre in forum Serial
    Replies: 3
    Last Post: - 10th May 2006, 20:16

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts