Started following some tutorial on att85 usi. Downloaded example code from make avr book.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
|
||||
|
||||
// ------- Preamble -------- //
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/power.h>
|
||||
|
||||
#include "pinDefines.h"
|
||||
#include "USART.h"
|
||||
|
||||
#include "i2c.h" /* for i2c functions */
|
||||
#include "25LC256.h" /* for EEPROM specific */
|
||||
|
||||
// -------- Defines --------- //
|
||||
|
||||
#define LM75_ADDRESS_W 0b10010000
|
||||
#define LM75_ADDRESS_R 0b10010001
|
||||
#define LM75_TEMP_REGISTER 0b00000000
|
||||
#define LM75_CONFIG_REGISTER 0b00000001
|
||||
#define LM75_THYST_REGISTER 0b00000010
|
||||
#define LM75_TOS_REGISTER 0b00000011
|
||||
|
||||
#define CURRENT_LOCATION_POINTER 0
|
||||
/* where to store a pointer to the current reading in EEPROM */
|
||||
#define SECONDS_POINTER 2
|
||||
/* store seconds-delay value here */
|
||||
#define MEMORY_START 4
|
||||
/* where to start logging temperature values */
|
||||
#define MENU_DELAY 5
|
||||
/* seconds to wait before bypassing main menu */
|
||||
|
||||
// -------- Functions --------- //
|
||||
|
||||
static inline void printTemperature(uint8_t tempReading) {
|
||||
/* temperature stored as 2x Celcius */
|
||||
printByte((tempReading >> 1));
|
||||
if (tempReading & 1) {
|
||||
printString(".5\r\n");
|
||||
}
|
||||
else {
|
||||
printString(".0\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint16_t secondsDelay; /* how long to wait between readings */
|
||||
uint16_t currentMemoryLocation; /* where are we in EEPROM? */
|
||||
uint16_t i; /* used to count memory locations */
|
||||
uint8_t tempHighByte, tempLowByte, temperatureByte; /* from LM75 */
|
||||
uint8_t enterMenu; /* logical flag */
|
||||
|
||||
// -------- Inits --------- //
|
||||
clock_prescale_set(clock_div_1); /* 8 MHz */
|
||||
initSPI();
|
||||
initI2C();
|
||||
initUSART();
|
||||
LED_DDR |= (1 << LED0);
|
||||
|
||||
/* Load up last values from EEPROM */
|
||||
secondsDelay = EEPROM_readWord(SECONDS_POINTER);
|
||||
|
||||
/* Delay to allow input to enter main menu */
|
||||
printString("*** Press [m] within ");
|
||||
printByte(MENU_DELAY);
|
||||
printString(" seconds to enter menu. ***\r\n ");
|
||||
|
||||
for (i = 0; i < MENU_DELAY; i++) {
|
||||
_delay_ms(1000);
|
||||
}
|
||||
|
||||
if (bit_is_set(UCSR0A, RXC0) && (UDR0 == 'm')) {
|
||||
enterMenu = 1;
|
||||
}
|
||||
else {
|
||||
enterMenu = 0;
|
||||
}
|
||||
|
||||
while (enterMenu) {
|
||||
printString("\r\n====[ Logging Thermometer ]====\r\n ");
|
||||
currentMemoryLocation = EEPROM_readWord(CURRENT_LOCATION_POINTER);
|
||||
printWord(currentMemoryLocation - MEMORY_START);
|
||||
printString(" readings in log.\r\n ");
|
||||
printWord(secondsDelay);
|
||||
printString(" seconds between readings.\r\n");
|
||||
printString(" [<] to shorten sample delay time\r\n");
|
||||
printString(" [>] to increase sample delay time\r\n");
|
||||
printString(" [?] to reset delay time to 60 sec\r\n");
|
||||
printString(" [d] to print out log over serial\r\n");
|
||||
printString(" [e] to erase memory\r\n");
|
||||
printString(" [s] to start logging\r\n\r\n");
|
||||
|
||||
switch (receiveByte()) {
|
||||
case 'd':
|
||||
SLAVE_SELECT;
|
||||
SPI_tradeByte(EEPROM_READ);
|
||||
EEPROM_send16BitAddress(MEMORY_START);
|
||||
for (i = MEMORY_START; i < currentMemoryLocation; i++) {
|
||||
SPI_tradeByte(0);
|
||||
printTemperature(SPDR);
|
||||
}
|
||||
SLAVE_DESELECT;
|
||||
break;
|
||||
case '<':
|
||||
if (secondsDelay >= 10) {
|
||||
secondsDelay -= 5;
|
||||
EEPROM_writeWord(SECONDS_POINTER, secondsDelay);
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (secondsDelay < 65000) {
|
||||
secondsDelay += 5;
|
||||
EEPROM_writeWord(SECONDS_POINTER, secondsDelay);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
secondsDelay = 60;
|
||||
EEPROM_writeWord(SECONDS_POINTER, secondsDelay);
|
||||
break;
|
||||
case 'e':
|
||||
printString("Clearing EEPROM, this could take a few seconds.\r\n");
|
||||
EEPROM_clearAll();
|
||||
EEPROM_writeWord(CURRENT_LOCATION_POINTER, MEMORY_START);
|
||||
EEPROM_writeWord(SECONDS_POINTER, secondsDelay);
|
||||
break;
|
||||
case 's':
|
||||
printString("OK, logging...\r\n");
|
||||
enterMenu = 0;
|
||||
break;
|
||||
default:
|
||||
printString("Sorry, didn't understand that.\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ------ Event loop ------ //
|
||||
while (1) {
|
||||
|
||||
currentMemoryLocation = EEPROM_readWord(CURRENT_LOCATION_POINTER);
|
||||
|
||||
/* Make sure in temperature mode */
|
||||
i2cStart();
|
||||
i2cSend(LM75_ADDRESS_W);
|
||||
i2cSend(LM75_TEMP_REGISTER);
|
||||
/* Get Temp from thermometer */
|
||||
i2cStart(); /* Setup and send address, with read bit */
|
||||
i2cSend(LM75_ADDRESS_R);
|
||||
tempHighByte = i2cReadAck(); /* two bytes of temperature */
|
||||
tempLowByte = i2cReadNoAck();
|
||||
i2cStop();
|
||||
temperatureByte = (tempHighByte << 1) | (tempLowByte >> 7);
|
||||
/* temperatureByte now contains 2x the temperature in Celcius */
|
||||
printTemperature(temperatureByte); /* serial output */
|
||||
|
||||
/* Save the new temperature value */
|
||||
EEPROM_writeByte(currentMemoryLocation, temperatureByte);
|
||||
|
||||
/* move on to next location and record new position
|
||||
if not already at the end of memory */
|
||||
if (currentMemoryLocation < EEPROM_BYTES_MAX) {
|
||||
currentMemoryLocation++;
|
||||
EEPROM_writeWord(CURRENT_LOCATION_POINTER, currentMemoryLocation);
|
||||
}
|
||||
|
||||
/* delay */
|
||||
for (i = 0; i < secondsDelay; i++) {
|
||||
_delay_ms(1000);
|
||||
LED_PORT ^= (1 << LED0); /* blink to show working */
|
||||
}
|
||||
|
||||
} /* End event loop */
|
||||
return 0; /* This line is never reached */
|
||||
}
|
||||
Reference in New Issue
Block a user