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

Problem while trying to write to Serial Window #1 at regular intervals

Hi All,
I'm trying to write to the Serial Window #1 at regular interval of time (But not successful yet). To generate the time interval i'm using timer0 of 8051 in 16 Bit Timer Mode 0x01
The values are initialized as shown below
TH0 = 0xFF
TL0 = 0x00
In the given program below, if I comment all the printf statements It works fine, generates accurate delay as needed (as seen in Debug Session). i.e. TL0 starts incrementing for every clock tick and when it reaches 0xFF, the next clock tick sets the overflow flag which in turn calls the ISR (Interrupt_Service_Routine0), wherein I again set the timer's TH0 and TL0 value.
But if I uncomment the printf statements in the program (Func1 and Func2), I don't get accurate time delay (as seen in Debug Session). when control reaches Func1 and passes ahead of printf statement the TH0 and TL0 value changes to 0x06 and 0x52 respectively.
As I have understood the timer 0 values should be between FF00 to FFFF (as initialized in the Timer_0_Init and Interrupt_Service_Routine0)
Please do correct me if my understanding is not correct

Using Keil IDE uVision2 V2.38a
Have selected ,b>Generic->8052 (all variants),/b> in the Options for Target in Project Menu
The program is as shown below:

/*------------------------------------------------------------------------------
HELLO.C

Copyright 1995-1999 Keil Software, Inc.
------------------------------------------------------------------------------*/

#include <REG52.H>                /* special function register declarations   */
                                  /* for the intended 8051 derivative         */
#include <stdio.h>                /* prototype declarations for I/O functions */


#ifdef MONITOR51                         /* Debugging with Monitor-51 needs   */
char code reserve [3] _at_ 0x23;         /* space for serial interrupt if     */
#endif                                   /* Stop Exection with Serial Intr.   */
                                         /* is enabled                        */
#define FUNC1           3
#define FUNC2           2

sbit Port1Pin0 = P1^0;
sbit Port1Pin1 = P1^1;
sbit Port1Pin2 = P1^2;
sbit Port1Pin3 = P1^3;

unsigned short myFlag = 0;
unsigned short count = 0;

/* --------------------------------------------------------- */
//Functions (Func1 and Func2)to be called from ISR
void Func1() {
//      printf("Func1\n");

        Port1Pin0 = 1;
        Port1Pin1 = 0;
        Port1Pin2 = 1;
        Port1Pin3 = 0;
}

void Func2() {
//      printf("Func2\n");

        Port1Pin0 = 1;
        Port1Pin1 = 0;
        Port1Pin2 = 0;
        Port1Pin3 = 0;
}

/* --------------------------------------------------------- */
//Initializing TImer0
void Timer_0_Init(void)
{
        TMOD |= 0x01;

        TL0 = 0x00;
        TH0 = 0xFF;

        ET0 = 1;
        TR0 = 1;
        EA = 1;
}

/*----------------------------------------------------------*/
//ISR for Timer 0
void Interrupt_Service_Routine0(void) interrupt 1
{
        TR0 = 0;                //Deactivate Timer 0
        TL0 = 0x00;             //Setting timer Initial value again
        TH0 = 0xFF;             //Setting timer Initial value again
        TF0 = 0;                //Set Timer Overflow Flag to 0
        TR0 = 1;                //Activate Timer 0

        ++count;
        if (myFlag == 0 && count > FUNC1) {
                //Call Func1
                Func1();
                myFlag = 1;
                count = 0;
        }
        else if (myFlag == 1 && count > FUNC2) {
                //Call Func2
                Func2();
                myFlag = 0;
                count = 0;
        }
}

/*------------------------------------------------------------*/
void main(void)
{
/*------------------------------------------------
Setup the serial port for 1200 baud at 16MHz.
------------------------------------------------*/
#ifndef MONITOR51
    SCON  = 0x50;                       /* SCON: mode 1, 8-bit UART, enable rcvr      */
    TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
    TH1   = 221;                /* TH1:  reload value for 1200 baud @ 16MHz   */
    TR1   = 1;                  /* TR1:  timer 1 run                          */
    TI    = 1;                  /* TI:   set TI to send first char of UART    */
#endif

        Timer_0_Init();
        while(1) {
                //Do Nothing, wait for Timer overflow which inturn calls ISR
                ;
        }
}

