17 Replies

Hey um, I know you can do rand() to get a random 0 - max, but isnt there a easy way? like for my calc / lua its random(1,4); to get a random digit 1-4. Each time i've tryed rand() with RAND_MAX i never had it working :l gmoon? xD

Thanks for all the help gmoon, But heres a little challange that will get me a step closer.
I was told it's possible to have 2 pins on portB, run at different speeds, without effecting the other. But when you want PB1 to blink at the rate of 1/sec, and PB2 to blink at the rate of 5/sec.... it wont. instead they blink the same rate at like 6 blinks/sec. I was told theres something called "Mask" which allows ports to run at their own rate. How?

I see what you're saying. For one thing, these blink functions are "blocking"--for the duration of the delay, they are "lost" inside the functions.

RE: masks--first of all, the blink() functions so far have been bit operations--individual bit operations do an "end run" around a the concept of a mask. If we had written:

PORTB = _BV(bit);

instead of

PORTB &= ~_BV(bit);

..then we'd have overwritten all the other bits in PORTB--we didn't do that, so we've been "self-masking," so to speak. Masks are usually applied either to eliminate certain bits or to include certain bits. Bit-wise logic doesn't need masks, but if you were converting computational results to bit fields, you would use a mask. You really should study this tutorial on bit-wise operations...

To get back to it, there's more than one way to do it--the more complex way is to use IRQs (interrupts.) But better to start simply.... Remove the delay from the functions, and implement blinkon() and blinkoff() functions, placing the delay outside of the function:

This is just one simple way of doing it. You can remove the internal function delays completely--do other processing and then a short delay between each blink, if you need other processing during the interim, also.

You can re-write blinkon() and blinkoff() to accept bit fields (masks) instead of individual bits.

...which uses the OR operator to combine the two bits into a bit field, which is kinda like a mask.... You'd write a complementary blinkoff() function to also accept bit fields (the _BV() macro is one bit only.)

These functions aren't perfect--if you blink() a bit that was "turned on" by blinkon() previously, it will be be "turned off" inside blink().... To do that, you'd need a "state" variable for the port.

It should be mentioned, as it was in the previous thread, that these functions and bit operators are using negative logic--ON is low, and OFF is high.

What about the info in this previous thread? If you have any specific questions about converting that code into the above example, please ask. Everything you're trying to achieve was already covered there....

Commenting on the snippet above:

--there is no "function" keyword in C--you need to specify the type for each argument in a function (and a return value), like this function definition:

_BV() converts those constants into the actual number, with a simple shift operation. When avrgcc compiles, it will optimize the shift away and substitute the correct bit value.

Unless you're doing something computationally with the bits you should use the predefined constants (like PB2, PB5, etc.) They've been provided to make it easy to move the code from one AVR to another...

When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.

In other words, if you use the library function the delay might suddenly be different, depending how high a value you plug in, and what the CPU speed is...If you only need small millisecond delays (in the mid-to-low hundreds), you can eliminate the wrapper and just use _delay_ms()...

It was originally "calibrated" to compensate for the inaccuracy of the internal clock, but I reuse it and don't bother to recalibrate--a crystal is better if you need precise timing.

Not that it's a big deal....but AVRDUDE is the programmer software only (transfers the code to the AVR) and not the C compiler.

The compiler is avrgcc (technically it's a cross-compiler, since it's running on a different platform--i.e., not the AVR itself.) While "gcc" is the standard GNU c complier, it's GPL and part of every Linux system; in fact linux itself is compiled with gcc. The standard set of C libraries and functions for the AVR is avr libc, which is called "libc" in *nux (anyone see a pattern here?)

One aspect of this is that you COULD be including the wrong "stdlib.h"; if your paths and such aren't set right, you could have gotten the unix/windows/cygwin version of instead of the avr version. (RAND_MAX on my linux system is 32bits instead of the 16bit value in the AVR version.)

I don't know if this applies or not, but here's a batchfile I made to make avrdude easier (it's my first ever batch file that I made by myself so don't critisise... well, maybe constructive critisim, and don't make fun of my spelling!)

here's a link, if nobody downloads it within 10 days then it gets deleated. the link is near the bottom where the tiny red arrow is pointing

To use it:First right click and hit edit (opn it up with notepad)find and replace stk200 to your programmer (mines stk200, that's why it's like that)put the bat file in the same directory as your C file.go to the directoy using CMDType in upload programnameit's upload because that's the name of the batchfileprogram name is the name of the C file (don't type in .hex afterwards)

oh, and I forgot, it's meant to make it so you don't have to type that long thing in everytime with the code for the avr
press ctrl+C to exit the program, it's meant for a robot to program a bunch of avrs with the press of a button oever and over and over again (automatic programming)