# Tag Info

34

On a microcontroller, main() is not really expected to ever exit, and the behavior if it does is not defined — so it's up to whoever wrote the C runtime for the microcontroller. I've seen systems that: Have an implicit loop around main(), so that if it exits, it simply gets called again. Have a simple "jump-to-self" loop that gets executed if main() ...

21

As others have mentioned, you should consider a IIR (infinite impulse response) filter rather than the FIR (finite impulse response) filter you are using now. There is more to it, but at first glance FIR filters are implemented as explicit convolutions and IIR filters with equations. The particular IIR filter I use a lot in microcontrollers is a single ...

19

Yes, it's almost certainly a good move to learn to use C as well as possible (C++ will give you a helpful starting point, although as leftaroundabout notes, there will still be plenty to pick up, especially the differences between coding for small embedded systems compared to writing for something like Windows) given it's ubiquity. Most microcontrollers ...

17

a is a pointer to an array of bytes. If you cast it to a uint16_t and assign it to b, then b will contain the address of the base of the array (where it is stored) in SRAM. If you want to treat the two bytes of the array a as an integer, then use a union as suggested by user14284, but be aware that the union will represent the byte array in the memory byte ...

16

These statements are equivalent: x = x & 0x01; x &= 0x01; It means to perform a bitwise operation with the values on the left and right-hand side, and then assign the result to the variable on the left, so a bit of a short form. If you're not familiar with bitwise operations, I suggest you start getting familiar with those first - the & being ...

16

Learn C, and get a cheap microcontroller development board, like an MSP430 or ARM Cortex, and at least write and load a few C programs. I have a computer science degree and a software development background, mostly C++ programming for games and now iOS games and apps, but my last job was a semi-pro EE gig that started with doing a bunch of firmware ...

16

Of course to properly look at this we must know what it means to "Natively" execute anything. On the surface this seems like an easy question, but it isn't. Let me elaborate. But first, let me say that I am massively simplifying this description! There is no way I can explain this in a reasonable number of words without some over-arching generalizations ...

15

To expand a bit on #if 0: It's essentially a hack to allow for multi-line comments. The preprocessor, which runs before the compiler does, will remove everything between #if 0 and the matching #endif. One reason it's used instead of /* */ style comments is that you can enable the entire block simply by changing it to "#if 1".

13

Microcontrollers like the PIC are very unforgiving to the learner. If you're setting out trying to learn C for the first time, practice on a PC first. Test your code as much as you can on your PC where you have a good debugger and protection from memory faults. Once you're confident that your logic is working right, then compile your code for the PIC.

13

