Why It is stuck in loop? RX pin is not receiving data from Virtual Terminal? #proteus

Thread Starter

vedaraj

Joined Apr 23, 2022
1
This code is to simulate RFID reader working using AT89C51 in Proteus Software. Instead of RFID reader i am using Virtual Terminal for sending or scanning RFID, here in my case I am Typing ID in Virtual Terminal, string 'a' stores input and compares with existing string and gives Output. Problem here is the ID I am typing in virtual terminal is not copied to string 'a'. It is stuck in while loop. RI is a interrupt flag that tells if any serial data received in RX pin.

``
#include<reg51.h>
#include<string.h>

void delay( unsigned int i );
void lcd_cmd( unsigned char a );
void lcd_data( unsigned char b );
void lcd_init( void );
void lcd_str( unsigned char* str );
void sendser_char( unsigned char b );
void sendser_str( unsigned char* str );
sbit rs = P2 ^ 0;
sbit en = P2 ^ 1;
unsigned int i;
unsigned char a[60], b[10];
sfr ldata = 0x90;//port1
void clear( void );

void main()
{
TMOD = 0x20;//timer1 mode2 -auto reload mode
TH1 = 0xfd;//9600 baud rate
SCON = 0x50;//8bit data ,1start bit,1stop bit
TR1 = 1;
REN = 1;
lcd_init();
lcd_str( " WELCOME TO " );
lcd_cmd( 0xc0 );
lcd_str( " MY PROJECT " );

delay( 65000 );
while( 1 )
{
lcd_cmd( 0x01 );
lcd_cmd( 0x80 );
lcd_str( " Waiting For " );
delay( 65000 );
lcd_cmd( 0xc0 );
lcd_str( " RFID Tag " );
delay( 65000 );

for( i = 0; i < 10; i++ )
{
while( RI == 0 ); //------------------------------------->code is stuck here, RI value shall be changed
//------------------------------------->when input given in virtual terminal.but it is never changing.
a = SBUF;
RI = 0;
}
a = '\0';
delay( 65000 );
if( 0 == strcmp( "0123456789", a ) )
{
lcd_cmd( 0x01 );
lcd_cmd( 0x80 );
lcd_str( " WELCOME USER 1" );
lcd_cmd( 0xc0 );
lcd_str( a );
delay( 65000 );
clear();
}
else if( 0 == strcmp( "10003B0CAE", a ) )
{
lcd_cmd( 0x01 );
lcd_cmd( 0x80 );
lcd_str( " WELCOME USER 2" );
lcd_cmd( 0xc0 );
lcd_str( a );
delay( 65000 );
clear();
}
else
{
lcd_cmd( 0x01 );
lcd_cmd( 0x80 );
lcd_str( " INVALID TAG" );
lcd_cmd( 0xc0 );
lcd_str( a );
delay( 65000 );
clear();
}
}
}

void lcd_init()
{
lcd_cmd( 0x38 );
lcd_cmd( 0x0c );
lcd_cmd( 0x01 );
lcd_cmd( 0x80 );
}

void delay( unsigned int i )
{
unsigned int j;
for( j = 0; j < i; j++ );
}

void lcd_cmd( unsigned char a )
{
rs = 0;//cmd
ldata = a;
en = 1;
delay( 5 );
en = 0;
delay( 5 );
}

void lcd_data( unsigned char b )
{
rs = 1;//data
ldata = b;
en = 1;
delay( 5 );
en = 0;
delay( 5 );
}

void lcd_str( unsigned char* str )
{
while( *str )
{
lcd_data( *str++ );
}
}

void sendser_char( unsigned char b )
{
SBUF = b;
while( TI == 0 );
TI = 0;
}

void sendser_str( unsigned char* str )
{
while( *str )
{
sendser_char( *str++ );
}
}
``
 

djsfantasi

Joined Apr 11, 2010
9,163
It’s hard to scan your code from a smartphone, but I don’t see any possible way RI could be changed. You set it to zero. You test it for zero. But you never change its value.
 

click_here

Joined Sep 22, 2020
548
Looking at that part of the code...

How is RI declared? If you are using it in an interrupt you would usually have to declare it as 'volatile'.

Code:
    for( i = 0; i < 10; i++ )
    {
        while( RI == 0 ); 
        
        a = SBUF;
        RI = 0;
    }
    
    a = '\0';
'a' is an array ~ You want to do something more like this...
Code:
    for( i = 0; i < 10; i++ )
    {
        while( RI == 0 ); 
        
        a[i] = SBUF;
        RI = 0;
    }
    
    a[10] = '\0';
Hope that helps :)
 

click_here

Joined Sep 22, 2020
548
Also, you have name clashes with 'a' and 'b'
Code:
// Global variables
unsigned char a[60], b[10];
...
void lcd_cmd( unsigned char a )
... 
void lcd_data( unsigned char b )
You should give them a more descriptive name.

It is usually considered good practice to avoid unnecessary global variables, this is one of the reasons why :)
 
Top