Started following some tutorial on att85 usi. Downloaded example code from make avr book.
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
// Talking Voltmeter Example
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/power.h>
|
||||
#include "pinDefines.h"
|
||||
#include "USART.h"
|
||||
|
||||
#include "talkingVoltmeter.h"
|
||||
|
||||
void startSampleTimer(void) {
|
||||
sampleNumber = 0; /* back to start of sample table */
|
||||
TCCR2B = (1 << CS21); /* turn on timer clock */
|
||||
/* Two clock options above end up ~8kHz on 8MHz system */
|
||||
}
|
||||
void stopSampleTimer(void) {
|
||||
TCCR2B = 0; /* disable sample-playback clock */
|
||||
OCR0A = 128; /* idle PWM at mid-voltage */
|
||||
lastout = 0; /* start at 0 next time */
|
||||
}
|
||||
void speak(void) {
|
||||
startSampleTimer();
|
||||
loop_until_bit_is_clear(TCCR2B, CS21); /* Wait until done */
|
||||
}
|
||||
|
||||
void updatePWMAudio(void) {
|
||||
OCR0A = out + 128; /* re-center for 0-255 PWM */
|
||||
lastout = out; /* update last value */
|
||||
sampleNumber++; /* on to next sample */
|
||||
}
|
||||
void unpackByte(uint8_t dataByte) {
|
||||
/* Select pairs of bits from byte, save out */
|
||||
differentials[0] = (dataByte >> 6) & 0b00000011;
|
||||
differentials[1] = (dataByte >> 4) & 0b00000011;
|
||||
differentials[2] = (dataByte >> 2) & 0b00000011;
|
||||
differentials[3] = (dataByte & 0b00000011);
|
||||
}
|
||||
|
||||
/* Timer 2 controls sampling speed.
|
||||
ISR reads new data, loads PWM values into OCR0A */
|
||||
ISR(TIMER2_COMPA_vect) {
|
||||
/* Since we can decode 4 2-bit values at once, need to know where
|
||||
we are in the 4-step mini-cycle. */
|
||||
uint8_t cycle = sampleNumber & 0b00000011; /* keep last 2 bits */
|
||||
uint16_t tableEntry;
|
||||
uint8_t packedData;
|
||||
|
||||
if (cycle == 0) { /* at first sample, re-load */
|
||||
tableEntry = sampleNumber >> 2; /* where we are in table */
|
||||
if (tableEntry < thisTableLength) {
|
||||
/* read the next byte from the selected table */
|
||||
packedData = pgm_read_byte(&thisTableP[tableEntry]);
|
||||
unpackByte(packedData); /* split up byte into differentials[] */
|
||||
}
|
||||
else { /* at end of table, done. */
|
||||
stopSampleTimer();
|
||||
}
|
||||
}
|
||||
/* Decode the differences: current value = last + difference */
|
||||
out = lastout + dpcmWeights[differentials[cycle]] - (lastout >> 4);
|
||||
updatePWMAudio();
|
||||
} // end ISR (TIMER2_COMPA_vect)
|
||||
|
||||
void printString_Progmem(const char *stringP) {
|
||||
char oneLetter;
|
||||
while ((oneLetter = pgm_read_byte(stringP))) {
|
||||
transmitByte(oneLetter);
|
||||
stringP++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
uint16_t voltage;
|
||||
uint8_t volts;
|
||||
uint8_t tenths;
|
||||
uint8_t vcc = 51; /* 10x VCC, in volts */
|
||||
|
||||
clock_prescale_set(clock_div_1); /* 8 MHz */
|
||||
initTimer0();
|
||||
initTimer2();
|
||||
sei(); /* for timer2 ISR */
|
||||
initADC();
|
||||
initUSART();
|
||||
|
||||
printString_Progmem(PSTR("\r\n--=( Talking Voltmeter )=--\r\n"));
|
||||
|
||||
selectTable(INTRO);
|
||||
speak();
|
||||
|
||||
while (1) {
|
||||
|
||||
ADCSRA |= (1 << ADSC); /* start ADC */
|
||||
loop_until_bit_is_clear(ADCSRA, ADSC);
|
||||
|
||||
voltage = ADC * vcc + vcc / 2; /* vcc/2 to make rounding work */
|
||||
voltage = voltage >> 10; /* divide by 10-bits for ADC */
|
||||
/* "voltage" is now actually 10x real-world voltage */
|
||||
volts = voltage / 10;
|
||||
tenths = voltage % 10;
|
||||
|
||||
transmitByte('0' + volts); /* serial output as well */
|
||||
selectTable(volts); /* 0 points to ZERO_TABLE, etc */
|
||||
speak();
|
||||
|
||||
transmitByte('.');
|
||||
selectTable(POINT);
|
||||
speak();
|
||||
|
||||
transmitByte('0' + tenths);
|
||||
selectTable(tenths);
|
||||
speak();
|
||||
|
||||
printString_Progmem(PSTR(" volts\r\n"));
|
||||
selectTable(VOLTS);
|
||||
speak();
|
||||
|
||||
_delay_ms(SPEECH_DELAY);
|
||||
|
||||
} /* end while */
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user