hello friends I'm doing a 8x8 LED matrix with LPC1768 and when I compile I get an error that I can not solve also leave some warnings but I did not care much. could help me? I leave the whole project in keil
many thanks Ciernes
put unsigned char, because I read that e is 1 byte for characters 0-255 const use it to save data to flash and not take up ram unnecessarily. remove it to see if something managed. the multiply defined not understand
Just what do you think uint8_t means?
And what number of bits do you think "char" has on a machine that might possibly have 36-bit integers?
"const" to place things in flash? Do you think the computers did use flash, when the C language originally got a "const" keyword? Have you spent any time reading any chapter about "const" in a good book about the C programming language?
You want to remove "const", while lots of this worlds programmers would want more use of this keyword - maybe for a good reason.
But let's assume that "const" really would mean to store in flash - wouldn't that be good for you? Are you really in need of having character bitmap descriptions stored in flash, and then copied into RAM on program startup just so your program will be able to modify the bitmaps? Do you expect that your program has a need to modify these character bitmaps while running?
An interesting thing when writing software is to try to see it as involving contracts.
The requirements specification is a contract that you as developer has to fulfill.
The language standard is a contract that relates to what contract the compiler will fulfill.
The data type "char" is known to have size 1, i.e. sizeof(char) will always be 1. But we don't know exactly how many bits we might store in a char, even if just about any new processor just happens to settle for a design where char happens to end up exactly 8 bits large, i.e. with the numeric range 0..255 or -128..127. But the language standard doesn't give any such promise. A char itself isn't even known to be signed or unsigned - and if signed we don't know if it is two-complement or if it has a separate sign bit and potentially a +0 and a -0 as two separate binary representations.
So the language later added an additional set of data types to make it easier to write source code.
uint8_t <= exactly 8 bit unsigned uint_least8_t <= 8-bit or larger - the smallest possible native data type that fits 8 bits. uint_fast8_t <= 8-bit or larger - the fastest possible native data type taht fits 8 bits.
Suddenly, the developers got a much easier life writing code that can be moved between different processors on different hardware.
So while it's still ok to use char, int etc as data types, these generic types should be limited to situations where it really doesn't matter what size you happen to get - where it's enough with the limited promises you get from the language standard itself.
But in your case, it isn't enough with the promises from the language standard - you really do need to know that you do fit 8 bits of unsigned data. So why then downgrade the code from "uint8_t" to "unsigned char"?
Same thing with "const" - it's also there as part of a contract. It isn't there for storage in flash. It's there to tell "I promise that I will not change the value of this variable". In the case of storage in flash, you can see that storage in a read-only memory region would require the program to keep such a promise. But there are many other reasons for such a contract - a function that takes a parameter by reference (i.e. by address) could use that address to change the value of the parameter and that change will affect the rest of the program even after the function returns. So adding 'const', the function promises that it will not abuse its power and change the parameter even if it could. And not only that - the compiler will see the contract formed by "const" and will generate an error if the function tries to cheat and actually modify the variable.
So - you get an error relating to "const". That was the compiler noting that you had a variable "ascii" with a contract promising that it will never be modified. And you tried to send a subset (a single character) of this variable into a function. But this function did not give any promise that it too would uphold the original value of the ascii[] variable. So the compiler complained about a breach of contract. A quick look at the code shows that the function in question isn't trying to modify the variable - so why not then modify the function so it too promises to not change the input parameter? It should by now be quite obvious what route to take to add such a contractual promise to this function.
When you get compilation errors - or warnings - you shouldn't solving them by "let's try random rewrites until the error goes away".
You must instead try to figure out exactly why the compiler is unhappy. When you understand why the compiler is unhappy, you should then spend time trying to figure out what is the best way to fulfill all relevant contracts: - the contract of the language standard - the contract of the called function that promises that "if you give me input parameters within this range, I will give you meaningful results". - ...
Changing uint8_t -> unsigned char did not help you fulfill any contracts. It was just a route to try to cancel a contract. And for your specific processor you didn't even gain anything since uint8_t just happend to compile into exactly "unsigned char". So it was a meaningless change with zero gain.
Removing "const" on ascii[] was also a bad edit - you throw away the contract where you promised to never change the contents of ascii[]. But you did not gain any single advantage from this. You just removed some protection from your code. Just like driving a car without having an insurance.
Good programmers don't remove contracts from their code or their documentation. They try to add - and document - contracts. Promises to tell future developers within what envelope the code is safe to use without unexpected failures.
The best part of adding contracts? Much less time needed to try to debug the code. So the extra work of the contracts isn't extra work. It is instead saving lots of work. While increasing the trust that can be put into the code.
Another good thing? If this is a school assignment, code that shows clear use of contracts will get a better review. A better score. At least if the teacher isn't incompetent.
I read everything you told me to. I understand now what happens I have to protect the function that calls ascii. is necessary for the compiler because it thinks the function will modify the ascii variable. you are having a lot of patience with me but if I tell the truth, but I think, not as protecting function. I understand that I still have much to learn. is that the "easy via" (which men the solution) is not the most appropriate way to learn, but I'm blocked by this
This function:
void Matrix_NewFrame(uint8_t array[8]) { matrix[0] = array[0]; matrix[1] = array[1]; matrix[2] = array[2]; matrix[3] = array[3]; matrix[4] = array[4]; matrix[5] = array[5]; matrix[6] = array[6]; matrix[7] = array[7]; }
is receiving a pointer to 8 uint8_t elements.
As can be clearly seen from the implementation of the function, it never tries to modify the content of array[], and so if called as
Matrix_NewFrame(ascii['A']);
it is not trying to modify the bitmap for the character 'A' in the ascii[] array.
So the obvious thing to consider then, is to inform the compiler that the function is safe, by modifying the source code so the compiler sees this by adding the "const" keyword.
Then the compiler will know that there is a binding contract allowing you to call it with "ascii[xxx]" even if ascii[] happens to be const. And so the compiler will not complain about unsafe use of a const variable.
It really is important that you learn about the difference between "call-by-value" and "call-by-reference" and that you also understand the significance of using "const". And also that "const" can be used in two ways when relating to pointers, i.e. the difference between a const pointer and a pointer to const data.
ok I'll try to read carefully what you tell me. I'm researching where to put the const word. thank you very much
ok I put the const in the function:
void Matrix_NewFrame(const uint8_t array[8]);
but now it seems that there is still something wrong
Build target 'Target 1' compiling main.c... compiling matrix.c... linking... .\matriztest.axf: Error: L6200E: Symbol ascii multiply defined (by matrix.o and main.o). .\matriztest.axf: Error: L6200E: Symbol ascii multiply defined (by matrix_font.o and main.o). .\matriztest.axf: Error: L6200E: Symbol character_length multiply defined (by matrix.o and main.o). .\matriztest.axf: Error: L6200E: Symbol character_length multiply defined (by matrix_font.o and main.o). ".\matriztest.axf" - 4 Errors, 0 Warning(s). Target not created
matrix.h
extern const uint8_t ascii[128][8]; extern const uint8_t character_length[128];
Then actually define it ONCE
This is a time when a sequential reading of a good programming book really would have helped.
Ever consider the keyword "extern"? Ever looked into a book about C regarding use of multiple source files and the use of header files to inform the compiler of what functions and variables the different source files might contain?
There is a reason why people often start with something simple, like a "hello world!" application and then add new complexities step-by-step instead of trying a big-bang approach. The step-by-step approach teaches all the relevant keywords. How to spell them. What they are good for. When to use them. And it describes the block structure, the control and loop blocks. And covers from simple to more and more complex data type constructs.
Doing many small steps, with regular positive feedback in form of a working program, is way more satisfying than getting stuck with a too large piece of code and not understanding what is happening and why.
Note that Google is very good to use when you get an error message - it will very often lead to either other people having had a similar issue (and help they have received with it) or even full lessons teaching that relevant part of coding.
The code now does not throw any error, we wanted to thank the patience you have had. I certainly started with a "hello world" and it seemed easy, so I wanted to take a chance with something bigger it is clear that the code is too big and complicated for me, but believe me I'm going to spend long hours studying to do similar things without help. I know that no questions are addressed to "stupid" problems in this kind of forums but this forum together with two or three more are the ones who have a professional level. There are supposedly forums where people try to give you an expert solution but unfortunately these people have not shown a higher level mio. The next time I come into this forum, I will try to do more constructive questions. thank you very much Per Westermark
carefully: Jonathan