Thanks for your Time and Help

  • you are calling printf from (a function called by) an ISR, that is an absolute NoNo

    Erik

  • Thanks for immediate reply :-)
    Can U please let me know How can I see whether the functions (Func1 and Func2) are called at regular intervals as per the programs need??
    Or let me know where can I get more info about it!!

  • Erik, along with my prevoius question(s) please also let me know why I cant use printf.
    I'm very new to 8051 and hence any help on this would be great!!. I'm using printf to assist my debugging activity (to see control flow), please do suggest other ways to debug if possible.

    Thanks for your Time and Help

  • and print in the main

    or - even better - toggle a port bit in the ISR and scope on it

    Erik

  • Kaleed told me that you cant use printf in the interruption becoz it is not disentrent. and he got a+.

  • Thanks for the Reply
    Erik
    >>and print in the main
    How will adding a printf in main help me in knowing whether ISR called Func1/Func2
    >>.. .. and scope on it.
    Did U mean to set pins high/low to give suitable indications about porgress of program. Ex: port2pin1 set to high indicates entry in Func1
    port2pin1 set to low indicates entry in Func2

    Hamed
    Can U please let me know what changes I need to do in my current code, so that I can generate accurate delays even after having a printf in function(s) called upon by ISRs

  • so that I can generate accurate delays even after having a printf in function(s) called upon by ISR

    where you not told not to do that?

  • Sorry Hamed
    while reading your comment I read it as you can use printf and hence have asked the above question. Please discard the same, But However do let me how one can debug a program in keil other can using printf
    As Erik suggested of using Port pins to indicate suitable conditions, let me know any other possible ways. However i'm not clear about how adding a printf to main will help me in knowing the program flow
    Thanks for you cooperation

  • However i'm not clear about how adding a printf to main will help me in knowing the program flow

    pseudocode
    in the ISR
    func1flag = TRUE

    in the main
    if func1flag
    printf
    func1flag = FALSE

    Erik

  • while reading your comment I read it as you can use printf and hence have asked the above question

    Contrary to what you've been told you can successfully call printf() from an ISR. You just need to consider the ramifications of doing so.

    Ignoring the other considerations think how long it takes to output 5 or 6 characters at 1200 baud and think about how frequently you're trying to do it. In the example you've shown calling printf() from outside the ISR should rectify the apparent 'irregular' timing but is unlikely to produce serial output that matches your expectations assuming your expectations are correct.

  • Excuse me Jack, but I read this thread carefully and your assertion that "Contrary to what you've been told..." is simply not the case. Erik recommended against it - that is all. Personally, the fact that it is possible does not mean that anybody should be advised to do so (I don't think you did). Certainly you agree that it is a bad habit and a inappropriate way to utilize the small C51. Better for the OP to learn to do it right from the start, then.

  • Contrary to what you've been told you can sucessfullyl printf() from an ISR

    What a load of manure. Suggesting something that 'works' in 0.00001% of cases has no other purpose thatn throwing a monkey wrench into the machine.

    Contrary to what you've been told you do not need a hammer to pound a nail, you can do it with a shoe. That the shoe, most likely, will be ruined is irrelevant.

    The sardine is very busy to 'teach' newbies routes that will get them in trouble.

    Erik

  • Excuse me Jack, but I read this thread carefully and your assertion that "Contrary to what you've been told..." is simply not the case. Erik recommended against it - that is all.

    Well, I think you need to practise your comprehension skills. Here's what was said:

    you are calling printf from (a function called by) an ISR, that is an absolute NoNo

    The other contributor made an equally definite comment to the same effect.

    Personally, the fact that it is possible does not mean that anybody should be advised to do so (I don't think you did).

    Correct.

    Certainly you agree that it is a bad habit and a inappropriate way to utilize the small C51.

    Ah, the 'irrespective of the circumstances you musn't do this because it's a small processor' argument.

    Better for the OP to learn to do it right from the start, then.

    What is someone going to learn from wrongly being told they can't do something?

  • What a load of manure.

    No, it isn't. You can successfully printf() from an ISR.

    Suggesting something that 'works' in 0.00001% of cases has no other purpose thatn throwing a monkey wrench into the machine.

    I didn't suggest doing it, I merely corrected the misinformation the OP had been given.

    Contrary to what you've been told you do not need a hammer to pound a nail, you can do it with a shoe. That the shoe, most likely, will be ruined is irrelevant.

    Nobody has ever suggested to me that a nail cannot be driven by objects other than a hammer. Wherever did you get that idea from?

    The sardine is very busy to 'teach' newbies routes that will get them in trouble.

    Not at all. I just like to correct false information from the oldbies.

  • What is someone going to learn from wrongly being told they can't do something?

    A fine argument, but still, a total newby that does not bother to read documentation (i.e. student...) is not likely to even understand what is happening underneath the surface and why "it does not work" (he is on a hurry to finish work. I know I was...). Therefore, a small tip now and then can do wonders - after all, nobody points a gun at the OP's head. But later on, when it matters, lives may be at stake, therefore I truly believe it can do no harm to pointing out glaring mistakes. Having tried to do so yourself quite often, surely you can sympathize with this argument...