Discussion in "8051 Discussion Forum" started by    vishie90    Jan 11, 2010.
Mon Jan 11 2010, 07:12 pm
#1
hi im using a p89v51rd2 ic
i wrote a simple program for serial communication with the pc i am having the following problem.
1) i want the char 'a' & 's' to be shown on the output only once and dont want them to be repeated as shown below.
PLS reply at the earliest
PROGRAM
#include#define sw P1_1
void main(void)
{
unsigned char fname='a';
unsigned char lname='s';
sw=1;
TMOD=0x20;
TH1=0xFD;
SCON=0x50;
TR1=1;
if(sw==0)
{
SBUF=fname;
while(TI==0);
TI=0;
}
else
{
SBUF=lname;
while(TI==0);
TI=0;
}}
OUTPUT(as seen in TERMINAL)
ssssssaaasssaaasssaa ...



[ Edited Mon Jan 11 2010, 08:41 pm ]
Mon Jan 11 2010, 08:40 pm
#2
When using a microcontroller (no operating system),
you must remember that it is fetching and executing
instructions, one after another, over and over again,
while there is power applied.

What do you suppose happens when it gets to the end
of the main() function above?

It continues trying to fetch another instruction, but from where?

The very next memory location.

If there is a NOP there, it continues. If an executable
instruction, then it will execute that instruction.
If garbage, then who knows?

This will continue over and over again until it ether hangs, runs out of memory (0xFFFF),
where it will start over again at 0x0000, or resets, but it all depends on
what is in memory at the time.

A good rule of thumb is "never leave your processor unattended",
sort of like a child with sharp objects.

Try adding an infinite loop at the end of your main() function, like this:
 while(1);


See if this doesn't solve your problem...
Mon Jan 11 2010, 08:52 pm
#3
no it is still producing the continuous characters!!
Mon Jan 11 2010, 08:57 pm
#4
i would be happy if u told me how to produce just a single character only once!!
Tue Jan 12 2010, 01:37 am
#5
But I did...

I told you how, and you said it is still producing continuous characters, so you must have made a mistake!

If you want a simple solution to your problem WITHOUT learning anything, you can just copy the software from this thread:

http://www.8051projects.net/forum-t28908.html

I wrote this thread as an example that can be studied, and hopefully learned from, but it will do what you want very simply...

Here is a complete example for you to just copy and paste, if you like:
//=====================================================================
// simple example software for testing serial interface...            
//=====================================================================
#include "AT89X51.H"        //    
#include <stdio.h>
 //

#define sw P1_1   //

#define BUF_SIZE           16          // buffer size for both Rx  
                                       // and Tx buffers            
#define MICRO_FREQUENCY    11059200.0  // frequency of micro...    

typedef unsigned char BYTE;
typedef unsigned long ULONG;
typedef unsigned int WORD;

#define UART0_VECTOR       4           //0x23 Serial Port 0        

volatile BYTE TxBuffer[ BUF_SIZE ];  
volatile BYTE RxBuffer[ BUF_SIZE ];  
volatile BYTE RxInChar;
volatile BYTE RxOutChar;
volatile BYTE TxInChar;
volatile BYTE TxOutChar;
volatile BYTE TxEnabled;

//=====================================================================
// init routine for ISR handler...                                    
//=====================================================================
void SER_init()
   {
   /* disable interrupts...       */
   EA          = 0;
   
   /* clear com buffer indexes... */
   TxInChar    = 0;
   TxOutChar   = 0;
   TxEnabled   = 0;
   RxInChar    = 0;
   RxOutChar   = 0;
   
   /* Setup serial port registers */
   SM0         = 0;
   SM1         = 1;           // serial port MODE 1
   SM2         = 0;
   REN         = 1;           // enable serial receiver
   TI          = 0;           // clear transmit interrupt
   RI          = 0;           // clear receiver interrupt
   ES          = 1;           // enable serial interrupts
   PS          = 0;           // set to low priority
   EA          = 1;           // Enable Interrupts
   }

