Postat: 25 mars 2007, 15:08:15
Jag har nu kopplat in en servo på kretsen samt skrivit en C# program för att kontrollera dess position. Det fungerar... halvbra. Nog för att det funkar som det ska för det mesta, men väldigt ofta blir det störningar på datalinjen. Det första jag gjorde var att implementera mjukvarustyrt dataflöde (XON/XOFF). Det hjälpte lite men det är fortfarande många bytes som läses in helt fel på PIC'en. Jag trodde att det berodde på den ostabila strömförsörjningen (mina LED's dimmar så fort servo rör sig) och försökte sätta dit kondingar lite här o där (det fungerade ju tidigare
). Det hjälpte inte. Jag testade sen att koppla ur servon, men data blev fortfarande korrupt. Jag vet inte riktigt vad jag skall prova med nu.
Koden som ligger o kör på PIC'en (CC5X):
(Hemskt ful, jag vet
)
Edit: Jag kan ju tillägga att hittills har jag aldrig sett några fel i datan som skickas från PIC'en till PC'n. Bara den andra vägen.

Koden som ligger o kör på PIC'en (CC5X):
(Hemskt ful, jag vet

Kod: Markera allt
//***************************************************************************************
// Config
//***************************************************************************************
#pragma chip PIC16F877A
// Used in Stdio.c
#define Clock_4MHz
//***************************************************************************************
// Constants
//***************************************************************************************
#define DEBUG_LED PORTB.1
#define SERVO_PIN PORTB.2
#define LONG_DELAY 0
#define LONG_DELAY_CNT 9
#define OFFSET_DELAY -0x40
//-157
#define LONG_DELAY_STATE 0
#define OFFSET_DELAY_STATE 1
#define POSITION_DELAY_STATE 2
#define CMD_RESET 0x00
#define CMD_SET_SERVO 0xdf
#define XON 0x11
#define XOFF 0x13
//***************************************************************************************
// Variables
//***************************************************************************************
uns8 servoState;
uns8 servoDelay;
uns8 longDelayCnt;
//***************************************************************************************
// Interrupt Service Routine
//***************************************************************************************
#include <int16CXX.h>
#pragma origin 4
interrupt int_server( void)
{
int_save_registers // W, STATUS (and PCLATH)
if (T0IF)
{
// Long delay just ended
if (servoState == LONG_DELAY_STATE)
{
if (--longDelayCnt == 0)
{
servoState = OFFSET_DELAY_STATE;
TMR0 = OFFSET_DELAY;
SERVO_PIN = 1;
}
}
else if (servoState == OFFSET_DELAY_STATE)
{
servoState = POSITION_DELAY_STATE;
TMR0 = servoDelay;
}
else
{
servoState = LONG_DELAY_STATE;
longDelayCnt = LONG_DELAY_CNT;
TMR0 = LONG_DELAY;
SERVO_PIN = 0;
}
T0IF = 0; /* reset flag */
}
int_restore_registers // W, STATUS (and PCLATH)
}
//***************************************************************************************
// Headers
//***************************************************************************************
#include <Stdio.c>
//***************************************************************************************
// Function Declarations
//***************************************************************************************
void delay();
//***************************************************************************************
// Application Entry Point
//***************************************************************************************
void OnSetServo(uns8 param)
{
servoDelay = 255 - param;
printf("Servo position: %h\n", param);
}
void init()
{
PORTC = 0b.0000.0000;
TRISC = 0b.1000.0000; //0 = Output, 1 = Input RC7 - Incoming Data RX
TRISB = 0b.0000.0000;
SPBRG = 25; //4MHz for 9600 baud rate
TXSTA = 0b.0010.0100; //8-bit asych mode, high speed uart enabled
RCSTA = 0b.1001.0000; //Serial port enable, 8-bit asych continous receive mode
OPTION = 0b.0000.0010; /* prescaler divide by 128 */
T0IE = 1; /* enable TMR0 interrupt */
GIE = 1;
servoState = LONG_DELAY_STATE;
longDelayCnt = LONG_DELAY_CNT;
TMR0 = LONG_DELAY;
// PWM period of ~20ms
//ADCON2 = 0x06;
/*
T2CON = 0b.0000.0111;
TMR2 = 0;
PR2 = 75;
CCP2CON = 0b.0000.1100;
*/
// Duty cycle defaults to 5/256%
//CCPR2L = 8;
DEBUG_LED = 1;
}
void main()
{
init();
putc(XOFF);
uns8 command;
uns8 param;
bit waitingForCommand = 1;
while(1)
{
// Make sure there is no errors halting reception
CREN = 0;
CREN = 1;
if (waitingForCommand)
{
putc(XON);
command = getc();
putc(XOFF);
waitingForCommand = 0;
if (command == CMD_RESET)
{
// Reset is sent 3 times. Just keep looking for commands.
waitingForCommand = 1;
}
else if (command == CMD_SET_SERVO)
continue;
// If the program runs to this position the command was invalid. Continue to wait for a valid one.
waitingForCommand = 1;
printf("Unknown command: %h\n", command); //Print what you typed
}
else
{
putc(XON);
param = getc();
putc(XOFF);
waitingForCommand = 1;
if (command == CMD_SET_SERVO)
OnSetServo(param);
}
}
}
void delay()
{
uns8 a, b, c;
for (a = 0; a < 1; a++)
for (b = 0; b < 255; b++)
for (c = 0; c < 255; c++);
}