free 8051 Microcontroller Projects AVR PIC Microcontroller Projects Tutorials Ebooks Libraries, interfacing tutorials, lcd tutorial, stepper motor, dc motor 8051 assembly language programming electronics and communication ECE CSE pdf ebooks library BE final year project ideas Embedded systems

 
8051 microcontroller 8051 microcontroller
Forums

Rickey's World :: Discussion Forums :: Discuss and Learn :: 8051 Discussion Forum
 
<< Previous thread | Next thread >>
Unexplainable (for me) printf behaviour
Go to page       >>  
Moderators: Ajay Bhargav, Arun Kumar V, pdi33, Shailesh NAYAK, ۞ TPS ۞, shyam, sashijoseph, ExperimenterUK, DavesGarage
Author Post
kazola
Sun Jul 12 2009, 03:39PM
 User Offline
Registered Member #20243
Joined: Sun Jul 12 2009, 03:26PM

Posts: 9
Thanked 0 times in 0 posts
Hi everybody!
I've just joined Rickey's World.
I'm Joaquim, I hope I'll be around here during this year. I've worked in the RFID area so I'll try to help if there is somebody with a doubt in that area
I've search for a solution to my problem for a couple of days in this and others forums and there are people in the same situation, however, I've not been able to apply their solutions to my problem. I hope somebody in this forum will
In fact, I don't know what I'm doing wrong! Here is the code:

CODE:


#include "reg_c51.h"
#include <stdio.h>

char uart_data;
char caracter;
short index;
char trama[20];

char getchar (void)
{
char chr; /* variable to hold the new character */
while (RI != 1) {;}
/* now read the value in the serial buffer into the local variable */
chr = SBUF;
RI = 0;
/* the character is then returned to the calling function. */
return(chr);
}


char putchar(char chr) {
SBUF = chr;
}

/**
 * FUNCTION_PURPOSE: This file set up uart in mode 1 (8 bits uart) with
 * timer 2 in baud rate generator mode.
 * FUNCTION_INPUTS: void
 * FUNCTION_OUTPUTS: void
 */

void main (void)
{
        SCON = 0x50;                                      /* uart in mode 1 (8 bit), REN=1 */
   T2CON &= 0xF0;               /* EXEN2=0; TR2=0; C/T2#=0; CP/RL2#=0; */
   T2CON |= 0x30;               /* RCLK = 1; TCLK=1; */
   TH2=0xFF;                    /* init value */
   TL2=0xFD;                    /* init value */
   RCAP2H=0xFF;                 /* reload value, 115200 Bds at 11.059MHz */
   RCAP2L=0xFD;                 /* reload value, 115200 Bds at 11.059MHz */
        ES = 1;                                                      /* Enable serial interrupt */
        EA = 1;                                              /* Enable global interrupt */
   TR2 = 1;                     /* Timer 2 run */
   TI = 1;


   while(1) {                    /* endless */
        caracter = getchar();
        if((caracter=='\r') || (caracter=='\n')) {
            caracter = '\n';
            trama[index] = caracter;
            index = 0;
            //printf("%s",trama);
            printf("hello8051guys\n");
        }
        else {
            trama[index++] = caracter;
        }
   }
}              

/**
 * FUNCTION_PURPOSE: serial interrupt, echo received data.
 * FUNCTION_INPUTS: P3.0(RXD) serial input
 * FUNCTION_OUTPUTS: P3.1(TXD) serial output
 */

void serial_IT(void) interrupt 4
{
        if (RI == 1)
        {                                                /* if reception occur */
          RI = 0;                                  /* clear reception flag for next reception */
          uart_data = SBUF;          /* Read receive data */
          //SBUF = uart_data;           /* Send back same data on uart*/
        }
        else TI = 0;                  /* if emission occur */
                                          /* clear emission flag for next emission*/           
}
 


