|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
|
Exercising muscles that have atrophied ever since my managerial promotion, I reminisce of blissful days with a soldering iron.
There is something truly therapeutic about soldering a board together and making a part do what you want. Till you get stumped,
that is, then you can lose some hair. It could be some type of downward spiral. Get into management, get sick of it, go back to
engineering, lose some more hair. Now you are even more like the pointy haired manager in Dilbert, so back into
management you go. The process repeats until you've lost all your thinking hairs, and the only ones left are VERY pointed. Well,
bear with me while I dull the points on my dome a little and try to actually make something work (without telling someone else
to do itJ).
Structure
The first place to start is structure. Most microcontroller projects involve two things: wanting to do something, and then
doing it every so often. I start with every so often first. Once you get that going, it is not nearly as tough to do something.
In this case, I set up a timer interrupt using T0 in the Tiny 15. Here is a piece of code that does just that.
Basically what happens here is keeping track of four timing flagsone
every 2 ms, 10 ms, 100 ms, and every 1 second. (I will get into why they are labeled mask later.) The reason I only set
the flags in the interrupt is to minimize the actual time spent in the interrupt. There may be a lot of things that may or may
not need to be done every tenth of a second. If you put them all in the interrupt, and it overruns into the next interrupt, you'll
lose time that you'll never gain back. But if you set a flag and then check for the flag, the next interrupt might be late, but
the next time around, when the processor isn't as busy, the interrupt "catches up,"* so to speak.
One reason flashing an LED is so important is that it proves the basic structure is working.
I/O
After a few late nights, I've finally got my "O" going,** now to work on the "I." To begin with,
Atmel provides three registers to work with I/O, the data direction register, DDRB, the Port B register, and the Pin B register.
After defining the direction of each pin with DDRB, you can write to the output with the Port B address, but to read from the input,
you use the Pin B address. This creates a neat feature of being able to see if your output is being overloaded. You can write to the
output and then look at the pins to see if it is outputting what you thought it was. Hmmmm, kinda' cool, you could sense a bad condition
and go into a safe mode. Don't know if I'll use it on this project, but it could come in handy later!
Begin by setting up the buttons. As you may remember from TOP SECRET
Motor Control, I decided to put all my buttons on one port and differentiate between them using various resistors and the A/D
conversion capabilities of the Tiny 15. As I began setting that up, found myself facing a quandary
set a top level to the
comparison window, or will a bottom level be sufficient? I selected the bottom level only for now
why complicate things if
you don't need to. But what levels should be set? It is easy to calculate the voltage levels, but something is always lost in
measurement that you need to account for. To do this the easy way, I first set up the PWM output on the Tiny 15 to use it to get
an accurate read on the buttons. What better way to see what the micro thinks it is reading than to have it output it on a port?
Besides, I need an operating PWM anyway.
The PWM mode uses three 8-bit counters: timer counter 1 (TCNT1), and Output compare register 1A and 1B (OCR1A and OCR1B
respectively). As you set up the PWM output, you pre-define a clock prescaler, and load OCRB1 with the value that is the maximum
count of your PWM. An important note: the resolution of the PWM signal depends on the value in OCRB1.
Taking the "baby-steps" approach, I start by setting up a simple ramp for the PWM to follow, incrementing a counter until it
reaches maximum PWM, and then start over. I also hook the output up to an LED, just in case I made a hardware mistake; the damage
wouldn't be as bad as the motor might cause. To verify the microcontroller knows that I'm pressing a button, I toggle one of the
LEDs. Here is a smattering of simple code to do that. (Note: this all happens every 0.1 s as I mentioned in the Structure
section above.)
Once I'm satisfied that the code is working correctly, I simply set up the
A/D converter on the Tiny 15 to feed the value it reads from the keyboard to the PWM output. Now I know exactly what the Tiny 15
is reading from my keys, so I assign values to each button. We're cruisin' now!
|
|||||||||||||||||||||||||||||||||||||
|
Copyright © 2003 ChipCenter-QuestLink About ChipCenter-Questlink |
||||||||||||||||||||||||||||||||||||||