2
\$\begingroup\$

I want to know if it's possible to connect a ttl device directly to my PIC18LF4680 for serial communication via USART . I can connect the ttl device directly to my Arduino Uno without issues. This is my hardware :

PIC18LF4680 pin-out

ttl adapter

The ttl device has 6 pins (dtr , rxd , txd , vcc(3.3v or 5v) , cts, gnd) .

I have two different codes snippets below that perform USART communication.

Version one(I) utilizes the "usart.h" peripheral library. Version two(II) uses "TXREG" and "RCREG" for sending and receiving data.

Both versions run well in my virtual environment (proteus 8 professional), but not in the real world environment. Am I missing a step? Do I need a special library? Or is it not possible with this chip?

Version I ---------------------------------------

#include "fuses.h"
#include <p18lf4680.h>
#include <stdio.h>
#include <stdlib.h>
#include <plib/usart.h>


void main(void) {

    TRISB = 0x00;
    OSCCON = 0x76;          // 8mhz (0111 0110)

     LATBbits.LATB4 = 0; 
    LATBbits.LATB1 = 0; 
    LATBbits.LATB0 = 0; 

    unsigned char txt1[] = "Hello World \r\n";
    unsigned char txt2[] = "Enter a number.... \r\n";

    CloseUSART();

    OpenUSART(USART_TX_INT_OFF &
            USART_RX_INT_OFF &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_CONT_RX &
            USART_BRGH_HIGH &
            USART_ADDEN_OFF ,
            52);


    for(int x=0;x<=20;x++){__delay_ms(50);}

    // write/send intro to PC

    while(BusyUSART());
    putsUSART((char *)txt1);

    for(int x=0;x<20;x++){__delay_ms(50);}

    while(BusyUSART());
    putsUSART((char *)txt2);

    for(int x=0;x<20;x++){__delay_ms(50);}


    while(1){
        sdata = ReadUSART();

        switch(sdata){
            case '1':
                LATBbits.LATB4 = 1; 
                LATBbits.LATB1 = 0; 
                LATBbits.LATB0 = 0;

            break;

            case '2':
                LATBbits.LATB4 = 0;
                LATBbits.LATB1 = 1; 
                LATBbits.LATB0 = 0; 

            break;

            case '3':
                LATBbits.LATB4 = 0; 
                LATBbits.LATB1 = 0; 
                LATBbits.LATB0 = 1; 

            break;


            default:
                LATBbits.LATB4 = 0;
                LATBbits.LATB1 = 0;
                LATBbits.LATB0 = 0; 


            break;
        }
    }

}

----------------------------------------------------- Version II--------------------------------------------

#include "fuses.h"
#include <p18lf4680.h>
#include <stdio.h>
#include <stdlib.h>

#define STRLEN 12

volatile unsigned char t;
volatile unsigned char rcindex;
volatile unsigned char rcbuf[STRLEN];

void USART_init(void){

    TXSTAbits.TXEN = 1;     // enable transmitter
    TXSTAbits.BRGH = 1;     // high baud rate mode
    RCSTAbits.CREN = 1;     // enable continous receiving

    // configure I/O pins
    TRISCbits.TRISC7 = 1;     // RX pin is input
    TRISCbits.TRISC6 = 1;     // TX pin is input (automatically configured)

    SPBRG = 52;            

    PIE1bits.RCIE = 1;      // enable USART receive interrupt
    RCSTAbits.SPEN = 1;     // enable USART


}

void USART_putc(unsigned char c)
{
    while (!TXSTAbits.TRMT); // wait until transmit shift register is empty
    TXREG = c;               // write character to TXREG and start transmission
}

void USART_puts(unsigned char *s)
{
    while (*s)
    {
        USART_putc(*s);     // send character pointed to by s
        s++;                // increase pointer location to the next character
    }
}

void main(void) {

    OSCCON = 0x76;          // 8mhz (0111 0110)

    USART_init();

    USART_puts("Init complete! \n");

    INTCONbits.PEIE = 1;    // enable peripheral interrupts
    INTCONbits.GIE = 1;     // enable interrupts

    while(1)
    {

    }

}

