I am learning about AVR microcontroller programming and currently have a simple LED blinker set up on an ATtiny26.
A 10k potentiometer is connected to ADC7 (pin 7) as per the example in part 1 of this tutorial. The output pins of port B are connected to LEDs via transistors in a multiplexed array. (The circuit works just fine without the ADC involved.)
To test/learn, I am blinking a single LED and waiting for a number of milliseconds equal to what is read from the ADC. I am having a problem when I try to multiply the value to implement longer delays.
I thought the problem was that the variable I store the ADCH in was an int
but needs to be something else because this is an 8-bit microcontroller and an int
can only be 0-255. Substituting long
in did not work, however.
Here is the code that works:
#define F_CPU 1000000UL
#define ADC_VREF_TYPE = 0x40
int SD = 1;
int main()
{
// Set port A to output (1)
DDRA = 0b11111111;
// Set port B, pin 3, to input (0)
DDRB &= ~(1 << PB3);
// Set control and status register
ADCSR = 0b11100111;
// Set ADC multiplexer selection register
ADMUX = 0b00100111;
while (1)
{
// Set SD (step delay) to value from ADC
SD = ADCH;
// Turn on LED (it is a multiplexer, so two pins are used)
PORTA = 0b00010001;
// Wait for SD milliseconds
milli_delay(SD);
// Turn off LED
PORTA = 0b00000000;
// Wait for SD milliseconds
milli_delay(SD);
}
}
The problem occurs when I try to use a multiplier like this:
SD = ADCH * 10;
When doing this, the LED will flash quickly at one end of the potentiometer sweep, but will light solid and stay that way at some point while turning the pot to slower speeds (larger ADCH values); essentially "locking up" and requiring a reset while the potentiometer is at the original position again. My guess is that I'm trying to store a value greater than the numeric type holds, but I can't seem to overcome this by changing the variable type. I've tried long
and uint32_t
but I don't really understand what the numeric types hold on this micro.
Q: What do I need to do so that I can implement delays ranging from 0 to say 2000 milliseconds?
FYI I have the following libraries included:
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <math.h>
Edit:
I had placed _delay_ms(x)
directly in my example to avoid posting the functions I am actually using which call _delay_ms(1)
inside a loop. My thought was it would be more concise, but as one answer pointed out, it actually appeared to be a mistake.