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
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.
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.
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:
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.
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?
Not at all. I just like to correct false information from the oldbies.
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...
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.
This is a bit like suggesting that every mechanical engineer should be an explosives expert in case he is every asked to design artillery.
In any case all I did was point out a glaring mistake and offer a correction. I didn't suggest that it was either a generally advisable or, in this case, useful course of action.
a total newby that does not bother to read documentation (i.e. student...)
I didn't think the OP fell into that category. His post seemed quite reasonable with a willingness to learn - not really deserving of a one line scoffing dismissal that wasn't even factually correct.
.... had I coded something and asked someone (no web) "what is wrong" and been told "You can successfully do this" I would have persisted up the road I was travelling and lost a lot of time.
When you make statements that are FALSE in 99.9% of the cases DO NOT DO SO WITHOUT stating all ramifications of doing so or you will lead many down the garden path.
How can you (in sardinespeak) state "You can successfully printf() from an ISR" without knowing if the OPs UART is interrupt driven or not?
How can you (in sardinespeak) state "You can successfully printf() from an ISR" without knowing the OPs program timnings?
How can you (in sardinespeak) state "You can successfully printf() from an ISR" without knowing the OPs printf frequency?
YES an advanced user may be able to pull some rabbits out of the hat, but to avoid misunderstandings either state the 99% truism or give ALL EACH and EVERY ramification of doing it
Thank You All (Erik, Hamed, Tamir, Jack) for your replies Sorry for putting you all in a heated argument. Erik Thanks for the clarification regarding using printf from main
a total newby that does not bother to read documentation (i.e. student...)...." can anyone of U please let me know where exactly can I get these documentations for reference Hence may be I will understand the root causes of the issue (being discussed in the current post) in a better way. Also understand the pros and cons of using printf (as discussed by Jack and Tamir) At present I'm referring the book "Embedded C by Michael J Pont" Also do suggest me some books if possible Thanks Again for all your Time and Patience
you can start by reading the 8051 bible, here:
www.semiconductors.philips.com/.../80C51_FAM_ARCH_1.pdf www.semiconductors.philips.com/.../80C51_FAM_PROG_GUIDE_1.pdf www.semiconductors.philips.com/.../80C51_FAM_HARDWARE_1.pdf
if you are interested in making your work better, try this link:
iapetus.neab.net/.../hardening.html
also, always work with static code analyzers. you can learn a lot from their findings (for example: PC-lint).
there are many other sources on and off-line. learning it is a never ending story.
Thanks All For Providing Your Valuable Inputs Thanks Tamir For The Links And Suggestions
I'm afraid that's your inability to read and understand things in context coming to the fore.
I pointed out that there were considerations. As one of the regular proponents of making people think rather than presenting them with a complete package I thought you'd approve.
That information is all readily available in the code the OP posted. However, these details are irrelevant - none of those things prevent one from being able to successfully printf() from an ISR.
I wouldn't have described calling printf() from an ISR as "pulling rabbits out of the hat", more a question of understanding the implications and consequences of doing so. Given that you view this as a magic trick only achieveble by an advanced user it would be a useful educational exercise for you to research and list the ramifications yourself.
Can somebody please quickly elaborate on the ramifications of calling printf from an ISR mentioned in this thread?
..... these details are irrelevant - none of those things prevent one from being able to successfully printf() from an ISR.
since when ?
One example of a relevant detail is that if putchar is ISR driven you can't. DO NOTE the MCU: above.
In most cases printf() from an ISR will lead to some other ISR not being serviced in a timely fashion or the ISR with the printf being constantly seviced i.e. it takes so long to execute that it is activated again before it is done.
Putting a printf in an ISR is an abhorrent violation if the KISS principle (keep ISRs short & simple)
One point to the above is that the problems can show up in an intermittent way making the debugging (of what is wrong in the first place) virtually impossible.
I'm afraid that's your inability to read and understand things in context coming to the fore. so, you are back to your old tricks, when you can not see a technical reason you go personal.
so, you are back to your old tricks, when you can not see a technical reason you go personal.
You quote what I say removing the context, then comment on your interpretation of what is left. Either this is wilfull misquoting or it it a deliberate attempt to distract attention from your technical shortcomings.
I was giving you the benefit of the doubt, but there you go.
Either this is wilfull misquoting or it it a deliberate attempt to distract attention from your technical shortcomings
it is pointing out that because of YOUR "technical shortcomings" (re the '51 and C51)you resort to personal attacks.
You see? You've done it again. You've removed the sentence before the one you've quoted which contains the information to which the quote refers, then tried to use the remainder as an opportunity to complain that being shown to be wrong is a personal attack.
You really do need to either make more of an effort to post correct information or grow a thicker skin.
We started with this:
And moved throught this:
One example of a relevant detail is that if putchar is ISR driven you can't.
Eventually establishing after a lot of wriggling that it meant this:
One example of a relevant detail is that if [serial comms are] ISR driven you can't [printf() successfully from an ISR].
And now we're still waiting for an explanation of why this is true.
and I'm still waiting for you to read "the bible" and find out
"One example of a relevant detail is that if [serial comms are] ISR driven you can't [printf() successfully from an ISR]."
I've worked with 8051s (and the like) since the 1980s and I cannot think why such a requirement could not be achieved.
OK, it may not be considered the best or the recommended way of doing things, but I think it is achievable.
So ... Please ... Erik ... If you think "the bible" has something that states it is not possible (presumably in an indirect manner), be so kind as to give us the details.
Hello Sausage man,
Look at this quote:
and then
Suggesting something that 'works' in 0.00001% of cases...
Maybe I have filleted down something, but where do you see here that Erik claims it is not possible at all?
"Maybe I have filleted down something, but where do you see here that Erik claims it is not possible at all?"
I was simply going by the contents of the last couple of posts; i.e.,
#1
#2
But if #2 doesn't follow #1, then OK.
---
I do wonder where the figure of 0.00001% originates - Some clever area of statistical analysis?
Regardless, I'm glad that it is usable in even 0.00001% of cases - Having successfully used very similar techniques for debugging purposes in the past :)
if you e-mail me I will gladly answer; however, since the sardine has consistently replied to my inquiries by stating "read the standards" I can not answer his inquiry by any other means.
Please note that in my "read "the bible"" I have, as opposed to his posts not included any snide remarks about his (lack of) competence.
I will, however answer the 'new' question not from a can: I do wonder where the figure of 0.00001% originates - Some clever area of statistical analysis? just a means of saying 'rarely'
You've skinned it and cut it into steaks. You must have slept through fishmongery 101.
The 0.00001% claim applied to polled serial comms, interrupt driven serial comms was dragged into the conversation as something that would prevent it working entirely.
We're still waiting for an explanation.
First off, I haven't mentioned the 'C' standard once in this thread nor suggested that you read it.
Second, surely it would be a shame for you to deprive the rest of the forum community the benefit of your knowledge, just because you don't want to tell me?
First off, I haven't mentioned the 'C' standard once in this thread nor suggested that you read it. correct, but do you expect me to forget all your snide remarks in other threads
I have, in the above thread, suggested they ask by e-mail. Would it not be even better if YOU found out and posted your finding since (according to you) your answers are so much better/clearer/precise/glorious/perfect/.... than mine.
As I pointed out above I have read it and it does not explain why if [serial comms are] ISR driven you can't [printf() successfully from an ISR].
You claim the answer is contained in that document, but I can't find it. I'm surprised you don't seem to want to take this opportunity demonstrate conclusively that I'm wrong by quoting the part of that document that shows that if [serial comms are] ISR driven you can't [printf() successfully from an ISR]. Obviously you would need to explain how the quote applies to printf() as that document does not make any reference to the 'C' library functions.
You claim the answer is contained in that document, I do not, I 'claim' that understanding the document will make you able to find the answer.
The '51 is not a good processor for "C is C, I do not care about the hardware".
I do not, I 'claim' that understanding the document will make you able to find the answer.
My understanding of that document along with my understanding of Keil's implementation of printf() tells me that it is possible to successfully call printf() from an ISR even when using interrupt driven serial comms.
You're going to have to actually explain precisely what it is in that document that makes it impossible to successfully call printf() from and ISR.
View all questions in Keil forum