This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I can't get familiar with PUTCHAR and PUTS

I've got a problem. I've posted it yesterday but it was probably lost in text.

static void Nastav_seriovy_kanal (void)
{
	SCON = 0x50;
	TMOD = TMOD | 0x20;
	TH1 = 0xF4;
	TL1 = 0xF4;
	ES = 1;
	TR1 = 1;
}

static void Preruseni_seriovy_kanal (void) interrupt 4
{
	if (RI == 1)
	{
	    RI = 0;
	    if(SBUF == 'A') putchar('Q');
	}
	if (TI == 1) TI = 0;
}
I'm also including stdio.h, and string.h(string.h is not necessary).

Does anyone have any idea why it doesn't work?

Parents
  • Putchar procedure doesn't work as I expected.
    In my opinion and I hope it's clearly said in that source code I've posted, it should work as follows.

    When 'A' character is received through serial port of x51 processor it sends a 'Q' character back. But it won't send anything back.

    There are no errors or warnings. Serial port is functional.

Reply
  • Putchar procedure doesn't work as I expected.
    In my opinion and I hope it's clearly said in that source code I've posted, it should work as follows.

    When 'A' character is received through serial port of x51 processor it sends a 'Q' character back. But it won't send anything back.

    There are no errors or warnings. Serial port is functional.

Children
  • I could simply change it as follows.

    if(SBUF == 'A') SBUF = 'Q';

    and it WILL work. But I want to use PUTCHAR and later PUTS procedures to communicate through serial port.

  • In my opinion and I hope it's clearly said in that source code I've posted,

    It doesn't say anything in your source code, as there are no comments. Someone who actually goes through the trouble of trying to understand the source code might figure it out. However, please be aware that understanding uncommented source code is very difficult - and even more so for someone who is not the author of the code.

    That aside, let's look at the problem.

    Did you set a breakpoint in the ISR to see if it is actually called ? Your code excerpt does not show the EA bit being set anywhere, but I would guess that you've thought of that and do it somewhere else in your code.

    Did you have a look at the source code of the putchar function ? It should be in C51/lib somewhere.

    Do you call putchar() from anywhere else in the program ? The function is _not_ reentrant, so if you call it in the normal program and in an ISR without taking some precautions, problems are pretty much guaranteed.

  • "It doesn't say anything in your source code, as there are no comments."

    Even the function names aren't in English!

  • "I want to use PUTCHAR and later PUTS procedures to communicate through serial port."

    It is a very bad idea to try to use these in an interrupt service routine!

    For interrupt-driven serial IO, see:

    http://www.keil.com/download/docs/71.asp

    This shows you how to write a custom putchar to use interrupt-driven serial comms.

  • It is a very bad idea to try to use these in an interrupt service routine!

    Well ... yeah.

    You can use them in an ISR, as long as you're aware that they are going to hog CPU cycles like crazy (they spinlock if the serial transmitter is busy) and that they're not reentrant.

    Also, I think there's some code putchar.c that could drop characters or enter an endless loop under certain rare circumstances. Something along the lines of

    do
    {
      RI = 0;
      while(!RI);
    } while(SBUF != XON)
    

    With some bad luck, RI goes to 1 at the beginning if the do loop, gets overwritten by a 0, and the while loop will run until the next character has been received.

    Certainly, the chances for this are minimal, but I don't see anything that would prevent the behavior.