//=====================================================================
//=====================================================================
void SER_ISR() interrupt UART0_VECTOR using 2
   {
   /* Received value interrupt    */
   if( RI )
      {
      RI = 0;

      /* get byte if there's room in the buffer */
      if( ((RxInChar + 1)%BUF_SIZE) != RxOutChar )
         {
         RxBuffer[ RxInChar++ ] = SBUF;
         RxInChar %= BUF_SIZE;
         }
      }

   /* Transmitted value interrupt */
   if( TxEnabled )
      {
      /* if previous byte is finished transmitting */
      if( TI )
         {
         TI = 0;

         /* adjust queue and transmit character... */
         if (TxOutChar != TxInChar)
            {
            SBUF = TxBuffer [TxOutChar++];
            TxOutChar %= BUF_SIZE;
            }
         else
            /* nothing else to transmit, so disable function... */
            TxEnabled = 0;
         }
      }
   }

//=====================================================================
//=====================================================================
void SER_setbaud( ULONG BaudRate )
   {
   /* disable interrupts */
   ES           = 0;
   
   /* Clear interrupt flag and buffer */
   TI           = 0;
   TxInChar     = 0;
   TxOutChar    = 0;

   /* transmitter is disabled */
   TxEnabled    = 0;
   
   /* Set timer 1 up as a baud rate generator.  */
   TR1         = 0;           // stop timer 1
   ET1         = 0;           // disable timer 1 interrupt
   PCON       |= 0x80;        // 0x40=SMOD1: set serial baudrate doubler
   TMOD       &= 0x0F;        // clear timer 1 mode bits
   TMOD       |= 0x20;        // put timer 1 into MODE 2 : 8-bit, auto-reload
   TH1         = (BYTE) (256.0 - (MICRO_FREQUENCY / (192.0 * (float)(BaudRate))));
   TR1         = 1;           // start timer 1
   
   /* enable interrupts */
   ES           = 1;
   }

//=====================================================================
//=====================================================================
char putchar( char ThisChar )
   {
   /* wait if buffer is full... */
   while( ( (TxInChar+1) % BUF_SIZE) == TxOutChar );
   
   /* add this character to the transmit buffer */
   ES = 0;
   TxBuffer[ TxInChar++ ] = ThisChar;
   TxInChar %= BUF_SIZE;

   /* if transmitter is disabled enable it */
   if( !TxEnabled )          
      {
      TxEnabled = 1;
      TI = 1;
      }
   
   ES = 1;

   /* return character as default value */
   return( ThisChar );
   }

//=====================================================================
//=====================================================================
void main()
   {
   char fname='a';
   char lname='s';

   // set port pin to 1              
   sw = 1;

   // initialize serial interface...
   SER_init();
   SER_setbaud( 19200 );

   // send 'a' or 's', depending on state of sw...
   if( sw == 0 )
      {
      putchar( fname );
      }
   else
      {
      putchar( lname );
      }
   
   // loop forever...
   while(1);
   }


But, even in this example, you will notice I put the "loop forever" instruction at the end of main(), which is exactly what I suggested you do...

You will have to adjust the value of MICRO_FREQUENCY to fit your target hardware system, and you will have to adjust the value sent to SER_setbaud(...) to match your serial terminal of course.

I hope this will make you happy...
Tags serial programming using 80518051 interrupt driven UART8051 uart library8051 serial port uart
Tue Jan 12 2010, 10:23 am
#6
thanks for the reply. i just realised it would have been much simpler if i had used an external interrupt and a delay which makes it print only the char i want only once!!
and now.. again another question.. how do i make the serial output come to the new line; ie like printf("\n")???
Tue Jan 12 2010, 07:01 pm
#7
jus put 0x0d and 0x0a to sbuf register to print the serial output in next line
0x0d-->carriage return
0x0a-->line feed
Tue Jan 12 2010, 10:44 pm
#8
in other words as hplaneti said
'\r' <- carriage return
'\n' <- line feed

[Topic moved to 8051 Discussion forum]
Wed Jan 13 2010, 08:56 am
#9
ok new problem. im not able to use more than 1 printf in the program it says multiple reference warning
Thu Jan 14 2010, 01:52 am
#10
well are you trying to use printf in interrupt?

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

Bobbyerilar
Thu Mar 28 2024, 08:08 am
pb58
Thu Mar 28 2024, 05:54 am
Clarazkafup
Thu Mar 28 2024, 02:24 am
Walterkic
Thu Mar 28 2024, 01:19 am
Davidusawn
Wed Mar 27 2024, 08:30 pm
Richardsop
Tue Mar 26 2024, 10:33 pm
Stevencog
Tue Mar 26 2024, 04:26 pm
Bernardwarge
Tue Mar 26 2024, 11:15 am