Контроллер МЕГА16, IAR EWAVR 4.20, scmRTOS v 3.00-beta
фрагмент кода
OS_PROCESS void TProcess::Exec()
{
while(true)
{
__watchdog_reset();
Sleep(100);
PORTA &= ~(1<<PA5);
PORTA &= ~(1<<PA7);//вниз 0
__delay_cycles(10); //t1 > 0.45 мкс
word hGray, vGray; //код грея от энкодера
__watchdog_reset();
for(int i = 0; i < 10; i++)
{
hGray <<= 1;
vGray <<= 1;
PORTA |= (1<<5)|(1<<7);//вверх 1
__delay_cycles(10);
if(PINA&0x40) hGray |=(1<<0);
if(PINA&0x10) vGray |=(1<<0);
PORTA &= ~(1<<PA5);
PORTA &= ~(1<<PA7);//вниз 0
__delay_cycles(10);
}
__delay_cycles(30);
PORTA |= (1<<5)|(1<<7);//вверх 1
__watchdog_reset();
hGray &= 0x3FF;
vGray &= 0x3FF;
__watchdog_reset();
*phA = GrayToBin(hGray);
*pvA = GrayToBin(vGray);
byte dir=0;
__watchdog_reset();
byte vvA = HIGHBYTE(vAngle<<6);
byte hhA = HIGHBYTE(hAngle<<6);
byte TvA = HIGHBYTE(vTargetAngle<<6);
byte ThA = HIGHBYTE(hTargetAngle<<6);
if ((vvA>TvA)&&enable_move) dir |=(1<<3);
if ((vvA<TvA)&&enable_move) dir |=(1<<2);
if (vvA == TvA) dir &= ~((1<<2)|(1<<3));
if ((hhA>ThA)&&enable_move) dir |=(1<<1);
if ((hhA<ThA)&&enable_move) dir |=(1<<0);
if (hhA == ThA) dir &= ~((1<<0)|(1<<1));
if ((vvA == TvA)&&(hhA == ThA))
{
enable_move = 0; //EFlag.Clear();
}
PORTA = 0xF0|dir;
//move = 0xFF;
//задание направления движения
//__watchdog_reset();
__watchdog_reset();
}
}
Виснет в момент совпадения (== по if) . Испол зую глобальные переменные, здесь vAngle - текущее значение угла, vTarget -заданное значение. Когда движок доезжает до заданного места (совпадает значение энкодера и заданное), происходит перезапуск по ватчдогу.