PIC16F84A RS232 Communication Problems

Discussion in 'Embedded Systems and Microcontrollers' started by solpic, Oct 12, 2009.

  1. solpic

    Thread Starter Member

    Jul 23, 2009
    25
    0
    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!

    Code ( (Unknown Language)):
    1. /* ----------------------------------------------------------------------- */
    2. /* Template source file generated by piklab */
    3. #include <pic16f877a.h>
    4. #define VAR 0x2F
    5.  
    6. /* ----------------------------------------------------------------------- */
    7. /* Configuration bits: adapt to your setup and needs */
    8. typedef unsigned int word;
    9. word at 0x2007 CONFIG = _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF;
    10.  
    11. unsigned volatile short time = 0;
    12. unsigned volatile short time2 = 0;
    13. unsigned char at VAR writeBuffer = 0;
    14. unsigned char i;
    15.  
    16. void isr() interrupt 0 {                                                                                                   /* interrupt service routine */
    17.     /* << insert interrupt code >> */
    18.     time++;
    19.     time2++;
    20.     if(time>20000)
    21.     {
    22.         _asm
    23.         bcf    PORTA, 1
    24.         _endasm;
    25.     }else{
    26.         _asm
    27.         bsf    PORTA, 1
    28.         _endasm;
    29.     }
    30.     if(time>40000)
    31.         time = 0;
    32.     T0IF = 0;
    33.     INTF = 0;
    34. }
    35.  
    36. void setHigh()
    37. {
    38.     _asm
    39.     bcf    PORTB, 1
    40.     _endasm;
    41. }
    42.  
    43. void setLow()
    44. {
    45.     _asm
    46.     bsf    PORTB, 1
    47.     _endasm;
    48. }
    49.  
    50. unsigned char valueBit(unsigned char bit)
    51. {
    52.     unsigned char t = 1;
    53.     t = t<<bit;
    54.     return (t & writeBuffer)==0;
    55. }
    56.  
    57. void zerotime()
    58. {
    59.     time2 = 0;
    60. }
    61. int getTime()
    62. {
    63.     return time2*256+TMR0;
    64. }
    65.  
    66. unsigned char inTime()
    67. {
    68.     return time2*256+TMR0<1920;
    69. }
    70.  
    71. void writeByte(unsigned char byte)
    72. {
    73.     unsigned char tmp;
    74.     writeBuffer = byte;
    75.     tmp = valueBit(0);
    76.     zerotime();
    77.     setHigh();
    78.     while(inTime()){}
    79.     zerotime();
    80.     if(tmp)
    81.         setHigh();
    82.     else
    83.         setLow();
    84.     for(i = 0; i<7; i++)
    85.     {
    86.         tmp = valueBit(i+1);
    87.         while(inTime()){}
    88.         zerotime();
    89.         if(tmp)
    90.             setHigh();
    91.         else
    92.             setLow();
    93.     }
    94.     while(inTime()){}
    95.     zerotime();
    96.     setHigh();
    97.     while(inTime()){}
    98.     setLow();
    99.    
    100. }
    101.  
    102. void main() {
    103.     /* << insert code >> */
    104.     TRISA = 0x00;
    105.     TRISB = 0x01;
    106.     PORTA = 0x01;
    107.     writeBuffer = 0x00;
    108.     PORTB = 0x00;
    109.     T0CS = 0;            // select internal clock
    110.     T0IE = 1;            // enable timer interrupt
    111.     GIE = 1;
    112.     T0IF = 0;
    113.     INTF = 0;
    114.     while(1)
    115.     {
    116.         writeByte(0x5A);
    117.         zerotime();
    118.         setLow();
    119.         while(time2<10){}
    120.     }
    121. }
    122.  
     
  2. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    Why not use a PIC with a USART like the 16F628A which is cheaper than the ancient 16F84A
     
  3. solpic

    Thread Starter Member

    Jul 23, 2009
    25
    0
    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?
     
  4. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    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
     
  5. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    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.
     
  6. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    Old Serial Mice were powered off of the RS232 port....

    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
     
  7. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    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.


    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.
     
  8. BMorse

    Senior Member

    Sep 26, 2009
    2,675
    234
    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.....
     
  9. rjenkins

    AAC Fanatic!

    Nov 6, 2005
    1,015
    69
    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...
     
Loading...