i have problem with the led blinking. I using the exmaple program given by keil using uVision3. When i run the program, the LED on the development board didnt blink, it just stay on! wat should i do?
thanks!
O ok because i have search some of the thread that says that using loop will do the job. But after that I try to search again and found out that having loop wont do as well as timer.
I am now using AT89S8252, product code is EQ-8051-ST1 which come with the development board and a programmer board. at the development board there are 8 LED, can these LED be control by the coding that I have done. Or is there other way other than blinking, can test out whether the board is working fine. I would prefer with C code.
Thanks You
1) Do not use the name wait() for your function. All it tells is some magic waiting (is expected to) happen, but not what wait. Waiting for a key press? Waiting for the supply voltage to stabilize? Waiting a specific time?
Since you are talking about a time delay, change the name so that it clearly says exactly how long the delay is. Optionally modify it to take a parameter to specify how many such time "clicks" the function will wait.
For example:
delay_10ms(25); // Delay 250 ms delay_1s(20); // Delay 20 seconds delay_us(2700); // Delay 2700 us
2: You normally don't encapsulate all use of a timer into the delay function. You often initializes the timer once from main() and then you either use the timer in free-running mode, or clears the counter value ... (depending on how you choose to impelement the delay and the capabilities of the timers in your specific processor) in the delay function.
You want a delay function to have as little setup time as possible so that it may also contain a loop to handle n delay steps. With a lot of initial setup, the length of the first and the following ticks may be different.
Just seen some code written by one of my co-workers.
He had a line:
if (AvaSpace()) // maintain link
I asked him what it was doing, maybe 'maintaining a link'?
He ummed and arred for a while and then conceded that he didn't remember.
So we looked at the function itself (the one that he had written only two days ago!).
It determines whether there is enough space in an internal buffer to store a data record.
I then realised what the name was suggesting ...
Have A Space ?
I have now suggested to the management that he needs some urgent training!
Now they even write software using SMS language?!
I think his intended name (before shorening it was) AvailableSpace?
But a name AvailableSpace() sounds like a function that tells exactly how much space. A function EnoughSpace() - or better EnoughSpaceForRecord() - focuses more on the actual problem at hand: Is it possible to insert (at least) one more record?
With old development tools, the linker had severe limitations on the number of significant characters in an external symbol. This isn't a problem with modern tools. It takes extra time to write a longer symbol name, but the support cost (or at lesat total life-time cost) may be ten times the original implementation cost. So spending a little bit of extra time with very good symbol names do help.
I looked at some code yesterday. A function with a bool parameter named "bit". It really did not help me understand what the parameter did. The next function did take a parameter "protocol". It took me some time to figure out that this parameter selected tcp or udp for a transfer. Helpful symbol names are really vital - both for the sw quality and for the time it takes to maintain or extend/modify an existing software.
"I think his intended name (before shorening it was) AvailableSpace?"
Unfortunately you are not correct, he said "have a space" was probably what he meant - But he couldn't actually remember!!??
Yes, I certainly agree with your comments - A little initial though can save a lot of time later on.
A fully descriptive function name sometimes becomes unamangble e.g SeeIfThereIsRnoughSpaceReturnFalseIfnotTrueIfThereIs();
so while I am all in favor of descriptive funtion names the REAL place for describing a function is in the function header like
////////////////////////////////////////// // // FUNCTION U1 CheckSpace(U8 CSP_Csize) // // verify that there is enough space for CSP_Csize in RS232 output buffer // returm TRUE if there is, FALSE if not //
then if you have ANY question about a function look at the header
likewise sometimes a construct with many variables makes it 'impossible' to describe the variables and thus a definition of a variable should always be commented.
Erik
The function header comment can document the behaviour and reason. But the name must be meaningful since you can't spend 100% of your time cross-reference the function comment. Some editors picks up Doxygen or Javadoc comments and can show them when you hold the mouse above a symbol name. But most editors can not...
You have to make a distinction between descriptive name and a sentence.
SeeIfThereIsRnoughSpaceReturnFalseIfnotTrueIfThereIs();
See If There Is... don't help with any meaning.
Return False If not True If... don't convey any extra meaning since the true/false concept is built into the language. It is just a question of making the symbol name use positive or negative logic, i.e. "IsAxx", "HaveXX" or "IsNotXX", "MissingXX", ...
The code should focus on "what", and the comments should help out with "why".
A delay_ms(10) answers the what. But a comment may be able to point that an external hardware needs at least 6ms settle time which indicates what may happen if the function parameter is decreased. Without a comment, it will not be meaningful to take a scope and verify the delay. A measured delay of 10.5ms (because of interrupts or other things outside of the code control) may represent a failure if I don't know if 10ms has hard tolerance requirements in both directions.
Per.
I dreamt up a long 'descriptive' name, It was just an example of the type of names I have seen when someone codes "in the other ditch".
The function header comment can document the behaviour and reason. But the name must be meaningful enough for someone working with the project since you can't spend 100% of your time cross-reference the function comment unless you are just dropped into something you have no idea of
in other words: the function name shall be meaningful enough to convey what it does, but for deatails - in the few cases you need them - you have to go to the funtion header.
No, my answer was not critique about your suggested name, but a continuation trying to explain why people should not think that a long name equals a good name. Everything is about context. And why people should not think that foo() is an acceptable name as long as there is a one-page comment describing the foo() logic directly above the implementation.
Writing too much is a very common error - most people who send in their first school assignment are scared to death about software comments. So they document every single code line, completely duplicating the software function in two different languages - but often with the comments describing a previous version of the application :).
How many have seen the following assembly code?
MOV A,0 ; Set register A to zero
Might be ok in a book teaching assembler, where the example is intended to let the reader learn the mov instruction. But as a comment in a real program, it does not supply any extra information. The reader still don't know why it is important that A is zero. If A is used as index into a text string, it might help to tell the reader that "start from first char in string".
I shall take a section of the Rules for Code Monkeys book I wrote many years ago about "comments" to help others figure out what a comment is.
(Rules for Code Monkeys is an internal document like the coding guidelines you have there at work: that open copy right next to your keyboard).
************
Generally "Comments" can be categorized as Tactical, Strategic, or Theater-Level. (The Theater Level can be termed Theatrical, but in the "Theater of War" sense and not the Showboat sense).
Theatrical comments are typically found in the file's header, and shall describe the purpose of the module, and how it may fit in the theater of operations for the Computer Software Configuration Item (CSCI). The CSCI is known as the final 'executable' file.
Theatrical comments provide the reader a higher level of understanding of the software and typically reflect the Software Requirements Specification (SRS) from the coding standpoint. Theatrical comments can be found anywhere, and do not [currently] have a flower-box identifier to indicate such comments. The most obvious location is within the module header information.
Theatrical comments provide the reader with a wider conceptual view of the code module. Theatrical comments can be information about the system's environment like the OS, CPU, Memory, IDE, Versions, etc. While Strategic and Tactical are the dominant forms, Theatrical comments should be still be contained in all source code modules. Source code also includes batch files, linker support files, and anything else that is required to cleanly build the CSCI besides the cross-compiler itself. If the IDE requires startup files, then those too should also be considered source-code and commented accordingly.
Strategic comments describe what a section of code is supposed to accomplish. Strategic comments should be placed before the code section that implements the task. This includes the function header block. At the function block, these Strategic comments identify the scope of the function, the expected method of accomplishing the task, the passed parameters, the return value, and any special notes the software engineer should know about the function. These notes may include such items as measured execution times, atomicity, or any other code-centric information that the software engineer should be aware of when modifying the function.
The more common Strategic comment has an enclosed flower-box describing the intent behind the following code. The code itself should be clear enough through liberal and consistent white-space usage, and data-store (aka 'variable') name selection.
Strategic comments should precede most control flow operations, and alterations of CSCI states. (e.g. if(), else, while(), or the enabling of interrupts, or data-store assignments that implement what the code is supposed to do).
Strategic comments should be the primary and dominant form of commenting source code.
Tactical comments describes the specifics on how the code is implementing a task. Typically these tactical comments are on an end-of -line basis. (For 'C' it would use the double-slash // delimiters).
Tactical comments serve to enlighten the non-obvious behavior or method implemented, and not simply a re-statement of what the code performs:
i = 0; // assign zero to i <---- poor comment i = 0; // start indexing from zero <---- a better comment
The over-use of tactical comments will result in source code that takes too long to read, and begins to devalue and hide the worth while comments. So the above example typically wouldn't be commented.
Tactical comments should be as detailed as needed to inform the programmer. The common used for Tactical comments is when describing the side effects of code implementation or when the code performs something that is not obvious to the standard or novice programmer. Always write on a level that is explanatory the reader, and never assume the reader is as competent as you think you are.
Enjoy,
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
I have a template of stuff, one of which is the function name template.
This has the elements that I think are important to source code. IMHO.
/* **====================================================================== ** Function_Name [catagory] [spec tracking numbers] **====================================================================== ** ** Function comments ** **---------------------------------------------------------------------- ** ** Parameters Passed: <void> ** Parameters Returned: <void> ** Notes: ** **---------------------------------------------------------------------- */ void Function_Name( void ) { . . . }
An example of implementing this template into the real world... well I made this up, but it is a typical construct...
/* **====================================================================== ** Keil_Example [ CALC ] CSC8 CSU8.2.1 R4 **====================================================================== ** ** This function shall scan the array for the specified value, perform ** the simple pattern masking for validation. Based upon that 'match' ** compute and return it's corrilation factor. ** ** Add more description text here to make it thorough enough, but not ** too thorough that the code-monkey ignores the design documents. ** ** It helps to make reference to the design doc ** ( e.g. "reference table XYZ for details on return format" ) ** **---------------------------------------------------------------------- ** ** Parameters Passed: ** ** u8 val - value to search for within array ** u32 *arry - array to parse ** u32 pmask - pattern mask for validation ** ** Parameters Returned: ** ** s16 - corrilation factor: internal fractional binary format ** ** Notes: ** ** CAUTION: Contains a polling loop with no safeguards to protect ** from an infinite loop if the hardware fails! ** (needs a time based break mechanism) ** ** As of 04-Dec-08, this routine takes way too long. ** Need to optimize the algorithm. Suspect the array indexing ** is taking too long. FIX IT! -- Cpt. VF ** **---------------------------------------------------------------------- */ s16 Keil_Example( u8 val, u32 *arry, u32 pmask ) { . . . }
Things like date created or author of the function, to me, are irrelevant, since the module header contains this information on when the module was edited and why... and who was responsible for the changes.
The repeated function name in my header is important, along with the tags 'category' and the document referencing labels. Although your IDE/editor might not explicitly state that it uses the DOS 'grep' function, it has the same result.
grep CALC *.c > calculations.lst grep DIAG *.c > diagnostics.lst grep UTIL *.c > utilities.lst grep CSC *.c > requirements.lst grep MUTATOR *.c > mutators.lst grep ACCESSOR *.c > accessors.lst
Your document references allow you to quickly identify where in your source code *you think* you are fulfilling the requirement(s).
As far as naming conventions go, all will fail. Most fail equally well. Do what you think is right. You'll get better at it in time.
Hungarian is a total waste, so don't go down that path.
Naming conventions become important for accessors and mutators (crossing module boundaries), while the internals are far less important.
That delay_ms( 10 ) function looks to me like an internal (module specific) function. A more formal type function name to me would look like TimeBase_Delay( 10 ) where you might infer that the time base module contains this function, and you must look into it in order to know that the passed parameter is in milliseconds.
Don't get me wrong, I'm not advocating that cross-module accessors & mutators have start with the module name. That is up to you. I usually don't do that. But I do use Upper_Case function names as potential cross module functions while all lower_case function names are internal service types. That's just me and not something I advocate others implement in a coding standard.
It is not "TimeBase_Delay_ms( 10 )" for a reason: I would use this format:
TimeBase_Delay( DEBOUNCE_DELAY );
and in the definition of the constant, I would have determined the function needs (milliseconds), while the code that called the function knows that it must call a delay function, but not need to know the delay is in milliseconds, microseconds, or some fractional hour format.
The delay_ms( 10 ) is kind of missing the point: you are delaying 10 milliseconds for a reason: make that reason clear to the poor slob who must maintain your scrawlings:
delay( SCREEN_REFRESH_TIME );
Anyway, I've rambled on too much again.
It would be quite interesting the see the full code monkey rule set.
Swatting magic numbers and instead use constants is the next step up, when people have considered their use of symbol names and how to comment their code.
Doing the swatting first would probably result in:
enum { N = 17, // N=18 seems a bit excessive. M = 12, // Use 12. ... }; wait(N); // need to wait
or possibly introducing broken defines:
#define M 12 #define N M+5 wait(N*1000); // us
#define N M+5 Always( always( always ) ) use parenthesis.
#define N (( ((M)) + ((5)) )) // (over) (use) (them) (!)
Its in the book; on page( PARENTHESIS ) to be exact.
Its basically standard stuff; a racy jacket, a steamy intro, the main characters are shallow, has a thin plot line, lots of typos, and has a dry, monotone-ish narration.
In the end you are either a satisfied or you're left needing more.
<excerpts from "Rules for Code Monkeys"...>
Thou shalt not use Hungarian Notation. Thou shalt not use 'internet' code; unless an assignment is due, and the teacher can't tell the difference anyway. Thou shalt not kill (depending upon the project specifications) Thou shalt not use the closing bracket ']' symbol without first declaring allegiance to King Kong or saying several "Hail Fay Wray"s. Thou shalt not ramble-on-and-on in forums. etc.
You know, the standard stuff.
Yes, I know that you hate macros.
I felt that I had to write that example just because the people in most need of good advice about symbol names and sw comments are quite likely to do produce such #define'd constructs.
A #define'd expression without parentheses is definitely one of the mortal sins of programming - it doesn't matter if it is production code or just some test code.
Another is to hide the #define'd symbol by not using capital letters.
Or having a conditional #define that mucks up a dangling else. Or writing code that has a dangling else.
A define that makes use of a parameter more than once is also quite high up on the no-no list. And code that does call a #define while using ++, -- or similar modifying accesses on one or more of the parameters.
I haven't really decided what is the best way to get good developers. - Huge quantities of information. - Give people a bit of help into all kinds of traps and then have them learn why they got into the trap and how to avoid at least that speficic pot-hole in the future.
In the end, hands-on experience with problems is quite efficient. People tend to remember a broken nose far longer than they remember the text in a school book. And they don't doubt the real pain that results from doing something the wrong way. The trick is to not produce permanent damage so they switch to another profession, and not to produce permanent monetary loss.
Yes, I have seen
#define TEN 10