Simple, isn't it? I think this code is so known by any programmer. My idea is to collect some characters and print the entire string when an "enter" is pressed. When this is achieved, if there is some constant string like "hello8051guys" no problem arise. When I comment that one and try to get the char array I've been building, there is no answer!
I have redefined putchar and getchar but anything appears on the screen Does anybody have a great idea? Perhaps am I doing something incredibly wrong?
Well, I'll be waiting for your wise answers.

Sorry for my English, I'm from Catalonia! Have a good night!

Back to top

shyam
Sun Jul 12 2009, 10:51PM

 User Offline

Registered Member #2984
Joined: Mon Aug 06 2007, 11:33AM

Posts: 847
Thanked 136 times in 125 posts
try this.....

CODE:
 while(1)
 {                    /* endless */
        caracter = getchar();
        if((caracter=='\r') || (caracter=='\n'))
        {
            caracter = '\n';
            trama[index] = caracter;
            trama[index+1]='\0';
            index = 0;
            printf("%s",trama);
           // printf("hello8051guys\n");
        }
        else
        {
            trama[index++] = caracter;
         }
}


lProgress is not made by early risers or hard workers, but by LAZY people, trying to find easier ways to do the same........
Back to top

kazola
Mon Jul 13 2009, 02:40AM
 User Offline
Registered Member #20243
Joined: Sun Jul 12 2009, 03:26PM

Posts: 9
Thanked 0 times in 0 posts
No luck!
In fact I rely on the initial "0x00" positions on the char array to detect the string end.
I attach an image with the situation I obtain in KEIL.

http://firestation.shacknet.nu/

In the "Watch" window we can see the string is well build and in the "Serial #1" window we can see the string is on the 3rd line... it really detects the "enter" but no string is displayed.

Another suggestion? Perhaps I'm misunderstanding something?
Back to top

shyam
Mon Jul 13 2009, 03:12AM

 User Offline

Registered Member #2984
Joined: Mon Aug 06 2007, 11:33AM

Posts: 847
Thanked 136 times in 125 posts
try initialising index to 0 before the wile loop

lProgress is not made by early risers or hard workers, but by LAZY people, trying to find easier ways to do the same........
Back to top

kazola
Mon Jul 13 2009, 03:19AM
 User Offline
Registered Member #20243
Joined: Sun Jul 12 2009, 03:26PM

Posts: 9
Thanked 0 times in 0 posts
Hehe, thanks for helping Shyam!
No luck again
Anybody thinks the threat in the following link
http://www.keil.com/forum/docs/thread6798.asp
is useful?
I'm working with a AT89C51ED2, the clock rate = 22.1184
I know the code is for a 11.0592MHz cristal, but it would not explain why a constant string like "hello8051guys" is well processed, would it?
Back to top

Ajay Bhargav
Mon Jul 13 2009, 01:29PM
Rickey's World Admin

 User Offline

Registered Member #1
Joined: Fri Feb 24 2006, 04:56AM

Posts: 7567
Thanked 1330 times in 1254 posts
printf and getchar functions doest work with interrupts.. disable interrupts and try again

www.rickeyworld.info
If you feel satisfied with the user's forum reply please click on the thank button.

Obey forum rules!
Respect others!
Back to top

DavesGarage
Mon Jul 13 2009, 03:44PM

 User Offline
Registered Member #14254
Joined: Tue Jan 20 2009, 08:14AM

Posts: 621
Thanked 116 times in 112 posts
Yeah, you're setting up timer 2, but your interrupt is #4 - isn't that the timer #1 interrupt?


-Dave
"Basic research is what I am doing when I don't know what I am doing"
Back to top

DavesGarage
Mon Jul 13 2009, 03:46PM

 User Offline
Registered Member #14254
Joined: Tue Jan 20 2009, 08:14AM

Posts: 621
Thanked 116 times in 112 posts
Also, I don't think you can achieve 115.2k baud with a 11Mhz crystal...

You'll either have to cut your baud rate in half, or double your crystal frequency...



-Dave
"Basic research is what I am doing when I don't know what I am doing"
Back to top