While Wouters answer is absolutely correct this maybe more beginner friendly and a better example regarding your question. int (*fp)(int) = NULL; int FunctionA(int x){ return x + x; } int FunctionB(int x){ return x * x; } void Example(void) { int x = 0; fp = FunctionA; x = fp(3); /* after this, x == 6 */ fp = FunctionB; x ...

12

If you can live with the restriction of a power of two number of items to average (ie 2,4,8,16,32 etc) then the divide can easily and efficiently be done on a low performance micro with no dedicated divide because it can be done as a bit shift. Each shift right is one power of two eg: avg = sum >> 2; //divide by 2^2 (4) or avg = sum >> 3; ...

11

On the bottom of page 350 of the microcontroller datasheet, it mentions that writing a small value to the timer value register during the overflow interrupt might cause the next interrupt to be triggered only on the next pwm iteration, since the timer continues to count while the interrupt routine is being executed. An unsynchronized write to the TIM ...

11

I'll give a general answer since the question lacks information: Suppose you have an uint8_t as input and a uint8_t as output and you want to create a full lookup table (i.e. every input has an output). You'd need 256 values, as the input can have 256 different values. You can now create a table with: const uint8_t the_table[256] = { ... } The const ...

10

Because you say: "All I need is cheap", you should take a look at the MSP LaunchPad. You will get it for about 5$. Another very popular platform is the Arduino. On Sparkfun for about 30$. Remark: These boards all use microcontrollers (not microprocessors). TI Launchpad. Complete development system for \$US4.30 (cable included) (Some programming ...

10

There are no pullups on P2.6 and P2.7. The MSP has internal pullup / pulldowns but you have to set them up yourself. So as part of your initialization, add this P2REN |= (1<<6) | (1<<7); // turn on pullups P2OUT |= (1<<6) | (1<<7); // set them to pull up Then the inputs won't float randomly when the switches aren't pressed.

9

Microchip's C30 compiler comes with extensive libraries for all the peripherals, and lots of other stuff can be downloaded. I bought the full version but the free version is adequate for most users. All the Microchip code examples use it. Most people use C30 for the PIC24 and dsPIC. The other compilers don't have a very good reputation, judging from ...

9

Is it ever gonna be possible to use C++ for coding PICs? Yes, it is possible now. For dsPIC, there is the IAR Systems C++ Compiler (although it's very old and not supported). Another option is to use a C++ to C converter. Using a pre-build step, convert the C++ to C, then give the (nasty looking) C to your normal C compiler. Take a look at LLVM or ...

9

Bit banging is creating the whole series of pulses in software, instead of relying on a piece of hardware inside the microcontroller. Many microcontrollers have a hardware SPI, and then all you have to do is write a byte to the output register, and the SPI controller will shift the data out, and at the same time receive data from the slave. You can get an ...

9

I am not a PIC person, but normally for serial standard you need three lines: Send (TX) Receive (RX) Ground (GND) Since you dont need RX, you could use the circuit ground and use pin 3 for TX, if your Arduino and your PIC agree on the baud rate, and other parameters related to serial comms (stop bits, parity bits, etc). This in theory could be standard ...

8

You cannot do what you want with just connecting a relay to the USB port. The USB is a bus, with a serial protocol running on it. It is necessary for you to interface with that bus using the proper protocols. You will require a use "device" which is capable of being programmed to respond to a computer-based stimulus, and activate an external signal. ...

8

Suppose I am using a 8051. Then you are supposed to know about CODE, DATA, IDATA, XDATA and PDATA memory - 8051 is a multi Harvard architecture. Where that Static Variable will be stored? That is a good question. It will depend on the compiler settings - usually called "memory model"; But you can also explicitly say where the compiler will put ...

8

The correct question is not "C or C++" (with a one-bit binary answer) but "which C++ features to add to my C (and which C features to discard as a consequence)" (which has a whole lot of bits, which will probably vary with the particular project and chip). There are some C++ features that you should defintely use because they correct 'mistakes' in C, and ...

8

The C18 compiler supports the number-to-ascii family of standard C functions in stdlib.h: itoa(), ltoa(), ultoa() et cetera. Depending on which compiler / stdlib.h you have, the relevant function prototype would be: extern char * itoa(char * buf, int val, int base); // signed int extern char * utoa(char * buf, unsigned val, int base); // unsigned int ...

7

There are many benefits to inline functions over preprocessor macros: Type checking. The compiler will complain if the arguments are of incorrect type. No risk of multiple evaluation: macros can be dangerous when the argument is an expression, consider: #include <stdio.h> #define square(n) ((n)*(n)) int main(void) { int x, i = 0; while (i ...

7

You need a compiler (and an assembler and a linker), also known as a toolchain. The compiler converts your C program source code into executable object code for your target machine. This object code can be represented as a series of hex digits in a .hex file. http://en.wikipedia.org/wiki/Compiler SDCC is a free compiler which supports the AT89C51.

7

#pragma pack(1) ensures that C struct items are packed in order and on byte boundaries. It may save RAM - which is often precious in a microcontroller. Packed structs also allow for casting directly over memory buffers for data interchange: void f(void *buf) { struct ip_header *hdr = (struct ip_header *)buf; hdr->dst = 0x8000001; } Be careful ...

7

Firstly, lets check that you have connected your LDR up correctly, it should be something like this... To read the value of PIN RA0/AN0, you need to do some initialisation to make sure the port is setup correctly. The datasheet explains how all this works, but these values should work: TRISAbits.TRISA0 = 1; // Set RA0/AN0 to input ADCON0 ...

7

Your delay will be the length of the newdelay() function plus the time it takes to send the serial data. You have: Send the count through serial wait 1000ms toggle LED. Each of those steps takes time. To get an exact 1000ms time you can either trigger the serial sending from a 1 second interrupt, or you can examine the millisecond count within your ...

7

If by "native" you mean injecting the source code as a stream of ASCII characters to be logically decoded by the low-level logic, then forget it. Such a processor would have several orders of magnitude the complexity of current processors: you don't only have to detect the 64-bit pattern representing the variable "filename", but it can appear anywhere in the ...

7

You need to re-read the ADC status register inside the loop; otherwise, you're just re-testing the bit you read the first time. Also, you need to reverse the sense of the test — you want to repeat the test if the bit is "1" and drop out of the loop once it switches to "0". It may also be necessary to toggle chip select to the ADC on each read, as shown ...

Only top voted, non community-wiki answers of a minimum length are eligible