Толи я что-то не понял, толи оно не работает.
В общем при попытке перейти на AtTiny25 впрямую ничего не получилось, пришлось курить маны.
В итоге было найдено кучка ошибок в коде программы, особенно если всё делать по манам.
Пришлось програмить своё заново, и оно того стоило!
В данный момент программа может работать как на Tiny15, так и на 25/45/85 (последние особо дёшевы в Чип и Дип, 220 рублей за tiny25 и всего 110 за tiny85).
Програмил на AVR-GCC в AVR Studio, код громозок и есть куда оптимизировать, но лень, очень лень.
Выкладываю свою разработку в исходнике, кому надо - оптимизируйте.
AVR Studio нахаляву забрать можно на сайте атмела, WinAVR найти в гугле.
Если кто на выходе в 2 раза сократит прогу, то пойдёт и на tiny15, хотя, ИМХО, проще купитьт 45 или 85 тиню в Чип и Дип.
Шил все тини с помощью UniProf (версию не помню, но последняя с ручным апдейтом exe файла).
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#define ON_PROCESS 1
#define ON 2
#define OFF_PROCESS 3
#define OFF 4
#define SYSTEM_FAIL 10
// ïðåäíàñòðîéêè.. ïðèìåðíî â ñåêóíäàõ :)
#define initTimer 4 // ÷àñòîòà ïðîâåðêè òàéìåðîì
#define initButtonDelay 2 // çàäåðæêà êíîïêè 2ñåê
#define initBeforeStartDelay 5 // âðåìÿ äî âêëþ÷åíèÿ 10ñåê.
#define initAfterStartDelay 90 // çàäåðæêà ïîñëå âêëþ÷åíèÿ 90ñåê âðåìÿ íóæíîå íà ñòàðò âèíäå.
#define initBeforeOFFDelay 150 // âðåìÿ äî îòêëþ÷åíèÿ 150ñåê
#define initBeforeOFFDelay_Multipler 2 // ìíîæèòåëü 2 .=> 150ñåê*2 = 300ñåê = 5ìèí
#define initPowerDownDelay 120 // âðåìÿ îæèäàíèÿ âûêëþ÷åíèÿ êîìïà âî âðåìÿ âûêëþ÷åíèÿ
int PC_State;
int BeforeStartDelay;
int ButtonDelay;
int AfterStartDelay;
int BeforeOFFDelay;
int BeforeOFFDelay_Multipler;
int PowerDownDelay;
int Timer_step;
int main ( void )
{
DDRB = (1<<PB4)|(1<<PB1)|(1<<PB0); // èíèöèàëèçèðóåì ïèíû 0,1 è 4 äëÿ ââîäà èíôû
TCCR0B = (1<<CS02)|(1<<CS00); // òàéìåð CLK/1024
TIMSK = (1<<TOIE0); // âêëþ÷àåì òàéìåð
sei();
PORTB = 0x00; // óñòàíàâëèâàåì âñå ñîñòîÿíèÿ â 0 äëÿ íà÷àëà ìîîíèòîðèíãà
Timer_step = initTimer;
PC_State = OFF;
BeforeStartDelay = 0;
ButtonDelay = 0;
AfterStartDelay = 0;
BeforeOFFDelay = 0;
BeforeOFFDelay_Multipler = 0;
PowerDownDelay = 0;
for(;;)
{
}
return 0;
}
// PB0 - OUT BUTTON
// PB1 - OUT POWER
// PB2 - IN USB
// PB3 - IN ACC
// PB4 - OUT LED
void p_OFF()
{
if ( PINB & (1<<PB3) ) // ïîÿâèëîñü acc
{
PC_State = ON_PROCESS; // ïåðåõîäèì â ðåæèì âêëþ÷åíèÿ
BeforeStartDelay = initBeforeStartDelay; // îæèäàíèå äî íàæàòèÿ êíîïêè
ButtonDelay = initButtonDelay; // êàê äîëãî æàòü êíîïêó
if ( !(PORTB & (1<<PB1)) )
{
PORTB |= (1<<PB1); // âêëþ÷àåì áëîê ïèòàíèÿ
}
}
}
void p_ON_PROCESS()
{
if ( BeforeStartDelay > 0 ) // òàéìàóò äî íàæàòèÿ êíîïêè
{
if ( !( PINB & (1<<PB3) ) ) // à âäðóã acc ïðîïàëî ïîêà ìû êíîïêó åù¸ íå íàæàëè?
{
if ( PORTB & (1<<PB1) )
{
PORTB &= ~(1<<PB1); // îòïóñêàåì êíîïêó...
}
PC_State = OFF; // ïåðåõîä â ðåæèì ñëåæåíèÿ çà âêëþ÷åíèåì
return;
}
BeforeStartDelay --; // ìèíóñóåì òàéìàóò
}else{ // ïîåõàëè âêëþ÷àòü êîìï
if ( ButtonDelay > 0 ) // äåðæèì êíîïêó íàæàòîé
{
if ( !( PORTB & (1<<PB0) ) )
{
PORTB |= (1<<PB0); //òóïî æì¸ì êíîïêó
}
ButtonDelay --;
}else{
if ( PORTB & (1<<PB0) ) // ïðîâåðêà íà îòïóùåííîñòü êíîïêè
{
PORTB &= ~(1<<PB0); // îòïóñêàåì êíîïêó
AfterStartDelay = initAfterStartDelay; // çàäà¸ì òàéìåð äî ïîÿâëåíèÿ USB
}else{
if ( AfterStartDelay > 0 ) // æä¸ì äî ïîÿâëåíèÿ óñá ïî òàéìåðó
{
AfterStartDelay--;
}else{ // ïðîâåðÿåì ñòàòóñ USB
if ( PINB & (1<<PB2) ) // usb ïîÿâèëîñü, óõîäèì â ðàáîòó.
{
PC_State = ON;
return;
}else{
PC_State = SYSTEM_FAIL; // à íåòó óñá, ãîâíî ñëó÷àåòñÿ...
return;
}
}
}
}
}
}
void p_ON()
{
// ïðîïàäàíèå USB
if ( !( PINB & (1<<PB2) ) ) // ïðîïàëî USB. æîïà êîðî÷å.
{
PC_State = SYSTEM_FAIL;
return;
}
if ( !( PINB & (1<<PB3) ) ) // ïðîïàäàíèå ACC
{
PC_State = OFF_PROCESS;
BeforeOFFDelay = initBeforeOFFDelay; // èíèöèàëèçàöèÿ òàéìåðà äî âûêëþ÷åíèÿ
BeforeOFFDelay_Multipler = initBeforeOFFDelay_Multipler; // èíèöèàëèçàöèÿ òàéìåðà ìíîæèòåëÿ
ButtonDelay = initButtonDelay; // êàê äîëãî æàòü êíîïêó
PowerDownDelay = initPowerDownDelay; // êàê äîëãî æäàòü ïîòóõàíèÿ êîìïà
}
}
void p_OFF_PROCESS()
{
if ( !( PINB & (1<<PB2) ) ) // íåò îòâåòà ñ usb
{
PC_State = SYSTEM_FAIL; // íàõóé ïàäàåì è âñ¸ ãàñèì
return;
}
if ( BeforeOFFDelay_Multipler == 0 ) // òèïà òàéìåð ñ ìíîæèòåëåì íà íóëå.
{
if ( ButtonDelay > 0 ) // ïîêà äåðæèì êíîïêó, è äàæå åñëè íå äåðæèì.
{
if ( !( PORTB & (1<<PB0) ) )
{
PORTB |= (1<<PB0); // íàæèìàåì êíîïêó åñëè åù¸ íå íàæàòà
}
ButtonDelay --; // ìèíóñóåì òàéìåð íàæàòîé êíîïêè.
}else{
if ( PORTB & (1<<PB0) ) // îòïóñêàåì êíîïêó åñëè îíà åù¸ íàæàòà
{
PORTB &= ~(1<<PB0);
}
if ( PowerDownDelay > 0 ) // òèïà æä¸ì ïðîñòîãî âûêëþ÷åíèÿ
{
PowerDownDelay--; // íó è ìèíóñóåì òàéìåð îæèäàíèÿ âûêëþ÷åíèÿ
}else{
PC_State = SYSTEM_FAIL; // ïðîâàëèâàåìñÿ â system_fail â ëþáîì ñëó÷àå
}
}
}else{
if ( BeforeOFFDelay == 0 )
{
BeforeOFFDelay = initBeforeOFFDelay; // âîññòàíàâëèâàåì òàéìåð îòêëþ÷åíèå
BeforeOFFDelay_Multipler--; // ìèíóñóåì ìíîæèòåëü òàéìåðà âûêëþ÷åíèÿ
}else{
if ( PINB & (1<<PB3) ) // ACC âíåçàïíî ïîÿâèëîñü, ñëó÷àþòñÿ ãëþêè...
{
PC_State = ON;
return;
}
}
BeforeOFFDelay --;
}
}
void p_SYSTEM_FAIL()
{
if ( PORTB & (1<<PB1) ) // åñëè âêëþ÷åíû áëîêè ïèòàíèÿ...
{
PORTB &= ~(1<<PB1); // ...âûêëþ÷àåì íàõåð
}
if ( PINB & (1<<PB3) ) // òèïà åñòü ACC
{
if ( PORTB & (1<<PB4) ) // ìèãàíèå ñâåòîäèîäà ERROR
{
PORTB &= ~(1<<PB4); // âûêëþ÷àåì ñâåòîäèîä
}else{
PORTB |= (1<<PB4); // âêëþ÷àåì ñâåòîäèîä
}
}else{
PC_State = OFF; // ñáðàñûâàåì ñîñòîÿíèå. àññ íåò âñ¸ ðàâíî.
if ( PORTB & (1<<PB4) ) // ìèãàíèå ñâåòîäèîäà ERROR
{
PORTB &= ~(1<<PB4); // âûêëþ÷àåì ñâåòîäèîä
}
}
}
ISR(TIMER0_OVF_vect)
{
Timer_step--;
if ( Timer_step == 0 )
{
if ( PC_State == OFF )
{
p_OFF();
}
if ( PC_State == ON_PROCESS )
{
p_ON_PROCESS();
}
if ( PC_State == ON )
{
p_ON();
}
if ( PC_State == OFF_PROCESS )
{
p_OFF_PROCESS();
}
if ( PC_State == SYSTEM_FAIL )
{
p_SYSTEM_FAIL();
}
Timer_step = initTimer;
}
}
PS Знать бы АСМ получше, на нём бы написал
