#include<reg51.h> void boud_rate() { SCON = 0x50; TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ TR1 = 1; TI = 1; } char serial_receive() { char chr; /* variable to hold the new character */ while (RI != 1) {;} chr = SBUF; RI = 0; return(chr); } void main(void) { boud_rate(); unsigned char rx_data; for(;;) { rx_data = serial_receive(); switch(rx_data) { // case '1': open_door(); case 0067892341 : open_door(); break; // case '9': open_door(); case 0045780034 : open_door(); break; default: dont_open(); } proper_delay(); } }
errors
'rx_data':undefined identifier illigal octal digit
please tell me how to overcum these errors
How about:
unsigned char rx_data; boud_rate();
#include<reg51.h> void baud_rate() { SCON = 0x50; TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ TR1 = 1; TI = 1; } char serial_receive() { char chr; /* variable to hold the new character */ while (RI != 1) {;} chr = SBUF; RI = 0; return(chr); } void main(void) { #include<reg51.h> void boud_rate() { SCON = 0x50; TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ TR1 = 1; TI = 1; } char serial_receive() { char chr; /* variable to hold the new character */ while (RI != 1) {;} chr = SBUF; RI = 0; return(chr); } void main(void) { baud_rate(); unsigned char rx_data; for(;;) { rx_data = serial_receive(); switch(rx_data) { case 0067892341 : open_door(); break; case 0045780034 : open_door(); break; default: dont_open(); } proper_delay(); } } errors rx_data:undefined identifier illigal octal digit
k, but I am receiving characters in the interrupt handler, how to use those characters in main?
Was there something wrong with the solution I have already described?
"a[5][11]={{$,0,0,6,2.....},{$,0,4,6,7,8,.,.},.,.}"
Of course the above gives a syntax error.
Don't you realize the difference between characters and numbers?
0 is a number with value zero. You write it using a single digit. '0' is the ASCII character zero. It does not have the numeric value 0. It has the numeric value 0x30 = 48.
If you can see the codes on the hyperterminal, then the codes are sent out as printable text. So each character you receive on the serial port is a '0', '1', '2', ...
You really have to keep track of the difference betweeen 0 and '0' because you can't perform the comparison unless you have the same format on both sides of the comparison operator.
And you have to understand that the compiler can handle an array of numbers (as long as the numbers are within the range of the data type for the array) but numbers can't contain any $. And your arrays can just as well be filled with the characters '0', '1', '2', ...
C strings like "123" is an array of characters { '1', '2', '3', '\0' } which indicates what strcmp() would do when comparing a printable string of code digits as received from your RFID receiver with the strings you have stored as known keys.
Have you invested in a good book about C? Have you read it? Have you worked yourself through the exercises in the book?
C is not a language suitable for people who just try random code constructs.
#include<reg51.h> #include<string.h> #include"_LCD_R8C.c" void serial_int (void) interrupt 4 { static unsigned char chr='\0'; unsigned char str1[]="$0016221826"; unsigned char str2[]="$0123456789"; unsigned char c[11],str[11],i,j,str0[11]; if (RI==1) /* it was a receive interrupt */ { RI = 0; /* clear the received interrupt flag */ // TI = 0; /* signal that there's a new character to send */ chr = SBUF; /* read the character into our local buffer */ c[11]=chr; lcd_command(0x10); lcd_print_b(chr); for(j=0;j<1;j++) { for (i = 0; i < 11; i++) { str[i] = c[i] ; } str[11]='\0'; } strcpy(str0,str); /*this step is not necessary*/ j=strcmp(str0,str1); if(j==0) { lcd_printxy(1,1,"YES"); } else { j=strcmp(str0,str2); if(j==0) { //open_door(); lcd_printxy(1,1,"YES"); } else { //close_door(); lcd_printxy(2,5,"NO"); } } } } // else if(TI == 1) // { // TI = 0; // if (chr != '\0') // { // if (chr == '\r') chr = '\n'; // SBUF = chr; // chr = '\0'; // } // } int main() { lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; TH1 = 0xFD; ET0 = 0; TR1 = 1; // RI = 1; ES = 1; EA = 1; }
here in this method using string comparison the program will be too long to compare 250 no. what to do? I have blocked TI interrupt because I am not sending any data. please tell me any mistakes if i have done
My eyes are bleeding.
An ISR should end quickly. Your ISR should just pick up characters and either place them in a ring buffer for main to pick up and process. Or maybe support the knowledge of the length of keys and that they start with '@' and end with '\n' and fill an array with a single ID and then inform main() when the ID is ready to compare.
Was there anywhere in the answers you got any text that could be seen as us recommending you to move all your code into the ISR?
Your program haven't even a loop anymore - so what do you think happen when main() reaches the final "}"?
c[11]=chr;
You always assign at index 11 - which is outside of an array of 11 elements (0 to 10). When do you assign the first character to position 0? When do you assign the second character to position 1? ...
for (i = 0; i < 11; i++) { str[i] = c[i] ; } str[11]='\0';
What advantage do you see in (for every received character) copy a character array of 11 characters into a string? Especially since a string in C is also an array of characters, but with a character '\0' as terminator to tell strlen(), strcmp(), strcpy() etc where to stop.
You have nested if (strcmp()) statements - why? Haven't you realized that C can have arrays of arrays? So you can have an array of strings with known keys, and iterate through this array until you find a match or runs out of keys to check?
By the way - such a loop should obviously not be in the interrupt service handler that is intended to pick up a received character or send a character.
Shouldn't you pick up a book about C programming, and spend some time with it? Right now, you seem to produce mistakes at a very high speed - enough so that your examples could fill a book about different programming mistakes.
You do not get anywhere by random trial and error. Actually, you can get far with that approach. But genetic methods aren't fast. It takes a huge number of generations/iterations to progress. So please stop throwing dices to decide what random changes to make, and get a basic knowledge about C data structures, control statements, data types etc.
I wonder if Keil is using PHP.
The broken display of this thread seems to be caused by a dollar sign in one of my previous posts, that seems to have trigged a replace operation that resulted in an end of the table cell and table row in the middle of the text - so the remaining part of my post is emitted inside a <table> tag but outside any <tr> or <td> tags.
Note to web designers - do care about search/replace with user-supplied data and proper handling of break characters. In this case it is broken html output. In many cases, it is database implementations that allows SQL injection hijacking or killing services.
#include<reg51.h> #include<string.h> #include"_LCD_R8C.c" unsigned char chr; unsigned char c[11]; void serial_int (void) interrupt 4 { if (RI==1) { RI = 0; TI = 0; chr = SBUF; } } int main() { unsigned char a[2][11]={"$0016221826","$0123456789"}; int i,j; lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; TH1 = 0xFD; ET0 = 0; TR1 = 1; RI = 1; ES = 1; EA = 1; for(j=0;j<1;j++) { for(i=0;i<=10;i++) { c[i]=chr; } c[11]='\0'; } for(i=0;i<=1;i++) { j=strcmp(a,c); if(j==0) { lcd_printxy(1,1,"yes"); } else { lcd_printxy(1,6,"no"); } } }
you have told me to use array of strings the compiler is giving warning in line strcmp(a,c),(BOLD): pointer to different objects. please help me.
You are continuing your programming by introduction of random changes. Genetic programming really is not a fast route.
You have arrays of type unsigned char - what did the manual say that strcmp() expects? So why did you make your decision to use unsigned char arrays?
You still don't process received data character-by-character, to get a $ followed by 10 digits before you terminate the string with a '\0' and start comparing with your reference keys.
And you have zero synchronization between your interrupt handler and your main loop.
Your programs are never even close to function, because you are constantly ignoring the information you get about existing errors in the code. Moving the code will not remove the bugs in the code. Or will not automagically include extra code lines to perform the actions that your code do not make.
Why are you even using an interrupt handler for serial communication, if you haven't implemented any buffered solution so that the interrupt handler can operate independently of the main loop? You take the disadvantages with an interrupt-based solution while gaining none of the advantages...
When will you finally consider to spend some time with a good book about C programming?
newsflash today pradeepkumar read a C book today pradeepkumar followed the suggestions in this thread in other news: today hell froze over
It has happened before, you know. www.podcastingnews.com/.../hell-freezes-over-350.jpg
ya, for sure I will study c textbook. Will you suggest me any good c book to study..?(online/which is available on internet) I will study for some days, i will correct the mistakes and then i will post my code.
Suggestions here: blog.antronics.co.uk/.../
"online/which is available on internet"
Why not go to a real bookstore, and buy a real book?
Have you considered taking a class?
#include <reg51.h> #include <string.h> #include "_LCD_R8C.c" #define INPUT_LENGTH 12 #define ACCEPTABLE_INPUT_COUNT 2 char input[INPUT_LENGTH]; /* The input from the serial port */ int input_pos = 0; /* Current position to write in the input buffer */ int input_done = 0; /* 0 = not done yet, 1 = all input read */ void serial_int (void) interrupt 4 { if (!input_done && RI == 1) { /* Put the input at next position in the input buffer */ /* Then increase the position */ input[input_pos++] = SBUF; // lcd_command(0xC6); // lcd_print_b(SBUF); // lcd_command(0xC0); // lcd_print_b(input[input_pos]); RI = 0; SBUF=0; /* Check if we have received all input yet */ if (input_pos >= INPUT_LENGTH) input_done = 1; } } int main() { int i; /* Array of data that this programs thinks is acceptable */ char acceptable_inputs[ACCEPTABLE_INPUT_COUNT][INPUT_LENGTH] = { "$0016221826", "$0123456789" }; int acceptable_found = 0; /* Acceptable input found? */ /* Initialization */ lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; TH1 = 0xFD; ET0 = 0; TR1 = 1; RI = 1; ES = 1; EA = 1; /* Wait until we have received all input */ // while (!input_done) // ; /* Do nothing */ /* Check the received input for something we accept */ for (i = 0; i < ACCEPTABLE_INPUT_COUNT; i++) { if (memcmp(acceptable_inputs[i], input, INPUT_LENGTH) == 0) { /* Yes, the data received is acceptable */ acceptable_found = 1; break; /* Don't have to check any more */ } } if (acceptable_found) lcd_printxy(1, 1, "Yes"); else lcd_printxy(1, 1, "No"); return 0; }
how about this code? please tell me if there is any mistake
I thought you said you were going to take some time to do some study?
I think that would be a far better way to spend your time rather than randomly throwing code around...
Be sure to look-up the use of the volatile qualifier...
There are several errors. But don't you find them when you test your code? You are realizing the existence of a debugger?
1) Your ISR don't do anything in case the input buffer already is filled. 2) You let the ISR pick up 12 characters. Are you sure the 12th character of input[] would match the 12th character of your reference keys? 3) How do you get your ISR to synchronize the input, in case you miss one character or there is one character too much? Consider what happens if you disconnect/reconnect the serial cable while data is transmitting? Wouldn't it be good to consider '$' or '\r' or '\n' as synchronization characters? 4) Why do you send back null characters?
SBUF=0;
Or do you happen to believe that writing 0 to SBUF is clearing the just received character? 5) Do you really think it's safe to ignore the input_done check in main()? How fast can the ISR find 12 characters? How fast can main() start calling memcmp()? 6) Haven't we already discussed the bad idea of having the program run out of main()? 7) Do you happen to think that the 8051 processor works best when it has 16-bit integers to operate on - or you think it needs the "int" data type to fit the values 0 and 1 (or the input position)?
int input_done = 0; /* 0 = not done yet, 1 = all input read */
1) Your ISR don't do anything in case the input buffer already is filled. 2) You let the ISR pick up 12 characters. Are you sure the 12th character of input[] would match the 12th character of your reference keys? 3) How do you get your ISR to synchronize the input, in case you miss one character or there is one character too much? Consider what happens if you disconnect/reconnect the serial cable while data is transmitting? Wouldn't it be good to consider the dollar or '\r' or '\n' as synchronization characters? 4) Why do you send back null characters?
#include<reg51.h> #include "_LCD_R8C.c" #define INPUT_LENGTH 11 char input[INPUT_LENGTH]; /* The input from the serial port */ int input_pos = 0; /* Current position to write in the input buffer */ char getCharacter (void); /* read a character from the serial port */ int main() { int i; lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; TH1 = 0xFD; TR1 = 1; TI = 1; RI = 1; while(1==1) { /* read the next character from the serial port */ input[input_pos++] = getCharacter (); for(i=0;i<=input_pos;i++) { lcd_print_b(input[i]); } } } char getCharacter (void) { char chr[INPUT_LENGTH]; /* variable to hold the new character */ while (RI != 1) {;} chr[input_pos++] = SBUF; RI = 0; return(chr); }
first I tried displaying on the hyper terminal. I am getting correct value on the hyper terminal then I tried displaying the received number on the display, but I am getting the wrong value 002100 instead of $0016221826..
The trial-and-error continues.
Why have a getCharacter() function that has a local array chr[INPUT_LENGTH]? What do you think this one is used for? You receive one (1) character. You place it at a specific index in chr[].
Then you do something very interesting. You take the address of the array chr[] (yes, the name of an array represents a pointer to the first element in the array) and decides to convert this address into a character to be returned.
Haven't you got that C programming book yet? It would have told you a lot about how to use arrays. It would even have told you that the getCharacter() function have zero reason to contain an array since it is only intended to pick up one (1) character from the serial port and then return that single character.
Another thing - I have multiple times asked: Why do you print multiple characters to the LCD whenever you receive one more character? Don't you find it confusing to try to understand the printout on the LCD? Because I see no code that clears the LCD and start each loop by printing from the start of the line.
So if you receive the caracters 12345 on the serial port, your code would like to print 112123123412345 on the LCD - how helpful is that?
Or in reality - your LCD prints doesn't even print that. Because you print 2 characters when you have received 1. You print 3 characters when you have received 2. So the last character printed is always some data remaining since the previous iteration of your loop.
Yet another thing - you have an array with room for 11 characters. And an infinite loop repeating getCharacter() and then printing. What happens when you receive the 12th, 13th or 100th character? Where does it get saved?
Don't you think that a C text book and some quality time with a debugger would give better progress? Thowing LEGO pieces up in the air and check where they randomly land isn't likely to produce a nice castle or space ship. Right now, you are cutting/pasting/moving around source code without actually trying to understand what is actually happening. You can continue for 10 years without getting a working program, because it really is quite hard to throw 50 dices and get all 50 to show the value "6" at the same time. With better methodology, you could throw the first dice until it shows a "6". Then take the second dice and throw until you get a "6". Then the third. Then the fourth. That would give progress. The information from a C text book could give progress. The use of a debugger could give progress. Random code changes are likely to break as much as improving. So the probability of progress is very low. That is the reason why the days are ticking, while your school buddies have probably already managed to get their implementations to work by now.
Shortcuts can be very good when you know where they lead. Random shortcuts are known to lose time or get people completely lost.
ya your right, but what to do, I need to submit this program as fast as possible. . only 2 days remaining. I have studied the comparing of arrays and that part is completed. The only problem is in receiving char using interrupt and displaying it.
Now I have corrected all the mistakes still it is displaying 255 on the display.
once i am able to receive the char then I will finish off this program and take a break to study.
even I am feeling very bad.
Now I have corrected all the mistakes still it is displaying 255 on the display. HUH? if it is "displaying 255 on the display" it is not possible that you have "corrected all the mistakes"
once i am able to receive the char then I will finish off this program and take a break to study AKA sequencing error
while(1==1) { /* read the next character from the serial port */ input[input_pos++] = getCharacter (); for(i=0;i<=input_pos;i++) { lcd_print_b(input[i]); } } } char getCharacter (void) { char chr[INPUT_LENGTH]; /* variable to hold the new character */ while (RI != 1) {;} chr[input_pos++] = SBUF; RI = 0; return(chr); }
since the above read and display characters one by one why are you using arrays? what happens if you do this
lcd_print_b ('U');
you are making the mistake of writing code instead of growing code. get one thing to work at a time.
Erik
ya i am getting the same display like 112122123. . please help me to complete the program
lcd_print_b ('U');.. I am not getting.. please explain in detail.
#include <reg51.h> #include "_LCD_R8C.c" #define INPUT_LENGTH 11 int main() { char input[INPUT_LENGTH]; /* The input from the serial port */ int input_pos = 0; /* Current position to write in the input buffer */ lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ TR1 = 1; TI = 1; RI = 1; while(1) { /* read the next character from the serial port */ if(input_pos < INPUT_LENGTH) /* check for buffer overflow */ { input[input_pos] = getCharacter(); lcd_print_b(input[input_post]); /* only makes sense to print each character once */ input_pos++; } } char getCharacter (void) { char chr /* variable to hold the new character */ while (RI != 1) ; chr = SBUF; RI = 0; return(chr); }
i am getting display as 255... help me out...
Why are you not cutting/pasting your code?
The last code you posted is not your real code - check the spelling of your index when printing - what is "input_post"???
And how come you #include a c file? Why would there be both *.h and *.c files if it was intended that you should include *.c files?
ok sorry i ll correct it... i have got few questions 1) is it receiving all the characters ? or it is receiving all characters and me not able do display it on lcd?..
"is it receiving all the characters? or it is receiving all characters and me not able do display it on lcd?"
That really is something for you to determine in your own debugging of your system!
you presist in throwing the whole thing together and asking "what is wrong"
DIVIDE AND CONQUER!
#include <reg51.h> #include <string.h> #include "lcd.h" #define INPUT_LENGTH 12 #define ACCEPTABLE_INPUT_COUNT 2 char getCharacter(void); int input_pos=0; char input[INPUT_LENGTH]; int main() { int i,j; /* Array of data that this programs thinks is acceptable */ char acceptable_inputs[ACCEPTABLE_INPUT_COUNT][INPUT_LENGTH] = { "$0016221826", "$0016234114"}; lcd_init(); lcd_clear(); SCON = 0x50; TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */ TH1 = 0xFD; /* reload value for 2400 baud */ TR1 = 1; while(1) { input[input_pos++] = getCharacter(); if(input_pos==11) { for (i = 0; i < ACCEPTABLE_INPUT_COUNT; i++) { j = strcmp(acceptable_inputs[i],input); if(j==0) { lcd_printxy(1,8,"yes"); input_pos=0; } else { lcd_printxy(1,1,"no"); input_pos=0; } } } } } char getCharacter (void) { char chr; /* variable to hold the new character */ while (RI != 1) ; chr = SBUF; RI = 0; return(chr); }
when i debug step wise its working properly. when i download it to the microcontroller and give input i.e rfreader will read the ID number and sends it to MCU, the o/p is no, and again when i try to download for the next time i,e as soon as i click on "start" to download the program, output will be yes. Please help me to resolve this
Sorry, but no. You haven't debugged your code. It does not work when you step through it either.
You don't need to step through in a debugger - enough to follow the flow with pen and paper and try three different alternatives. Code matching first acceptable key. Code matching second acceptable key. Code not matching any key.
for (i = 0; i < ACCEPTABLE_INPUT_COUNT; i++) { j = strcmp(acceptable_inputs[i],input); if (j==0) { lcd_printxy(1,8,"yes"); input_pos=0; } else { lcd_printxy(1,1,"no"); input_pos=0; } }
How did you decide that if your input fails the test against the first code, it's a failure? Don't you think you need to iterate through the full array and first when all known codes mismatches, it's a fail?
Did't you notice that when you did your stepping through the code?
Why are you in such a hurry? The logic is simple. But to get something to work, you need to have the patience to work out all acceptable and unacceptable paths and verify that they they happen as expected. Any time you take a shortcut, you cut yourself. It is costing _you_ a lot of time, that you don't work a bit slower and really try to follow the logic of your code.
for (i = 0; i < ACCEPTABLE_INPUT_COUNT; i++) { j = strcmp(acceptable_inputs[i],input); if(j==0) break; } if (j==0) { lcd_printxy(1,8,"yes"); input_pos=0; } else { lcd_printxy(1,1,"no"); input_pos=0; }
as you said i am getting problem in this part of code. it is receiving all the characters but not able to compare, it is printing "no" on the lcd.. i am not able find out why it is happening so, Sir please help me out. which step of the above code should be corrected.
@Andrew Neil
Why don't you write a bit of the code at a time and test it before doing the next bit. You stand a chance of creating a whole project that works properly.
View all questions in Keil forum