Has somebody an idea, a suggestion in order to help me ?
PIC 16F877A > Hereunder the code consisting of driving two servomotors separately for a 2 axes pan tilt.
TMR2 : for 20 mS period
TMR1 : for Ton UPPER servomotor
TMR0 : for Ton LOWER servomotor
I deleted the code consisting of driving LOWER servomotor because it’s works properly.
For UPPER servomotor, the 16 bits data in consigne_1 never loads in both 8 bits registers TMR1L and TMR1H when troobleshooting and monitoring them with Debugger of MikroC For PIC. Both registers are empty. In that case servo never turns.
Code :
unsigned int consigne_1;
unsigned char *p1;
volatile unsigned char flag_TMR1;
// Timer2 (8 bits) : 20 mS period
// Prescaler 1:16
// Postscaler 1:5
// PR2 preload = 250
// TMR2 preload = 0
// Interrupt time : 20,005 mS
void Init_Timer2()
{
// Timer 2 in timer mode :
T2CON = 0x26;
PR2 = 250;
TMR2IE_bit = 1;
INTCON = 0xC0;
}
// Timer1 (16 bits) : Ton servomotor UPPER
// Prescaler 1:1
// TMR1 preload = 64536
// Interrupt time : 1 mS
void Init_Timer1()
{
// Timer 1 in timer mode :
T1CON = 0x01;
TMR1IF_bit = 0;
TMR1H = 0xFC;
TMR1L = 0x18;
TMR1IE_bit = 1;
INTCON = 0xC0;
flag_TMR1 = 1;
}
// Timer0 (8 bits) : Ton servomotor LOWER
// Prescaler 1:1
// TMR0 Preload = 156
// Interrupt Time : 0,1 mS (100 uS)
void Init_Timer0()
{
// Timer 0 in timer mode :
OPTION_REG = 0x88;
TMR0 = 156;
INTCON = 0xA0;
cnt0 = 0;
}
/* ----------------------------------------------------------------------------*/
void Interrupt()
{
if (TMR2IF_bit && TMR2IE_bit) // After 20 mS elapsed with Timer2 ...
//if (TMR2IF_bit == 1)
{
// Timer 0 : // Servomotor LOWER.
TMR0IE_bit = 0; // Disenables Timer0 interrupt bit (stops Timer0).
TMR0 = 156;
TMR0IF_bit = 0;
portd.b0 = 1; // Servomotor LOWER ON.
portc.b2 = 1; // LED ON.
TMR0IE_bit = 1; // Enables Timer0 interrupt bit (starts Timer0).
// Timer 1 : // Servomotor UPPER.
flag_TMR1 = 1; // Timer1 is counting.
//TMR1ON_bit = 0;
p1 = &consigne_1;
TMR1L = *(p1);
TMR1H = *(p1 + 1);
TMR1IE_bit = 1; // Enables Interrupt.
TMR1IF_bit = 0; // Resets Interrupt Flag.
portd.b1 = 1; // Servomotor UPPER ON.
portc.b2 = 1; // LED ON.
//TMR1ON_bit = 1; // Enables (start) Timer1.
// Restarts Timer 2 :
TMR2IE_bit = 1; // XXX optionnel XXX
TMR2IF_bit = 0;
PR2 = 250;
}
if (TMR0IF_bit && TMR0IE_bit) // After 100 uS elapsed with TMR0 ...
//if (TMR0IF_bit == 1)
{
cnt0++; // Increments "100 uS" counter.
//TMR0IE_bit = 0;
TMR0IE_bit = 1;
TMR0IF_bit = 0;
TMR0 = 156;
}
if (TMR1IF_bit && TMR1IE_bit) // After n x 100 uS elapsed with TMR1 ...
//if (TMR1IF_bit == 1)
{
flag_TMR1 = 0; // Timer1 stops counting.
portd.b1 = 0; // Servomotor UPPER OFF.
portc.b2 = 0; // LED OFF.
flag_TMR1 = 0;
TMR1ON_bit = 0; // Stops (disenables) Timer
TMR1IF_bit = 0;
TMR1IE_bit = 1; // XXX optionnel XXX
TMR1L = *(p1);
TMR1H = *(p1 + 1);
}
}
void main()
{
TRISC = 0;
PORTC = 0;
TRISD = 0;
PORTD = 0;
while(1)
{
p1 = & TMR1L
consigne_1 = 65535 - 1000; // consigne_1 = 65535 - 1000 => 64535 à 65535 = 1000 x uS = 1 mS = Ton.
sprintl(*p1, "%5u", consigne_1);
Delay_ms(1000);
consigne_1 = 65535 - 1500; // consigne_1 = 65535 - 1500 => 64035 à 65535 = 1500 x uS = 1,5 mS = Ton.
sprintl(*p1, "%5u", consigne_1);
Delay_ms(1000);
consigne_1 = 65535 - 2000; // consigne_1 = 65535 - 2000 => 63535 à 65535 = 2000 x uS = 2,0 mS = Ton.
sprintl(*p1, "%5u", consigne_1);
Delay_ms(1000);
}
}