any ideas on how i can write a code to transmit an AT command from 8051 to zigbee serially? thanks in advance
What problems do you see?
Does the 8051 need to know what device is connected to the serial port when it's about to send serial data? Isn't it enough that the 8051 and the external device have electrically compatible signals and that you know what baud rate, number of data bits and stop bits and parity settings to use?
SILabs have '51s with Zigbee functionality
Thanks for the reply. this is the code that i currently got, it is to turn on a port which i connected to an LED, when i receive a raw data !A@ from the zigbee. they are connected serially. next i want to do is when i receive a raw data from the zigbee serially, i want to send out an AT command instead to the zigbee for it to send out.
#include <DS89C4xx.h> //8051 header file
#define CR 0x0D
sbit mybit=P1^5;
unsigned char code start_header='!'; //to check where is the start of the data unsigned char code end_header='@'; //to check where is the end of the data unsigned char idata zigbeerxd[50]; //to store data from SBUF0 in serial interrupt unsigned char idata read[50]; //to read data from zigbeerxd[] in the main unsigned char idata rawdata[14]; //to store the data transmitted from zigbee unsigned char idata mynodeID[3]; //to check received data whether it is my ID unsigned char x,i,j,k,z,u,h; //declare variables for checking use unsigned char count; //to read serial data in the serial interrupt unsigned char read_count; //to read data from serial buffer unsigned char get_raw;
void delay (unsigned int value) { unsigned int x, y; for (x=0;x<value;x++) for (y=0;y<500;y++); } void serial_int (void) interrupt 4 { if (RI_0==1) { if(count==50) //check if array is full count=0; //restart from 0 zigbeerxd[count]=SBUF0; //storing the data from serial buffer into array count++; //increase the count RI_0=0; } }
void Read_Zigbee (void) { if(read_count!=count) //check for any unread data? { if(read_count==50) //go back to start position of array read_count=0; read[read_count]=zigbeerxd[read_count]; //read the data if (i==1) { if(read[read_count]==end_header) //check if data is '@'(end header) { k=0; //reset the values
i=0; get_raw=1; //raise the get_raw flag } else if (k<=13) //to prevent the array from overflow { rawdata[k]=read[read_count]; //store the data in rawdata[] array k++; } } else if(read[read_count]==start_header) //check the data is '!'(start header) i++; read_count++; } }
void check_data (void) { z=0; if(x==1); { if(rawdata[x]==mynodeID[1]) //check data if it's 'A' z++; }
if(z==1) { mybit=1; //toggle LED delay(2000); mybit=0; } }
void main (void) { delay(500); //delay to wait for zigbee to warm up count=0; //make count zero at first
read_count=0; get_raw=0; mynodeID[1]='A'; mybit=0; TMOD=0x20; //Use Timer1 TH1=0xfd; //9600 BAUD RATE, 8 BIT DATA, NO PARITY TR1=1; //Start Timer1 SCON0=0x50; //SERIAL MODE1, 8 BIT DATA, 1 STOP BIT, 1 START BIT, NO PARITY ES0=1; //enable serial interrupt for port 0 EA=1; //enable global interrupt RI_0=0; //reset receive interrupt flag delay(500); //wait for PPI to reset
while(1) { Read_Zigbee(); //function to read the new data from serial interrupt array
if(get_raw==1) //check if there is new data to check? { check_data(); //check the data get_raw=0; } } }
Your source code is illegible because you didn't follow the instructions on how to post source code - they are quite clearly stated, as this picture shows: www.danlhenry.com/.../keil_code.png
"mybit" - that really isn't a variable name that tells any story about what it does. Later in the program you have:
mybit=1; //toggle LED
So why must a reader scan through all your code just to figure out that "mybit" is actually controlling a LED? And "toggle LED" still doesn't tell a reader if writing a '1' will turn on or turn off that LED.
unsigned char code start_header='!';
You used a #define for CR, but then you decided to use normal variables for some of your "constants" - are you saying that your program supports reprogrammable tokens for the framing of your messages?
unsigned char x,i,j,k,z,u,h; //declare variables for checking use
Is it easy to read code when you need to all the time figure out what's the difference between 'i', 'j' or maybe 'k'? Or what is currently stored in 'u'? Your comments seems to indicate that 'k' is "the values". Easy to see from the name?
Every second you save with a short variable name like this you normally lose quite a number of minutes from being confused about the meaning of the variable.
read[read_count]=zigbeerxd[read_count]; //read the data
Seems strange that you have two different arrays but use the same index. So the raw data received from the UART is identically aligned with your currently processed command?
if(read[read_count]==end_header) //check if data is '@'(end header)
Why have a constant downgraded into a variable "end_header" if you still need to write a comment telling us that the variable is '@' and that '@' means "end header"? Does it make sense to try to write the same program twice - once as C code and once as C comments? Isn't it better to have C symbol names that tells the story and instead reserve the C comments for telling the reader why you need to do different things?
Because of your formatting issues (while ignoring the 'well-named' variables, it's almost impossible to actually read the code. But you have a busy-loop delay() that you most probably can't tell how long delays it actually gives. Or what happens if you maybe change some compiler options or changes to a different version of the compiler. Busy-loops aren't a good way to implement delays. Wouldn't it be better with a delay_100us(2000) that could have a user know that each tick of the input parameter represented 0.1ms of delay so the reader could figure out that delay_100us(2000) would be a 200ms delay?
By the way - you posted code without specifically telling what issues you have with the code and what you have done to try to overcome these issues.
"you have a busy-loop delay() that you most probably can't tell how long delays it actually gives. Or what happens if you maybe change some compiler options or changes to a different version of the compiler."
See: www.8052.com/.../162556
OK, thanks. but now i want to transmit a string of AT command using array from the 8051 micro controller to the computer and see through hyperterminal. i am able to transmit just a character like 'A'. But i'm not clear as to how to send a string of data using arrays. thank you in advance.
"But i'm not clear as to how to send a string of data"
Well, a string is just a sequence of characters, isn't it?
So you send the first, then the second, then the third, etc - until you reach the end.
This is just basic indexing through an array. If you're not clear on that, then it's time to get back to the basic 'C' textbook
blog.antronics.co.uk/.../
Remember that the serial transmission is slow compared to the instruction execution - so you need to wait for the transmission of one character to finish before starting the next.
Also, you need to wait for and correctly handle the response to each AT command before starting the next...
You do know how 'C' marks the end of a string - don't you?
What if i want to transmit a long string? Maybe around 40 to 50 characters. Do i still send a character one at a time? No right? If not the code will be very very long.
If you want to walk 10 kilometers do you then take one step at a time, or do you suddenly take 100 steps at the same time?
You always have to send one character at a time.
Program becomes very long? Why? Haven't you actually tried to search for the keywords "string" and "array" on Google? A loop that sends all characters in a string/array doesn't take more space because the string/array contains 50 characters instead of 1 character. It's only the assign of the string/array that will be come a longer line until the string is so long that you need to split it over multiple source code lines.
const char string[] = "This is a long string of many characters to send."
Have you not heard of loops ??
If not, then you really need to get (back) to that basic textbook!