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.

Serial Communication with 16f876 help

Not open for further replies.


New Member
I just did a little project where I turn a pot on RA0 and with PortB outputs to a 7-segment LED. Numbers go proportionally from 0 to 9. Took me a while but it seems to work great. I would now like to watch the output from the pot onscreen as the LED increments up.
I have Hyperterminal and Docklight.
I have the datasheet and also have the Midrange reference manual. I am getting confused. There appears to be many options to choose from.
Should I be using the USART?
Could you point me in the right direction. I'm sure to have more questions later.

I use Picbasic and melabs bootloader.

Any guidance would be appreciated.
Most RS232 serial communications are done asynchronous (this means there is no clock line, and only timing is used for sync).
You should indeed use the UART.

there are app notes on rs232 on microchips website
Much progress has been made. Thanks for the pointer on the app notes. AN774 helped alot.
I now get characters on screen in hyperterminal, however they appear as garble..


The garble tracks with the position of the pot so I know I'm on the right track.

Any suggestions?
Hyperterminal prints the values that the pic transmits to it as ASCII.
Every symbol on the pc has a value assigned to it; for example A = 65 decimal, a space is 32 decimal...

So if the pic sends a 3 to hyperterminal, it will not print a "3" but the symbol assigned to 3; wich is one of the garbled symbols above

Try adding 45dec (30Hex) to the number you transmit. 45 is the ascii code for 0. so if you want to send a 3; add 45 to it so you get 48; and 48 is the ascii code for "3"

an overview of the ascii codes:
check also how you are sending your stuff..... if you are using a MAX232 to connect to the PC, then your PIC serial data should be sent non-inverted (TRUE). If you have the PIC connected straight to the serial port then you should send the data inverted.

THe RS232 protocol sends a 1 as a -10V (depending on PC range betewen -5 and -12V) and a 0 as a +10V (arnge between 5V and 10V)

Hope it helps some

Thanks EXO and Ivancho.
I tried adding $30 to my variable(B4 = B3 + $30) but it still didn't work. Still garble.
The value in B3 is what I was sending to Hyperterminal.
I'm now sending B4.
Maybe I'm completely off track here.
Is the poke command the right way to get data to transmit?

Yes Ivancho I am using a max232. I don't know how to change between Inverted and true.
Some other things that might screw up the data:

-Is the baud-rate the same on the PC and the PIC?
-Are you using the same data-format on pc and pic?
Most commonly used is 8N1 (8databits; No parity; 1 stopbit)
I am afraid you are not sending the right command. :(

You are going to need to use a "baudrate" and Asynchronous serial transmition...... using the protocol RS232. You mention you are using PicBasic (is it the PRO version?)

First you have to check what the hyperterminal's baudrate is. Set it to 9600 8N1..... 960 0baudrate 8-bits -No parity, 1 stop bit. That will ensura that the PC and PIC are comunicating in the same language. :wink:

Then to your pic. The command to use when programming your PIC is the SEROUT command. This command takes the PIN you are sending the information through, the Baudrate it needs to talk at, and the data it needs to send. As I mention before since you are sending the data using a MAX232 you are going to have to send the data in TRUE mode.

Try a code like this:

Include "modedefs.bas" 

TRISB = 0 


'Get B3 code here

B4 = B3 + $30
Serout PORTB.1, T9600, [B4] 
pause 500

This code will send the PC the variable B4 to the PC serially twice a second, not too sure if you want all those sent to your hyperterminal. :roll:

If you are not using PICBASIC PRO then you will have to use the POKE comand to set your TRISB register. I can't remember from the top of my head the TRISB register address, I believe is 135d but I am not sure. You would hae to do something like Poke 135, 0.

You can also connect straight to the PC serial port thru a resistance (1K would work) If you do this you have to change the T9600 (true) to N9600 (inverted) for the comunication to work. And keep the serial cable as short as possible.

Hope it helps you a little bit. Check out this thread too PicBasic Pro, PicBasic Plus, Proteus Download

Last edited by a moderator:
Once again thanks EXO and Ivancho.

I am using 9600 baud at both the Pic and Hyper.
Hyper is set at 8N1.

I did consider the serout command but I'm trying to use the built in Usart which is on PortC,6 and I don't think I can use this command with PBC
(Not the PRO version)
Serout PORTC.6, T9600, [B4] keeps generating 2 errors.
Also the include file ("modedefs.bas") is not part of my include files that came with PBC.

I think I'll try PortB TX instead of the usart for now.
An upgrade to PBP is now at the top of my list.
Thanks again guys.
I am using my pic @ 4MHZ.
I relocated my variable to between getting the ADresult and before transmitting it .
You are right EZO, now I get whole numbers on Hyper, however they start at 0 and go up to 9 and then garble again.
The garble tracks the ascii table
I'm really close, any other suggestions would be appreciated.
Well, numbers bigger then 9 require extra code, because you now have to send 2 numbers... to make hyperterminal print a "10" you will have to send 49 (ascii for "1") followed by 48 (ascii for "0") ... get it?

So, in short, what you need to print numbers bigger then 9 on hyperterminal is a Binairy value to ascii converter routine.

You can do this by dividing your value by 100... the result will be the hundred's, add 30hex to this and print it to hyperterminal
then the REST of the previous result should be divided by 10... Result will be the tens, again add 30hex to this and print it to hyperterminal...
the REST of this will be the ones... just add 30hex to them and print again
you could then send 20hex (a space) to get a space between each number.

maybe ivancho can help you in getting this coded into picbasic... I really don't know much about picbasic :oops:

A bit overwhelming.
I'll have to ponder this for a while.

Any input Ivancho?

Thanks guys.
I'm trying to learn some picbasic and found that to calculate the remainder of a division you can use //

So for example
B4 = (B3 / 100) + $30 'calculate the hundreds and add $30 to make ascii
'Send B4 here
B4 = B3 // 100 'calculate the remainder
B5 = (B4 / 10) + $30 'calculate the tens and add $30 to make ascii
'Send B5 here
B4 = (B4 // 10) + $30 'again calculate the ramainder (this is the ones) + $30 for ascii
'Send B4 here

Another problem that might now occur has to do with your command

Poke TXREG, Bx
Before you do this you should check bit TXIF of register PIR1 to see you are allowed to transmit data. if this bit is is not set you must wait for it to become set before you do the poking.
You guys are working hard over the weekend.... good for you :wink:
Well three things:

1. What code are you using?... so we can focus on that. Are you using PICBasic ( not the PRo edition)... The Pro Editions was running around this board for a while not too ling ago. I am not sure how well is the download or you can buy it straight from MircoEnginering Labs

2. What type of data are you sending.? depending on the data you are expecting you can see what is trying to happen better.

3. What chip are you using? Is it a PIC16F877.... sounds like it :)

:arrow: I am not so sure about the capabilities on the PICBASIC you have the PRO edition is able to address the registers by name. I am not sure about the PICBASIC..... I actually believe it can't unless you actually write to the address of the register. So I hope you are doing some type of "alias" to the name TXREG

:!: The Serout comand is giving you the error because PICBASIC can address bits like POrtB.6 as PICBasic PRo does. :evil:

:idea: I would try using the serout command and make sure the comunications are workng before trying to use the USART. The Serout command is simple enough that should work just fine. And you can use the PIN on the PortC.6 so that you can latter change it to the USART

:idea: PICBASIC PRO has the command HSerout.... where you can use the built-in USART.

:idea: Try using Serout command with the variable you want to send to a pin of the portB... that is the only port that works with this command. Once you have that working you know that your circuit is communicating and you can see if it need to be inverted or True mode.... N9600 or T9600. Then move to the USART.

:arrow: On the comments to divide your number I believe you don't need to do that. If you just want to see what you are getting then you kow if you got an A you are sending a 65. But if you really want to see the 65 then you will have to do some manipulation to your results to send a ASCII value for 6 and a ASCII value for 5. :idea: I would suggest also to get rid of Hyperterminal and make a Visual Basic program that captures the serial port and displays what you need.

Let me see your code....

B4 = (B3 / 100) + $30 'calculate the hundreds and add $30 to make ascii 

'Send B4 here 
B4 = B3 // 100 'calculate the remainder 
'B4 WILL BE 65 AFTER THE B3//100

B5 = (B4 / 10) + $30 'calculate the tens and add $30 to make ascii 
'Send B5 here 
B4 = (B4 // 10) + $30 'again calculate the ramainder (this is the ones) + $30 for ascii 

'Send B4 here

Good Luck

Exo, your example set in. I tried as you said.the results were closer but need some further tweeking. I'm tinkering with it tonight.
00 00 00 00 01 01 02 02 02 03 03 04 04 05 05 06 06 06 06 06 07 07 08 08
09 09 09 09 10 10 11 11 11 11 11 11 12 12 13 13 14 15 15 16 16 17 17 18 18 18 1
8 19 20 21 21 22 23 24 24 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 24
23 23 22 22 21 20 20 19 19 19 18 18 17 16 16 16 16 16 16 16 15 14 14 13 13 12 12
11 11 10 10 09 09 09 08 08 08 08 08 08 07 07 06 05 05 04 04 03 02 02 01 01 00 0
0 00 00 00
Span went from 0 to 25 on hyperterminal, tracking the pot/LED.
I expect 0 to 255.
Is this what's known as Bit Banging?

Ivancho, I downloaded the Picbasic Pro manual tonight and looked at the Hserout command. I think you're right, this will do what I need with no effort.

Thanks again guys, this is pretty cool. :lol:

Exo, your concept was right on. A little tweeking by Ivancho and I get the results I expected on Hyperterminal.:lol:
I would have pulled the rest of my hair out if it hadn't been for you guys help. Thanks alot... :D
I'm going to try , as Ivancho suggests, to code the same project in Pic basic Pro. I sense a new thread coming for that. :oops:

Thanks again guys!!
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips