<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>8051 interrupts</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/14632/8051-interrupts</link><description> I am trying to generate an interrupt when a byte is received via the serial port of an Atmel AT89C51. I am not having much luck. Here is my code: 
 
#include &amp;lt;reg51.h&amp;gt;
#include &amp;lt;CTYPE.H&amp;gt;
#include &amp;lt;STDIO.H&amp;gt;
#include &amp;lt;INTRINS.H&amp;gt;

int big_d, count, dogg</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/141167?ContentTypeID=1</link><pubDate>Mon, 18 Feb 2002 10:07:02 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:71ac44a2-c636-4b92-afef-07ee870ede6b</guid><dc:creator>Robert Berkey</dc:creator><description>&lt;p&gt;A hybrid design in which characters are received via interrupts and sent using polling is common professional design.  &lt;br /&gt;
&lt;br /&gt;
The 8051 has the complication that the transmit interrupt cannot be ignored.  I&amp;#39;ve already shown that the polling loop needs only two instructions.  Moving the character to SBUF requires one.  That is three opcodes.&lt;br /&gt;
&lt;br /&gt;
The transmit interrupt can be as simple as:&lt;br /&gt;
&lt;pre&gt;
SERIAL_INTERRUPT:
   JBC TI, TINTERRUPT
&amp;lt;receive interrupt processing&amp;gt;


TINTERRUPT:
   SETB TRE
   RETI
&lt;/pre&gt;
&lt;br /&gt;
So the entire driver can be done with six opcodes and one memory bit.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/141169?ContentTypeID=1</link><pubDate>Mon, 18 Feb 2002 04:19:13 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:4de1df3d-2e98-4a33-a087-654ea475dc25</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;&lt;i&gt;&amp;quot;P.S. Andrew, I refuse to make a Windows-based configurator for the interrupt-driven serial port example--so don&amp;#39;t even ask. :-p&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
I wasn&amp;#39;t going to - &lt;i&gt;FastChip&lt;/i&gt; does it for me!  ;-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/137585?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 14:26:36 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:39fbd39d-2718-4e84-bba2-c9be9c6ae267</guid><dc:creator>Jon Ward</dc:creator><description>&lt;p&gt;&lt;i&gt;Depending on the application, you might just as well have saved all the timing overhead from filling the ring buffer.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&lt;b&gt;There&amp;#39;s very little over head in having putchar check file scoped bit var called txRingFull. No more than checking if TI is set. I always write my own putchar/getchar.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Polling requires a delay of 1 character time between writes into SBUF.  So, at 2400 baud, when you write into SBUF you must wait for 1/240th seconds.  This is FOREVER in a real-time program.  Sending a 240-byte string eats up 1 second of processing time (including waiting for the TI bit).&lt;br /&gt;
&lt;br /&gt;
Circular buffers are FAST. Writes into the buffer execute in a few instruction cycles.  Assuming the buffer is large enough, sending a 240-byte string is practically instantaneous.&lt;br /&gt;
&lt;br /&gt;
Using an RTOS, you can implement a DELAY to allow other tasks to run.  With polling, the delay will always be 1 character time.  However, with a buffered system, the delay will be the total character time represented by the buffer (which can be closer to 0.3-0.4 seconds).&lt;br /&gt;
&lt;br /&gt;
The argument that interrupt-driven/buffered serial I/O is complex is moot.  If you implement the circular buffer for receive, just copy it and make a few changes for transmit.  It&amp;#39;s only 3-4 lines of code in and out.&lt;br /&gt;
&lt;br /&gt;
But, my primary point is...&lt;br /&gt;
&lt;br /&gt;
It&amp;#39;s already been written.  It&amp;#39;s available for you to use.  There&amp;#39;s no royalty required.  You get source code.  It&amp;#39;s commented.&lt;br /&gt;
&lt;br /&gt;
What more could a developer want?  :-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jon&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
P.S. Andrew, I refuse to make a Windows-based configurator for the interrupt-driven serial port example--so don&amp;#39;t even ask.  :-p&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/134063?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 13:05:49 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:18f1f3da-a6d1-4402-8306-46eebbaf8fca</guid><dc:creator>Mark Odell</dc:creator><description>&lt;p&gt;&lt;i&gt;Using a transmit interrupt to send data is an unnecessary complication if you want to avoid the extra complexity of a transmit ring buffer.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Trivial complexity.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;And what are you going to do if your ring buffer is full? Poll the ring buffer? &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Same thing you do when TI is not set. Block. You just block on txRingFull or throw an assert if it shouldn&amp;#39;t happen or return a failure and put the task to sleep for another timer tick if mutitasking.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Depending on the application, you might just as well have saved all the timing overhead from filling the ring buffer.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;There&amp;#39;s very little over head in having putchar check file scoped bit var called txRingFull. No more than checking if TI is set. I always write my own putchar/getchar.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;As for multi-tasking applications, there is no requirement in multi-tasking that you have more than one task that needs to transmit characters.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Says who? It is a very critical requirement on my current project. All tasks must be able to have printf call level atomicicity to prevent inter char output mangling. It works very well.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Regards.&lt;br /&gt;
&lt;br /&gt;
- Mark&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/121723?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 12:53:36 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:8ae653e1-ee25-4845-b5e5-9dc767b402e8</guid><dc:creator>Robert Berkey</dc:creator><description>&lt;p&gt;Using a transmit interrupt to send data is an unnecessary complication if you want to avoid the extra complexity of a transmit ring buffer.  And what are you going to do if your ring buffer is full?  Poll the ring buffer?  Depending on the application, you might just as well have saved all the timing overhead from filling the ring buffer.&lt;br /&gt;
&lt;br /&gt;
As for multi-tasking applications, there is no requirement in multi-tasking that you have more than one task that needs to transmit characters.&lt;br /&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/121710?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 10:25:23 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:5d1ee1fd-13fa-489c-a796-d80252f022db</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;The example code cited earlier by Jon implements the ring buffer technique just described by Mark.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/85099?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 09:56:25 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3a8ede27-30f6-4b7a-9a7e-e0577d361107</guid><dc:creator>Mark Odell</dc:creator><description>&lt;p&gt;Do you understand that there is no transmit interrupt vector? The 8051 has a combined serial interrupt vector that either the RI or TI flag or both cause a vector to.&lt;br /&gt;
&lt;br /&gt;
You cannot have a serial receive interrupt vector service routine that does not check RI and TI or at least ignore TI.&lt;br /&gt;
&lt;br /&gt;
Polling for TI is silly if you want to have some level of hardware muti-tasking. You fill up a packet buffer, set TI and let the UART ISR send out the entire packet without further intervention from the background task or main() loop.&lt;br /&gt;
&lt;br /&gt;
Going further, you can ring buffer both the xmit and recv so that getchar pulls from the recv ring and putchar puts into the xmit ring. The serial ISR puts and pulls from the opposite rings.&lt;br /&gt;
&lt;br /&gt;
It all works swimmingly. The only caveat is that at very high baud rates, slower 8051&amp;#39;s cannot get the next byte into/from the Tx/Rx buffer in time with interrupt overhead.&lt;br /&gt;
&lt;br /&gt;
- Mark&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/84222?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 08:30:29 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:5ff9cf02-0c92-46c2-bf36-39d6f10480d0</guid><dc:creator>Robert Berkey</dc:creator><description>&lt;p&gt;No, polling of only the transmitter is common (and I would argue &amp;quot;good&amp;quot;) practice.&lt;br /&gt;
&lt;br /&gt;
Since there is no bit for &amp;quot;Transmitter Register Empty&amp;quot; (TRE), you can use the transmitter interrupt to implement TRE.  I&amp;#39;d suggest that you consider using JBC when polling TRE to avoid potential design problems in case you ever decide to send characters from the receive interrupt.  This might happen if you needed XON XOFF flow control.&lt;br /&gt;
&lt;pre&gt;
_1:     JBC   TRE, _2
        JMP   _1
