Styrning av servo
Postat: 18 februari 2011, 17:46:22
Tjabba!
Har en liten fråga angående styrning av servo. Det är så att jag använder mig utav en PIC16F872 för att styra ett servo. Allt fungerar jättebra, men har stött på ett litet underligt problem. Följande kod används när allt fungerar som det ska:
Problemet uppstår dock när jag försöker ändra
till
Tycker inte att datatypsändringen bör ha någon större inverkan på själva styrningen.
Anledningen till att jag vill ändra dem till float är för att jag vill kunna utföra avbrott tätare än med 0.1 ms.
Har en liten fråga angående styrning av servo. Det är så att jag använder mig utav en PIC16F872 för att styra ett servo. Allt fungerar jättebra, men har stött på ett litet underligt problem. Följande kod används när allt fungerar som det ska:
Kod: Markera allt
#include <pic16f872.h>
#define TRUE 1
#define FALSE 0
void initPorts();
void initPWM();
void initISR();
void initAD();
int getAD();
// values
int pulse_width = 15;
int ADvalue = 514;
//counters
int period_counter = 0;
int pulse_high_counter = 0;
int point_one_ms_counter = 0;
//flags
char ten_ms_flag = FALSE;
void main()
{
initPorts();
initAD();
initISR();
initPWM();
while(TRUE)
{
if(ten_ms_flag)
{
ten_ms_flag = FALSE;
ADvalue = getAD();
if(ADvalue <= 10)
pulse_width = 6;
else if(ADvalue <= 70)
pulse_width = 7;
else if(ADvalue <= 140)
pulse_width = 8;
else if(ADvalue <= 210)
pulse_width = 9;
else if(ADvalue <= 280)
pulse_width = 10;
else if(ADvalue <= 350)
pulse_width = 11;
else if(ADvalue <= 420)
pulse_width = 12;
else if(ADvalue <= 490)
pulse_width = 13;
else if(ADvalue <= 560)
pulse_width = 14;
else if(ADvalue <= 630)
pulse_width = 15;
else if(ADvalue <= 700)
pulse_width = 16;
else if(ADvalue <= 770)
pulse_width = 17;
else if(ADvalue <= 840)
pulse_width = 18;
else if(ADvalue <= 910)
pulse_width = 19;
else if(ADvalue <= 980)
pulse_width = 20;
}
}
}
void initPorts()
{
TRISB = 0x00;
TRISC = 0x00;
TRISA = 0xff;
TRISBbits.TRISB4 = 1;
PORTBbits.RB1 = 1;
PORTBbits.RB2 = 0;
PORTCbits.RC2 = 0;
}
void initISR()
{
INTCON = 0xE0;
OPTION_REG = 0b00000000;
TMR0 = 206;
T0IF = 0;
}
void initPWM()
{
CCP1CON = 0x0F;
T2CON = 0x04;
PR2 = 0xC7;
CCPR1L = 0xC7;
}
void initAD()
{
ADCON0 = 0b00000001;
ADCON1 = 0b10001110;
}
int getAD()
{
int value = 0;
ADCON0bits.GO_DONE = 1;
while(ADCON0bits.GO_DONE == 1);
value = ADRESH;
value = (value << 8) + ADRESL;
return value;
}
static void interrupt isr(void) //Avbrott varje 0.1 ms
{
if(T0IF)
{
T0IF = 0;
TMR0 = 206;
point_one_ms_counter = point_one_ms_counter + 1;
period_counter = period_counter + 1;
pulse_high_counter = pulse_high_counter + 1;
if(pulse_high_counter <= pulse_width)
PORTBbits.RB2 = 1;
else
PORTBbits.RB2 = 0;
if(period_counter >= 200)
{
period_counter = 0;
pulse_high_counter = 0;
}
if(point_one_ms_counter >= 100)
{
ten_ms_flag = TRUE;
point_one_ms_counter = 0;
}
}
}
Kod: Markera allt
int period_counter = 0;
int pulse_high_counter = 0;
int point_one_ms_counter = 0;
Kod: Markera allt
float period_counter = 0;
float pulse_high_counter = 0;
float point_one_ms_counter = 0;
Anledningen till att jag vill ändra dem till float är för att jag vill kunna utföra avbrott tätare än med 0.1 ms.