Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C Programming for microcontrollers (Joe Pardue, 2005).pdf
Скачиваний:
260
Добавлен:
12.08.2013
Размер:
4.55 Mб
Скачать

Chapter 9 – Digital Meets Analog – ADC and DAC

Chapter 9 – Digital Meets Analog – ADC and

DAC

But First - A Debugging Tale

In the ADC project that follows, I liberally ‘borrowed’ code from the Butterfly, adding my own inimitable style to allow a user from the PC to ask for a measure of light, temperature, and voltage. All was well except for a tiny problem with the voltage measurement. Tiny as in the first time I tried to measure voltage on the Butterfly I destroyed it. Well destroyed is a bit harsh. It looks just like it always did, but it doesn’t work. Fortunately I know myself so I had ordered six Butterflys because, as I said elsewhere, my nickname is Smoky Joe since my favorite learning method is producing copious quantities of smoke in my hardware projects. The Butterfly didn’t smoke though. It just died. Belly up, legs in the air, ready for a pin thru the thorax to be box mounted in the Dead Butterfly Museum. But Lepidopteron death is not what this is about. I eventually found that I had done something unbelievably stupid and since you wouldn’t believe it, I won’t relate that tale. Lets just say this event led me to becoming a bit paranoid about the voltage measurement part of the Butterfly hardware and I went forward on tiptoes and slightly hyperventilating as I proceeded with the ADC code.

My next version was able to read the light just fine, and the temperature just fine, and the voltage just one time.

When I requested: volt the hardware responded to HyperTerminal with: The reading is 1.1 volts.

And promptly died. No further responses to the PC. My response involved lots of obscenities and complaints about flushing another $19.99, but the Butterfly wasn’t destroyed this time, it rebooted just fine and only crashed when I asked for ‘volt’. My first assumption, reasonable I thought, was that it’s the light level in the room. Sound crazy? Well, it seems that the light sensor affects the Butterfly voltage reference and we have to measure the ambient room light to calibrate the voltage reference before we measure volts. So I covered the light sensor and the Butterfly still crashed. Then I went the other direction and put a bright light on it to no avail. So I thought that if its all that sensitive to light derived voltages maybe the USART traffic voltage is propagating about unpredictably and screwing things up. The USART uses a higher voltage than the Butterfly and they

207

Chapter 9 – Digital Meets Analog – ADC and DAC

have included a voltage inverter circuit that looked like a prime candidate to radiate messy voltages that might combine with a voltage on the Voltage In pin and might, theoretically, cause a problem. So I changed PC_Comm so that it sent the PC a ‘!’ every time it received a character. In HyperTerminal I got:

So after requesting ‘volt’ the Butterfly was no longer exclaiming with a ‘!’ but decided it wanted to play cards with a black club, or perhaps more reasonably, I thought, the ‘!’ was being scrambled on reception by the PC because the Baud rate had changed (I’ve seen that happen before). So I reread the data sheet on the USART and diddled with the Butterfly schematics and tried a few coding changes. Hours passed and still no fix. I messed with the USART initialization function, the ADC initialization function, the ADC read function, the oscillator calibration function and generally had myself a merry old goose chase for about half a day. Nothing fixed the problem, but at least the Butterfly didn’t explode nor make the least bit of smoke, the code was consistently responding with a black club rather than the ‘!’ but at least it was running.

Finally, in total desperation, I tried what I should have tried in the first place. I bracketed code by commenting out sections (putting // in front of a line) to see where exactly the problem occurred. Eventually I got to the getVolt function and started commenting out sections. This is a time consuming process, each time you comment something out, you have to recompile, load, and test the code. It takes a while. So here is the getVolt code:

void getVolt()

{

char voltintpart[]= {''0','\0'}; char voltfractpart[]= {'0','\0'}; int intpart = 0;

int fractpart = 0; int ADCresult = 0;

ADCresult = ADC_read(); intpart = ADCresult/50;

208

Chapter 9 – Digital Meets Analog – ADC and DAC

fractpart = ADCresult%50;

itoa(intpart, voltintpart, 10); itoa(fractpart, voltfractpart, 10);

// Send the voltage to the PC sendString("The reading is "); sendChar(voltintpart [0]); sendChar('.'); sendChar(voltfractpart [0]); sendString(" volts.\r");

}

I commented out each logical part and still nothing worked. Finally, because there was nothing logical to try, I commented out the itoa functions. And the Butterfly no longer messed up. Also, it started returning ‘!’ rather than the black club for each character I sent it. Of course, it didn’t return the correct voltage, because I wasn’t converting it to ASCII, but it was running fine otherwise and correctly returned the light and temperature. The itoa function is in the standard library, so I assumed that it must have a problem. I changed it to the itoa function (and the other support functions) that we wrote at the end of Chapter 6. Guess what? They also fail! I went for a long walk.

Later, after more staring at the function I noticed:

char voltintpart[]= {''0','\0'}; char voltfractpart[]= {'0','\0'};

These can’t be the problem, can they? They work just fine in the original Butterfly code. But many years ago I learned the hard way that if you assign memory to an array and then foolishly write beyond that memory, say to voltintpart[2], the third element of the array which only has two elements you will in fact write to the byte in memory that follows the array bytes which may not cause a problem if nothing else is using that byte, or it might just change it from the ASCII code for an explanation point to the Microsoft extended ASCII code for a black club. So I enlarged them to:

char voltintpart[]= {'0','0',0','\0'}; char voltfractpart[]= {''0',0','0','\0'};

And the code works just fine.

209