Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

RS-232 Serial to Pic 16f88 without a MAX232

Status
Not open for further replies.

Lynxdom

New Member
I've been trying to connect my PC to a pic 16f88, and have it flip some LED's to indicate that a byte was recieved. I am without a MAX232 mostly for money issues(I know they are only a dollar fifty), but also because I feel the more descrete components I use the more I'll understand whats going on.

I've built a voltage shifter and inverter to match the required 0-5V voltage level and the active low, as is required in the data sheet. I had a cicruit that I designed origionally, but I found a more simple design online and used it.

I have the Pic sending the character 'A' so I could hook it up to the OSCOPE for comparison. When I hook the TX to the RX the led's flip back and forth, telling me that the program is working. I wrote it using MPLAB IDE C(code bellow).

I have an OSCOP image of the raw serial output, which is -12 to +12(from a digital), and an image comparing the output from the chip to the output from the interface circuit(reading taken from the collector on the transistor without the pic attached time is 50uS and Volt is set to '5'). As far as I can see the timing and the voltage levels are the same.

I dont understand why the pic responds to itself, but wont respond to the PC..... HELP!!!

Thanks :)

Code:
#include<pic.h>

main()
{
	char indicator=0;    //initilize variables
	char data=0;
	char flip=0;
	int delay=0;
	char output=0;

	TRISB=0;
	PORTB=0;

	TRISA=0;
	PORTA=0;

	OSCCON=0b01100000;   //4 Mhz
	RCSTA=0b10010000;    //  Set for N81
	TXSTA=0b00100100;    //
	SPBRG=25;            //  Set for 9600 baud

	PORTB=0b11111111;    // Flash all Led's to make sure the program made it that far
	PORTA=0b11111111;
	for(int x=0;x<20000;x++);  // delay so the flash can be noticed
	PORTB=0b00000000;
	PORTA=0b00000000;	
	PORTA=0b11000000;   //Set LED's on for intial state.

	do
	{
		if((PIR1&0b00100000)==0b00100000)  // PIR1 bit 5 goes high when a char has successfully been recieved
		{
			if(flip)flip=0;  //Flip var flip to switch Led's
			else flip=1;
			
			data=RCREG;   //  Retrive data from RCREG to reset PAR1.5
		}

		if(delay==1000)  //Put Delay on transmit so OSCOPE can get a clean read and can confirm loop is running
		{
			TXREG='A';  // transmit 'A'
			delay=0;    // reset delay
		}

		if(flip)     //display to indicate that char has been recieved.
		{
			PORTA=0b11000000;
		}
		else
		{
			PORTA=0b00000011;
		}	

		delay++;  //inc delay for transmit
	}
	while(1);     //infinite loop
}

This is my first post ever, Im sorry if I left anything out, or formatted incorectly.
 

Attachments

  • OScope16F88andPCOutputs.jpg
    OScope16F88andPCOutputs.jpg
    21.3 KB · Views: 393
  • PC-PicScematic.jpg
    PC-PicScematic.jpg
    843.2 KB · Views: 565
  • SerialOutput_500us_CHAR_181N_9600_10000001_A.jpg
    SerialOutput_500us_CHAR_181N_9600_10000001_A.jpg
    16.4 KB · Views: 425
Last edited:
Bit overly complicated - a simple series resistor is all you need (check out the BASIC STAMP circuit), and use a software UART instead of the hardware one (because you can easily invert it in the software). The RS232 routines in my tutorials will easily do it.
 
Nice work! I love the drawing.. done by hand? Looks clean and neat... i cant even use a ruler to make a straight line ... :D good job... dont take Nigels suggestion the wrong way hes just trying to make sure you dont go crazy doing something that can be done a little simpler... But i like it nonetheless
 
Thanks, Yes I did it by hand :). 3v0 Recommended Eagle for making my schematics from here on out.wouldn't you know though, it doesn't include the 16f88 in its library :p

I appreciate any input, I don't take anything personally that doesn't include a profanity :). I just want to understand what I did wrong. It wouldn't be so bad if I couldn't wire pin 11(TX) to pin 8(RX) and have the LED's flash. I was wondering about reducing the resistor value on the collector to bump up the current some, but If I'm reading the data sheet correctly, 500uA should be plenty for the pin to register.

I've started on the code for a software solution just so I can move forward with my project, but at a later date I want to come back to this and figure it out. I want to be able to sleep at night :).
 
I Have only tried Nigels and im no good with making something like that work... but as for eagle i can Make you a part for the 16F88 if you want ? it will take about 3 minutes to do...
 