kazola
Mon Jul 13 2009, 04:10PM
 User Offline
Registered Member #20243
Joined: Sun Jul 12 2009, 03:26PM

Posts: 9
Thanked 0 times in 0 posts
Thanks to everybody!
Dave, cristal is 22.1184.
I have been thinking about the problem during all this afternoon.
It seems it is a very common problem and the solution is found at
http://www.keil.com/forum/docs/thread11351.asp
Back to top

DavesGarage
Mon Jul 13 2009, 04:14PM

 User Offline
Registered Member #14254
Joined: Tue Jan 20 2009, 08:14AM

Posts: 621
Thanked 116 times in 112 posts
Here is a simple program to test your processor with, that uses some handshaking in the get / put char routines:

See if this works on your system:

CODE:

#include "reg_c51.h"
#include <stdio.h>


char TxInUse;
char RxWaiting;
char RxInChar;

#define FREQ 22118400
#define BAUDRATE 115200

// --------------------------------------------------------------------
// --------------------------------------------------------------------
char getchar()
   {
   char TempChar;

   while( RxWaiting );
   TempChar = RxInChar;
   RxWaiting = 1;
   return( TempChar );
   }

// --------------------------------------------------------------------
// --------------------------------------------------------------------
char putchar(char chr)
   {
   while( TxInUse );
   SBUF = chr;
   TxInUse = 1;
   return( chr );
   }

// --------------------------------------------------------------------
// --------------------------------------------------------------------
void main (void)
   {

   char Junk;

   EA          = 0;     /* disable interrupts...                     */
   
   SCON0       = 0x50;  /* Setup serial port registers               */
   
   TI          = 0;     /* clear transmit interrupt                  */
   RI          = 0;     /* clear receiver interrupt                  */
   ES0         = 1;     /* enable serial interrupts                  */
   PS0         = 0;     /* set serial interrupts to low priority     */
   EA          = 1;     /* Enable Interrupts                         */

   ES0         = 0;     /* disable interrupts                        */
   
   
   TI          = 0;     /* Clear interrupt flag and char buffers     */
   TxInUse     = 0;     /* transmitter is disabled                   */
   RxWaiting   = 1;     /* receiver is waiting for a character...    */
   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;  /* timer 1 into MODE 2 : 8-bit, auto-reload  */
   TH1         = (unsigned char)(256.0 - ((float)(FREQ) / (192.0 * (float)(BAUDRATE))));
   TR1         = 1;     /* start timer 1                             */
   
   
   ES0         = 1;     /* enable interrupts                         */
   
   /* some simple text... */
   printf("This is a sample string\r\n");
   printf("Nothing very important\r\n");
   for( Junk='0'; Junk<='9'; Junk++ )
      putchar( Junk );
   printf("\r\n\n");

   /* a simple character echo routine */
   printf("Type all you want...\r\n");
   while( 1 )
      {
      putchar( getchar() );
      }
   }              

// --------------------------------------------------------------------
// --------------------------------------------------------------------
void SER_ISR() interrupt UART0_VECTOR
   {
   /* Received value interrupt    */
   if( RxWaiting )
      {
      if( RI )
         {
         RI = 0;
   
         /* get byte if there's room in the buffer */
         RxInChar = SBUF0;
         RxWaiting = 0;
         }
      }

   /* Transmitted value interrupt */
   if( TxInUse )
      {
      /* if transmit flag is set, then previous byte is finished transmitting */
      if( TI )
         {
         TI = 0;
         TxInUse = 0;
         }
      }
   }

 


-Dave
"Basic research is what I am doing when I don't know what I am doing"
Back to top

Go to page       >>   

Jump:     Back to top

Syndicate this thread: rss 0.92 Syndicate this thread: rss 2.0 Syndicate this thread: RDF
Powered by e107 Forum System

8051 Microcontroller Projects 8051 AVR tutorials PIC microcontroller, 8051 assembly language programming electronics and communication ECE CSE pdf ebooks library BE final year project ideas Embedded systems