_2:
&lt;/pre&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/94971?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 06:08:19 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:8fc0598d-4c28-4569-a44d-829f7bc69e84</guid><dc:creator>erik  malund</dc:creator><description>&lt;p&gt;&amp;quot;I would like to just use the interrupt to receive characters so I can increment a counter everytime I receive a byte.&amp;quot;&lt;br /&gt;
Increment the counter only if (RI)&lt;br /&gt;
&lt;br /&gt;
Erik&lt;br /&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/109959?ContentTypeID=1</link><pubDate>Fri, 15 Feb 2002 03:16:40 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:7ecb6d88-daba-437e-bae0-94d197128372</guid><dc:creator>Andy Neil</dc:creator><description>&lt;p&gt;&lt;i&gt;&amp;quot;The example link that I provided already handles serial transmit and receive in the interrupt, so you don&amp;#39;t have to write anything.&amp;quot;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Yes, I have used the example code that Jon cited and can confirm that it really does work - just like it says on the tin!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/94956?ContentTypeID=1</link><pubDate>Thu, 14 Feb 2002 18:29:07 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:5097caec-8fb3-4546-89a2-5d4a916d0f95</guid><dc:creator>Jon Ward</dc:creator><description>&lt;p&gt;&lt;i&gt;Do I need to send my characters in my interrupt subroutine as well?&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Well, technically speaking, no, you don&amp;#39;t need to send characters from the interrupt.  However, if you enable the serial interrupt, you will receive an interrupt when TI is set or when RI is set.  And, you will have to do a lot of work to get around this.&lt;br /&gt;
&lt;br /&gt;
The example link that I provided already handles serial transmit and receive in the interrupt, so you don&amp;#39;t have to write anything.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jon&lt;/b&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/54181?ContentTypeID=1</link><pubDate>Thu, 14 Feb 2002 17:43:36 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:aac357b1-931a-4d73-918b-908b11bd7352</guid><dc:creator>Hummer Hatchette</dc:creator><description>&lt;p&gt;Thanks for the info.  Do I need to send my characters in my interrupt subroutine as well?  I would like to just use the interrupt to receive characters so I can increment a counter everytime I receive a byte.&lt;br /&gt;
Jake&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/38387?ContentTypeID=1</link><pubDate>Thu, 14 Feb 2002 12:13:11 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:3a556eb4-f011-4b5c-875e-f4f5f166b4f8</guid><dc:creator>Jon Ward</dc:creator><description>&lt;p&gt;There are several problems with this program.&lt;br /&gt;
&lt;br /&gt;
1. Global interrupts are not enabled.  You must set the EA bit to enable them.&lt;br /&gt;
&lt;br /&gt;
2. You set the TI bit initially to allow transmission of characters, however, this triggers an interrupt.  Your interrupt routine does not handle sending characters.&lt;br /&gt;
&lt;br /&gt;
3. You interrupt calls _getkey to retrieve the character from the SBUF.  The problem with this is that _getkey clears the TI bit.  Your interrupt ALSO clears the TI bit.  So, if a serial character is receive between these times, it will be lost.&lt;br /&gt;
&lt;br /&gt;
4. I can only assume that this program is designed to receive serial characters in the interrupt and to transmit serial characters in a polled fashion.  This is BAD.&lt;br /&gt;
&lt;br /&gt;
A serial I/O example program already exists for the 8051.  Take a look at &lt;a href="http://www.keil.com/download/docs71.asp"&gt;http://www.keil.com/download/docs/intsio.zip.asp&lt;/a&gt; for a working example.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jon&lt;/b&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/54182?ContentTypeID=1</link><pubDate>Thu, 14 Feb 2002 10:17:39 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e695121b-ba7e-47c6-8088-06248c44c371</guid><dc:creator>Mark Odell</dc:creator><description>&lt;p&gt;I meant to say check for RI, read SBUF, and then clear RI. You would never need to read SBUF if RI was not set.&lt;br /&gt;
&lt;br /&gt;
- Mark&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 8051 interrupts</title><link>https://community.arm.com/thread/38388?ContentTypeID=1</link><pubDate>Thu, 14 Feb 2002 10:11:49 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e7cda2d3-becf-4f25-9be9-60d654d2aef4</guid><dc:creator>Mark Odell</dc:creator><description>&lt;p&gt;Start by making variables shared between background and interrupt functions volatile. This goes for memory mapped hardware variables too.&lt;br /&gt;
&lt;br /&gt;
The call to _getkey() is potentially dangerous too if called by other non-interrupt functions. Just read SBUF and clear RI if set. Remember, either TI or RI will set off your interrupt so you need to check for RI before reading SBUF.&lt;br /&gt;
&lt;br /&gt;
- Mark&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>