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.

pic16f886 uart + AT problem

Status
Not open for further replies.
__CONFIG(WDTDIS & XT);
basically changes my config bits to using XT of oscillator and /MCLR is external...however, i have a switch (RE3) attached at my board. RE3 happens to share the same pin as /MCLR and therefore i set the config bits to "RE3 is digital input" instead.

i get an output of "f" most of the time over at TeraTerm, i am not sure as to why nothing comes out at HyperTerminal.

hope to get ur guidance
 
MCLREN is MCLR External isn't it?

I got f's when I set the osc to 1 or 4 mhz in the simulator.

It sounds like the peripheral clock isn't setting, have you scoped your oscillator to make sure it is functioning correctly?

WDTDIS disables the watchdog timer.
XT sets the external oscillator.

To set MCLR as an input use this:
Code:
__CONFIG(WDTDIS & XT & MCLRDIS);

Wilksey
 
yes, MCLREN is MCLR External.

hmm i got "f" now that i set it to 8Mhz, 9600, 8, N, 1, as shown from my codes i posted few days back.
hmm i tried scoping the output of the Tx pin from the P16F886 and it seems to be transmitting out the alphabets, however its not shown in the HyperTerminal or TeraTerm.

my ConfigBits are
Osc: Internal RC No Clock
MCLR: RE3 as digital input
WDT: off
 
Ok, I can replicate your problem everytime, by setting a 4MHz clock it will output lower case f's.

Tell, me, from your config bits, are you trying to use an internal oscillator?

Try something, set your SPBRG to 25

Wilksey
 
Last edited:
hmm its weird i got the continous As and 1s if i change my SPBRG to 25, which means am using Fosc of 4Mhz, BR 9600 and not 8Mhz. tho i get a continous the symbol as shown at #130 of the extended ascii table at Ascii table when i first start the system. however, it goes back to As and 1s when i press on the switch RE3.

now for the AT commands =(( how do i actually command the P16F886 to control how the bluetooth works? like lets say enable to bluetooth to be connected, search & sync with other bluetooth devices, and send datas (for instance, maybe lighting up LED or something), etc...

Hope u can help me out on this.
 
oh yes yes! u spotted my oscillator problem. i think the fault at my side was that i have been trying to use the internal oscillator but i've been using the 8Mhz to calculate the SBRG. that point suddenly struck me too, with some clues from ur previous posts. =)

1. But now i am wondering as to why u can get a continous As when u are using 8Mhz on your simulator and fs when ur using 4Mhz??

2. You have any idea on how i should go about starting the ATs?
 
btw, another qn,

3.is it also possible to send a word like 'Apple' ?

i tried
Code:
TXREG = 0x41; //sending 'A' when pressing switch, 0X41 = A
TXREG = 0x70; //p
TXREG = 0x70; //p
TXREG = 0x6C; //l
TXREG = 0x65; //e
 
You obviously have some configuration / oscillator issues, but at least you can get it working with SPBRG = 25. This just means that you are using a 4MHz clock, or your PIC thinks its a 4MHz clock anyways.
The UART will sometimes generate some startup "codes", but normally only 1 or 2, usually to do with the PC hardware, or the 232 module.

Did you do a complete restart of the PC before trying to connect / receive, maybe it's a buffer issue?

The reason I was getting the correct response is because I set the code up for 8MHz operation, not 4, but when I changed to code from SPBRG=51 to 25, it calculated the correct code for 4MHz operation, and worked as it should at 4MHz.

As for the AT commands, I presume that when you issue an AT command to the bluetooth module it is like talking to a modem? So you will receive either:
1) OK
or
2) ERROR

Being a bluetooth module you may recieve some extra information, like a code or something, you will need to look up your spec.
You might create a few "expected" responses of OK and ERROR if the above information was correct, and send the AT command out to the modem, and then wait to recieve, this could be terminated with a CR / LF or CRLF, 0x0A + 0x0D, you may have to send the CRLF also, once the recieve has completed you can do a string compare against the result and the possibilities (OK, ERROR) if one meets, then do the required action.

For example:
Code:
if(!strcmp(inpBuff, m_OK_Response))
{
       //OK Received
}
elseif(!strcmp(inpBuff, m_ERROR_Response))
{
      //ERROR Received
}
else
{
     //Unexpected Response
}
Where m_ERROR_Response and m_OK_Response would be your own defined static variables.
And inpBuff would be your received UART buffer.

If your response returns a code as well as the response such as "ERROR 200", you can do an indexed array compare to just get the first, in this case, 5 characters of the buffer to compare against. Or you can make a function to split the "words" ERROR and 200, so you have an Array length of 2, index 0 = "ERROR", index 1 = "200", index 0 will always be the "command"

