PIC16F84A RS232 Communication Problems

Thread Starter

solpic

Joined Jul 23, 2009
25
Hello everyone,

I am trying to implement a half duplex rs232 communication link between my pic16f84a and my PC. It should be at 2400 baud, with 8N1 communication. The only pins on the rs232 connector that I have wired are the signal ground (which I have wired to ground), the data receive pin, and the data transmit pin which are both connected to the pic16f84a. I used the pins from this page http://www.arduino.cc/playground/uploads/Learning/rs232_pinout.gif, after verifying it from other pages, and assumed that the pin's parallel pin on the connector was it's corresponding pin. What I mean is that since the connector's pins are a mirror of the actual pins, I assumed each pin corresponded to it's mirrored pin. I am NOT using a UART so the signals are 0-5V. Pretty much nothing is happening on the computer end. I can get an LED to light up by connecting it to the data receive pin and sending data through /dev/ttyS0 but I could not read from it even after configuring the baud rate with stty speed 2400. Furthermore, whenever I would read from the PC with cat /dev/ttyS0 or while head -c 1 /dev/ttyS0; do : ;done the LED attached to the data receive pin on my breadboard would get much brighter. I tried inverting the bits and whatnot and that didn't work. So here is my code, compiled with SDCC in piklab. Also I'm using a 18.432 mHz oscillator. Any suggestions would be very helpful. Thanks!

Rich (BB code):
/* ----------------------------------------------------------------------- */
/* Template source file generated by piklab */
#include <pic16f877a.h>
#define VAR 0x2F

/* ----------------------------------------------------------------------- */
/* Configuration bits: adapt to your setup and needs */
typedef unsigned int word;
word at 0x2007 CONFIG = _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF;

unsigned volatile short time = 0;
unsigned volatile short time2 = 0;
unsigned char at VAR writeBuffer = 0;
unsigned char i;

void isr() interrupt 0 {                                                                                                   /* interrupt service routine */
    /* << insert interrupt code >> */
    time++;
    time2++;
    if(time>20000)
    {
        _asm
        bcf    PORTA, 1
        _endasm;
    }else{
        _asm
        bsf    PORTA, 1
        _endasm;
    }
    if(time>40000)
        time = 0;
    T0IF = 0;
    INTF = 0;
}

void setHigh()
{
    _asm
    bcf    PORTB, 1
    _endasm;
}

void setLow()
{
    _asm
    bsf    PORTB, 1
    _endasm;
}

unsigned char valueBit(unsigned char bit)
{
    unsigned char t = 1;
    t = t<<bit;
    return (t & writeBuffer)==0;
}

void zerotime()
{
    time2 = 0;
}
int getTime()
{
    return time2*256+TMR0;
}

unsigned char inTime()
{
    return time2*256+TMR0<1920;
}

void writeByte(unsigned char byte)
{
    unsigned char tmp;
    writeBuffer = byte;
    tmp = valueBit(0);
    zerotime();
    setHigh();
    while(inTime()){}
    zerotime();
    if(tmp)
        setHigh();
    else
        setLow();
    for(i = 0; i<7; i++)
    {
        tmp = valueBit(i+1);
        while(inTime()){}
        zerotime();
        if(tmp)
            setHigh();
        else
            setLow();
    }
    while(inTime()){}
    zerotime();
    setHigh();
    while(inTime()){}
    setLow();
    
}

void main() {
    /* << insert code >> */
    TRISA = 0x00;
    TRISB = 0x01;
    PORTA = 0x01;
    writeBuffer = 0x00;
    PORTB = 0x00;
    T0CS = 0;            // select internal clock
    T0IE = 1;            // enable timer interrupt
    GIE = 1;
    T0IF = 0;
    INTF = 0;
    while(1)
    {
        writeByte(0x5A);
        zerotime();
        setLow();
        while(time2<10){}
    }
}
 

Thread Starter

solpic

Joined Jul 23, 2009
25
I was under the impression that there was such a thing as a "direct connection" where you could use 0-5V signals for an RS232 connection. So I'm guessing from the responses that I have to use the standard -15 or +15 volts?
 

t06afre

Joined May 11, 2009
5,934
You can use a MAX232 variant/type as level translator for both input and output. This chip need only +5 volt and it will generate the correct RS232 level signal
 

THE_RB

Joined Feb 11, 2008
5,438
You can use direct connection with no dramas to send data from the PIC to the serial port. All the old PC Microsoft mouses (mice?) did that.

Just generate the serial inverted, and connect it with a 470 ohm resistor to the PC.
 

BMorse

Joined Sep 26, 2009
2,675
You can use direct connection with no dramas to send data from the PIC to the serial port. All the old PC Microsoft mouses (mice?) did that.

Just generate the serial inverted, and connect it with a 470 ohm resistor to the PC.
Old Serial Mice were powered off of the RS232 port....

For data transmission lines (TxD, RxD and their secondary channel equivalents) logic one is defined as a negative voltage, the signal condition is called marking, and has the functional significance. Logic zero is positive and the signal condition is termed spacing. Control signals are logically inverted with respect to what one would see on the data transmission lines. When one of these signals is active, the voltage on the line will be between +10 to +15 volts. The inactive state for these signals would be the opposite voltage condition, between -10 and -15 volts. Examples of control lines would include request to send (RTS), clear to send (CTS), data terminal ready (DTR), and data set ready (DSR).
I would use a level translator like the MAX232CPE, it doesn't matter if you are bit banging serial data to it, you still need the appropriate levels to interpret ones, and zero's....


My .02
 

THE_RB

Joined Feb 11, 2008
5,438
Old Serial Mice were powered off of the RS232 port....
...
Is that an agreement or an argument? Serial mice were powered from the PC serial port AND cirectly connected to it with no MAX232 chip. I've pulled apart many mice, some maintained +/- drivers but most of the later serial mice (when they got cheap) just use a transistor and one-sided drive with many just using a resistor from one of the mice's micro pins.


I would use a level translator like the MAX232CPE, it doesn't matter if you are bit banging serial data to it, you still need the appropriate levels to interpret ones, and zero's....

My .02
No you don't, that's a myth. I was interfacing hardware to PC ports from back in the 8086 (XT) days right up to today. The UART chip in the PC serial port is fully compatible receiving logic level signals 0v and 5v states. It's INCREDIBLY rare to find a serial port that won't accept 0v-5v level signals.

All that is REQUIRED to connect a microcontroller to a serial port is to invert the signal, but adding a 470 ohm resistor is polite in case of wrong connection etc it won't damage the micro.

You don't need to ensure full RS232 spec compliance to connect one 5v logic chip to another 5v logic chip. Even though MAXIM might like you to think that there is some "magic" voltages needed.
 

BMorse

Joined Sep 26, 2009
2,675
THE RB : Serial Mice - I was agreeing with you. I have been bit banging ports since Vic-20's and commodore64 days.... before the 8086.....
 

rjenkins

Joined Nov 6, 2005
1,013
I'd connect a 10K resistor in line with the TX data from the PC to the PIC, putting +/- 12V in to it may not be a good idea..
The 5V levels from the PIC should drive the PC receive side OK, but as has been said above you need to invert the logic levels to make up for the missing RS232 driver / receiver.

Depending what program you are using at the PC end, it may need the handshake pins linking out to convince it a valid device is connected..

On the 9 pin connector at the PC end of the cable, link pins 7 & 8 and, separately, link pins 1-4-6.

ps. the pin numbers are usually moulded in to 'D' connectors, though with some makes you may need a magnifying glass to see them...
 
Top