Контроллер МЕГА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 -заданное значение. Когда движок доезжает до заданного места (совпадает значение энкодера и заданное), происходит перезапуск по ватчдогу.
|