Hope this makes sense?

Wilksey
 
Yes, it is, but you need a delay in between each character.

Try this, at the top of your code add this:
Code:
void init_rs232();
#define MHZ *1000L
#define XTAL_FREQ 4MHZ
#define DelayUs(x) { unsigned char _dcnt; \
_dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \
while(--_dcnt != 0) \
continue; }

void main()

Then, add this:

Code:
if(TRMT)
				TXREG = 0x41; //sending 'A'
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				TXREG = 0x70; //sending 'p'
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				TXREG = 0x70; //p
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				TXREG = 0x6C; //l
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);				
				TXREG = 0x65; //e
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);
				DelayUs(255);

			}
			else{
				RB0=0;
				if(TRMT)
				TXREG = 0x70; //sending 'p'
			}

See how that works?

Wilksey
 
Interesting!! i've tried & Apple appears!! but, why do we need to put 4 delays instead of one?
i tried 1 delay and it gives me "Aple"
2 delays, it gives me messy results
3 delays, "Apple"
4 delays, no change.

But again, its weird to see that the output is "Apple" when i tried
Code:
   DelayUs(255);
//DelayUs(255);
   DelayUs(255);
//DelayUs(255);

btw, are u able to explain how/what does
Code:
#define MHZ *1000L
#define XTAL_FREQ 4MHZ
#define DelayUs(x) { unsigned char _dcnt; \
_dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1; \
while(--_dcnt != 0) \
continue; }

works? no offence but i have seen this in many examples but i am unable to figure out some stuffs, like
what does the "L" represents?
how did u come of the formula of _dcnt = (x)/((12MHZ)/(XTAL_FREQ))|1?
as for DelayUs(x), the x is the integer that we need to insert, but is there any formula to follow as to how we choose the right x? or is it by trial an error?

Hope to learn as much as possible from u here. I dont think its good to just learn the codes from u without really understanding them.

I am still trying to digest & understand ur bluetooth UART explaination =)

Thanks so much for the help so far!
 
Last edited:
btw, Wilksey,

