|
楼主 |
发表于 2010-1-27 14:25
|
显示全部楼层
单片机是ATtiny 13A,代码如下
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#define LOW 0x00
#define HIGH 0x01
#define FLASH 0x02
#define SOS 0x03
volatile unsigned char status;
ISR(INT0_vect)
{
//low battery warning
DDRB |= 0x01;
for (char i = 0; i < 12; i++)
{
PORTB |= 0x01;
_delay_ms(200);
PORTB &= 0xfe;
_delay_ms(50);
PORTB |= 0x01;
}
if (status == LOW) DDRB &= 0xfe;
if (status == HIGH) PORTB |= 0x01;
if ((status == LOW) || (status == HIGH))
for (char i = 0; i < 60; i++) _delay_ms(1000);
else cli();
}
int main()
{
unsigned char address, readData, writeData, i, pAddress;
//read eeprom
pAddress = 0x00;
address = eeprom_read_byte((uint8_t *)pAddress);
readData = eeprom_read_byte((uint8_t *)address);
switch (readData)
{
case 0x00:
status = LOW;
writeData = 0x55;
break;
case 0x55:
status = HIGH;
writeData = 0xaa;
break;
case 0xaa:
status = FLASH;
writeData = 0xff;
break;
case 0xff:
status = SOS;
writeData = 0x00;
break;
default://eeprom exception
status = LOW;
writeData = 0x00;
address += 1;
if (address >= 0x40) address = 0x01;
eeprom_write_byte((uint8_t *)pAddress, address);
eeprom_busy_wait();
}
//initial
//PB: ADC2 NC CELLS /LOBAT CTRL
//CELLS 0: 1cell 1: 2cell
DDRB = 0x04;//CELLS = 1
PORTB = 0x0a;//NC = 1, /LOBAT = 1
//measure the voltage of battary
ADMUX = 0x42;//0100_0010 - REFS0 ADLAR - - - MUX1 MUX0
DIDR0 = 0x08;//0001_0000 - - ADC0 ADC2 ADC3 ADC1 - -
ADCSRA = 0xc7;//1100_0111 ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
while (!(ADCSRA & 0x10));
//set CELLS if ADC_result > 0.55V
if (ADCH & 0x02) PORTB |= 0x04;//cell = 1
else if ((status == FLASH)||(status == SOS))
{
status = LOW;
writeData = 0x55;
}
ADCSRA &= 0x7f;
//close ADC
eeprom_write_byte((uint8_t *)address, writeData);
eeprom_busy_wait();
//set status and delay 2s
switch (status)
{
case LOW:
_delay_ms(4000);
break;
case HIGH:
DDRB |= 0x01;
PORTB |= 0x01;
_delay_ms(4000);
break;
case FLASH:
DDRB |= 0x01;
for (i = 0; i < 40; i++)
{
PORTB |= 0x01;
_delay_ms(10);
PORTB &= 0xfe;
_delay_ms(90);
}
break;
case SOS:
DDRB |= 0x01;
//send a SOS
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
break;
default:
break;
}
//write eeprom
eeprom_write_byte((uint8_t *)address, LOW);
eeprom_busy_wait();
//sleep, flash or SOS
if ((status == LOW)||(status == HIGH))
{
//low battery detect and warning
//set int0 interrupt to detect low battery
GIMSK |= 0x40;//enable int0
sei();//enable interrupt
for(;;)
{
//sleep
PRR |= 0x02;//set sleep mode as power down
sleep_enable();
//sleep...
sleep_cpu();
sleep_disable();
}
}
else if (status == FLASH) for(;;)
{
PORTB |= 0x01;
_delay_ms(10);
PORTB &= 0xfe;
_delay_ms(90);
}
else for(;;)
{
//send SOSs
_delay_ms(1900);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '-'
_delay_ms(300);
PORTB &= 0xfe;
_delay_ms(700);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
_delay_ms(200);
PORTB |= 0x01;//output a '.'
_delay_ms(100);
PORTB &= 0xfe;
}
return 0;
} |
|