void interrupt ISR(void)
{
    if (PIR1bits.RCIF)  // check if receive interrupt has fired
    {
        t = RCREG;      // read received character to buffer

        // check if received character is not new line character
        // and that maximum string length has not been reached
        if ( (t != '\n') && (rcindex < STRLEN) )
        {
            rcbuf[rcindex] = t; // append received character to string
            rcindex++;          // increment string index
        }
        else
        {
            rcindex = 0;        // reset string index
            USART_puts(rcbuf);  // echo received string
        }

        PIR1bits.RCIF = 0;      // reset receive interrupt flag
    }
}

Every and All help is appreciated. Thanks!

\$\endgroup\$
3
  • \$\begingroup\$ check the supply voltage of PIC PIC18LF4680 provided and the voltage level on Tx RX pin of the USB to TTL converter. It looks like, from the image, the USB TTL converter has option to choose the voltage level (3.3 V or 5 V) \$\endgroup\$
    – User323693
    Commented Aug 5, 2016 at 6:14
  • \$\begingroup\$ Yes, I can toggle voltage levels. I'm using 5v. \$\endgroup\$
    – newbie 14
    Commented Aug 7, 2016 at 15:26
  • \$\begingroup\$ Can you show us how you have the devices connected? \$\endgroup\$
    – mjh2007
    Commented Feb 7, 2017 at 15:21

2 Answers 2

1
\$\begingroup\$

talking hardware:

  1. make sure you connect MCLR_ to VDD (directly or by a pullup resistor)
  2. if the pic is running at 5V, use the USB TTL with 5V mode and not 3.3V
  3. you should measure VDD at RC6 if your code initialized UART correctly
  4. make sure your connections are correct. know what RXD and TXD of the converter mean. RXD is the receiver for PC-side or device-side? you can double check that everything is connected right using a voltmeter.

firmware:

  1. make sure your config bits are right, especially oscillator configuration bits. make sure you programmed the pic to use internal oscillator. add a blinking LED to your main just to make sure if your pic is actually "running"

  2. TRISC6 and TRISC7 should be set. Initially after a power-on-reset those bits are set but make sure you don't clear TRISC7 somewhere in your code.

\$\endgroup\$
3
  • \$\begingroup\$ My stand-alone 'blink' programs work, so I believe clock/oscillator configurations are okay. I will try inserting a 'blink' into my main function to see what I get. Thanks. \$\endgroup\$
    – newbie 14
    Commented Aug 7, 2016 at 15:16
  • \$\begingroup\$ More than once I have found the labels on USB converters to be plain wrong. Assume Tx and Rx may be transposed, \$\endgroup\$
    – KalleMP
    Commented Aug 22, 2017 at 18:26
  • 1
    \$\begingroup\$ Per @KalleMP, the Tx (output) pin will show a higher voltage than the Rx (input) pin. \$\endgroup\$
    – gbarry
    Commented Dec 23, 2017 at 18:50
-1
\$\begingroup\$

It's not clear what you mean by "TTL device". Remember that TTL specifies the logic type, in this case transistor to transistor logic.

The question is therefore whether the logic levels and drive levels are compatible enough to connect to the PIC, which uses CMOS logic. The answer is generally yes, as long as both are running from the same supply voltage.

There are 4 cases to look at:

  1. TTL --> PIC, logic low
  2. TTL --> PIC, logic high
  3. TTL <-- PIC, logic low
  4. TTL <-- PIC, logic high

TTL drives actively low, with the maximum voltage being just a few 100 mV at most. Case 1 works fine.

Case 2 is really the only possible problem spot. TTL does drive actively high, but not all the way to the supply. Check the minimum guaranteed voltage when TTL drives high, and the minimum required voltage for the PIC to interpret the input as high. The highest for PIC inputs is usually 80% of Vdd. For a PIC running at 5 V, that is 4 V. If the TTL output can't guarantee 4 V, then either this won't work or you need to add a pullup or something.

Cases 3 and 4 will work with no problem since the PIC CMOS outputs drive close to the power rails in either direction. The TTL logic will have no problem interpreting the CMOS signals correctly.

Since you mentioned the UART, perhaps you are really asking for some kind of converter between the UART signals and elsewhere. If that elsewhere is a COM port of a standard PC, then you want something like my RSLink2:

It connects directly to the PIC UART, power, and ground on the left side, and can be plugged into a PC COM port on the right side (although you'd usually use a RS-232 extension cable).

In this case, the UART signals on the left side also use CMOS logic, so are definitely compatible with the PIC UART signals.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.