isit possible to accomodate to BaudRate of 57600 because of the Bluetooth module (bluetooth module's baud rate is 57600)? i tried using 4Mhz and changing the respective SPBRG values corresponding to the 57600 but to no avail. i would like to try using 8Mhz, but how do i define it? i tried changing the oscillator mode to XT and change ur XTAL_FREQ definition to 8Mhz by writing "#define XTAL_FREQ 8MHZ", but both methods still fail.
 
Well, that was just a routine I found on a website, you can go here:
Code:
http://www.microchipc.com/sourcecode/#delay16x
This is a download link to 16F delay routines from MChip website, this is "official" delay routines for HITECH C, so they may serve you better.

Well, I usually delay about 10ms, so that is why I added 4, to make sure it sent through, you can, as you have discovered, tweak this timeout.

If you use the delay.c from the ZIP file in the above MChip link you can just call DelayMs(10); or lower, experiment!

The L represents a long number I think, might be wrong.

The original routine is from here:
Code:
http://www.edaboard.com/ftopic114099.html

a quick look at the code just decrements _dcnt until it is 0, and you can pretty much work out the rest as it just divides x (the number of Us) by 12MHZ / XTAL_FREQ or'd with 1.
x is from 0 - 255, as it is a char, this represents the number of Useconds to delay.

Wilksey
 
Are you using the internal oscillator or do you actually have an external oscillator connected to your PIC?

If you are using external Oscillator then it should just "work", you can experiment switching between HS and XT mode.
If you are using an internal oscillator you will need to do the following as it defaults to 4MHz, only changes are written below:
Code:
__CONFIG(WDTDIS & INTIO & MCLRDIS);

#define XTAL_FREQ 8MHZ

void main()
{
	OSCCON = 0x75;           //NEW LINE, 8MHz High Frequency clock
	TRISE = 0x08;
	TRISB = 0x00; 
	init_rs232();

The main one here is the OSCCON, by default the pic is set to 4MHz, this retunes the oscillator at 8MHz, you can fine tune this by using OSCTUNE.

All of this information was calculated from section 4.0 of the datasheet.

To get 57600bps for your bluetooth module, you should set SPBRG = 8 for 8MHz, you can achieve this for 4MHz unless you set BRG16 = 1, then SPBRG = 16 for 57600bps @ 4MHz.

Let me know how you get on!

Wilksey
 
Hey Wilksey, you are early!
Hmm as i am afraid that u will be offline soon, i am trying out the 4mhz & Osccon & try to digest the rest later.

1. will try to digest and understand the Delay later on (together with the eUsART explanation)

2. Nope, i do noe have any external clock connected to my PIC. i am solely using the internal oscillator. Oh, i understood how u derived 0x75. i have defined it earlier but didnt know how
to set the OSCCON value earlier.

3. Oh my, it works for 4Mhz!! but whhy do u set BRG16 =1 when we've already set BRGH =1??
as wat i can see from page 163 of the datasheet, it write that BRG16 (16bit BRG) is used to achieve slow baud rates for fast oscillator frequencies? In this case, how do we know if we
are supposed to just set BRGH and/or BRG16?
 
Ok, that is why you were not getting the expected results, as the 4MHz option is the default for the internal oscillator.

BRG16 is the 16 bit Baud Rate Generator, look up the table 12-3
BRG16 = 1 and BRGH = 1 is:
Code:
FOSC/[4 (n+1)]
So:
Code:
FOSC = 4MHz = 4000000

400000 / 57600 (Desired Baud Rate) / 4 - 1 = 16.36 = 16

So for a 4MHz Oscillator @ 57600bps SPBRG = 16

It's all in the data sheet.

Wilksey
 
nono, i understood how u got 16 for SPBRG.
but i was confused as to why we need to choose BRG16 to be 1 too? *of course, by looking at table 12-5, it shows that we need to set BRGH and BRG16 to be 1*

Does the 4, 16 and 64 means anything in table 12-3?

"BRG16 is the 16 bit Baud Rate Generator", but aren't we using 8bit now?

Pardon me if i asked too many questions and some may be silly. You've really been a great help to me!
 
Sometimes the datasheets can be confusing, luckily they provide some sample calculations which you can base yours upon.

The 4, 16 and 64 are just what you divide the FOSC / n by based upon the BRGH and BRG16 values, they have a meaning inside the Micro Processor, I expect to do with high speed / low speed / high bit / low bit timing operations of the UART peripheral.

Nope, 16 bit when BRG16 = 1, if you think about it, 16 bit is over double the possibilities of 8 bit, giving you a much better range which is why 57600 is possible with a 4MHz clock.

The simple answer as to why they have to be set is "because Microchip say they do", but i've read worse datasheets than the MChip ones in my time!

You can set BRG16 = 0 but you will have to use a 8MHz frequency setting or higher.

Remember, with a PIC and any other micro processor for that matter, everthing is almost always generated from the clock source, which is the key to correct timings! Which in the electronic world is the key to things working.

So do you have it all working now? I mean as far as talking to your bluetooth module at 57600 @ 4Mhz and your UART code working i.e. sending AT commands to the module?

Wilksey
 
Last edited:
"because Microchip say they do", hahaha, i see.

Hmm its true that 16bit will give a much better range but will it affect any other parts of the codes as i believe other areas are using 8bit? (is it?)

Any advantages or differences if i use 4Mhz, 16bit or 8Mhz, 8bit? since they compensate each other in both ways.

Yes, guess most of my problems for the past week has been due to the clock frequency. sigh.

Yup, thanks to u, communicating at 57600 @ 4Mhz or @ 8Mhz through the pic and showing the outcome at HyperTerminal, is working fine now.
(not with the bluetooth module yet) i am still figuring out the eUsART stuffs.

I just went to consult my supervisor and he said something about sending a string of characters "///" as its the first step to initializing the bluetooth into its AT mode. will consult him again later as i am still rather confused as to how i should go about hard-wiring the pic to the bluetooth module and how the final communication will be like, so i could provide u with a clearer view of my problem.

are u familiar with ATs too?
 
No, it is just a 16 bit register that is all.
It will not affect the rest of the code.
8MHz for 57600 may be more stable, and perhaps have a lower error rate than 4MHz.
Nothing else really would be affected, unless you need the higher speed for something else?

Well, it sounds like your Bluetooth module needs some special codes, but with the Bluetooth module datasheet you can get this working good.

AT Commands are commonly used on modems, AT means ATtention, then you have other identifiers to dial, disconnect, show information etc, signal strength etc.

If your Bluetooth module has a RS232 interface you will need to use a MAX232 converter chip or similar.

TX goes to RX and vice versa.

The final communication will be a series of commands to send out and a wait for responses.

This can be done with either a state machine or a termination check (CRLF).

What are you still trying to figure out regarding what has been said so far, and about the UART?

Wilksey
 
ohh i see, i will be using the 8 Mhz then.

i have checked up alot of sites and they mostly said abt bluetooth command to send sms and all but i think mine is slightly different. Guess i would need to take reference from "Serial Port Adapter AT Commands.pdf", if ur familiar with it. or how do i attach and send it to u?
i think the BT module is AT comaptible and has already been set up for rs232 connection.

yes, guess mine will be the one that need the CRLF.
trying to figure out how to putString (my supervisor said it was inefficient to use delays in our earlier codes.) and the other AT commands.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top