Ok i made it ill upload it now.. There are 2 versions... one is the DIP/SOIC which is 18 pins and the other is the SSOP which is 20pins...
 

Attachments

  • custom.zip
    2.9 KB · Views: 216
  • 18.jpg
    18.jpg
    70.4 KB · Views: 427
Last edited:
No problem from me.... Bill has tons of usefull info on his schematics. I learned IR stuff from it and almost everything i know started from his Junebug...
 
the 16F88(18DIP) foot-pint is readily there, even in EAGLE ver5.5.0, under Sparkfun.
 
At the risk of this becoming a Blog, I have done more experimentation with the original circuit. I'll be the first to admit, I have a problem with letting things go. I hope no one gets irritated, and I hope others can learn from my mistakes. :)

To this end, I decided to take current readings around the circuit to see what I could see.

One of the things I'm most curious about is why the chip responds to itself and not the nice circuit I went to all the trouble of building for it. I can confirm that the timing and voltage levels are similar enough that it should work. That only leaves the current levels. So I took different current readings across the circuit., and found the following(with pictures).

Between the TX and the RX - 32.1mA
Between the collector and the RX(no signal) - 20.6ma(after I reduced the resistor between +5 and the collector to 220Ohms).
Between the collector and the RX(+10 volt source at the RS232 connection) – 2.6mA

I may be wrong but I think the 2.6mA reading means that the pin is never getting a good active low, so the chip is reading a constant lo, even in the face of a signal. It tells me the RX is providing a far more enticing ground than the circuit I've provided. I have looked at the firefly circuit for some background, and it seemed to be very similar to the one Im using, just with lower resistor values. I'm still looking into that.

Has this told me what I needed to make it work? No! Am I going to keep plugging away at it! Hell Ya! I've also spent some of my Christmas money on getting a max232 chip that should be here next week. When it gets here I'm going to hook it up, and if it works analyze it and figure out why.
 

Attachments

  • TX-RX.jpg
    TX-RX.jpg
    159.9 KB · Views: 279
  • InActiveCollector-RX.jpg
    InActiveCollector-RX.jpg
    149.4 KB · Views: 310
  • ActiveCollector-RX.jpg
    ActiveCollector-RX.jpg
    45.8 KB · Views: 307
Last edited:
IT WORKS!

The final solution seemed to be in the clock. I had to finally put an 8Mhz external crystal, without it I got a steady stream of frame errors.

Given that the origional intent was to build a working circuit sans a MAX232, I have sort of failed in that regaurd. I will try the origional circuit just for fun(and vindication).

Thanks to all of you, for your input and help.

Code:
#include<pic.h>

void transmit(const char *data);

void main(void)
{
	char indicator=0;    //initilize variables
	char data[2];
	char frame=0;
	char overflow=0;

	int delay=0;
	char output=0;


	TRISB=255;
	PORTB=0;

	TRISA=255;
	PORTA=0;

	OSCCON=0b01110110;   //  Configuration for 8 Mhz
	RCSTA= 0b10010000;   //  Set for N81
	TXSTA= 0b00100100;   //
	SPBRG=51;            //  Set for 9600 baud

	for(int x=0;x<1000;x++);
	transmit("Fired up!\n\r\n\r");

	do
	{
		if(RCIF==1)
		{
			data[0]=RCREG;   //  Retrive data from RCREG to reset PAR1.5
			data[1]=0;

			transmit("Data:");
			transmit(data);
			transmit("\n\r");

			frame=0;
			overflow=0;
		}

		if((FERR==1)&&(frame==0))
		{
			frame=1;
			transmit("Frame Error\n\r");
		}

		if((OERR==1)&&(overflow==0))
		{
			overflow=1;
			transmit("Frame Error\n\r");
		}
	}
	while(1);     //infinite loop
}

void transmit(const char *data)
{
	int pos=0;
	char t=data[pos];

	while(data[pos])
	{
		while(TRMT==0);
		
		t=data[pos];
		TXREG=t;
		pos++;
	}
}
 
On a hunch I pulled the 8Mhz crystal out of the circuit in mid operation.... It still works fine. So the crystal isn't part of it. I'm going to start pulling things appart until I can find what it is. I have very little doubt that it has to do with the configuration of the chip....
 
Code:
OSCCON=0b01110110;   //  Configuration for 8 Mhz

The first 3 bits that control the clock source appears to have been the problem. Before the bits were configured for fosc select. Now, I have the bit configuration set for internal clock and it works. Thank you all for all your help :)
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top