Simulacion de entradas analogicas

Hola, estoy intentando programar un PIC 16F876 para manejar tres servos con unos potenciometros mediante el convertidor AD. El caso es que la simulacion en PROTEUS me funciona, pero al montar el circuito fisico, conecto un solo potenciometro y un servo y si vario los otros pot. tambien me mueven el servo. ¿Alguien me podria decir que puedo modificar en el circuito para que me funcione buen?

Muchas gracias.
 

Adjuntos

  • Esquema entradas analogicas.jpg
    Esquema entradas analogicas.jpg
    53.2 KB · Visitas: 14
Última edición:
Perdon, como el codigo me funciona, crei que solo haria falta el esquema con los potenciometros.

/*
Manejo de varios servos con potenciometros.
El potenciometro se lee con el conversor AD.
El servo se maneja con pwm por software.

Entradas analogicas por RA0 y RA1

Uso como puerto de control del servo el RC0, RC1.
*/

#include <htc.h>
#include <stdlib.h>


__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & CP_OFF & LVP_OFF);

#define _XTAL_FREQ 4000000

/* Valores para hacer la señal PWM */
#define longitud_pulso 1000 // Longitud maxima del pulso 20 ms
#define pulso_angulo_minimo 46 // Valores minimo del pulso de mando (-90º)
#define pulso_angulo_medio 74 // medio (0º)
#define pulso_angulo_maximo 100 // maximo (+90º)
#define DIVISOR 21

unsigned int pulso0_alto = pulso_angulo_medio; // valor de pulso alto entre angulo minimo y maximo
unsigned int pulso1_alto = pulso_angulo_medio;

void main(void)
{
unsigned int valor_AD_0 = 0, valor_AD_1 = 0; // Para guardar el valor AN convertido
unsigned int servo0_alto = 0, servo0_bajo = 0;
unsigned int servo1_alto = 0, servo1_bajo = 0;

TRISC0 = 0; // En salida para el servo
TRISC1 = 0;
RC0 = 0;
RC1 = 0;

TRISA0 = 1; // El puerto que se va a usar como entrada analogica debe estar como entrada
TRISA1 = 1;

// Configuracion del CAD ------------------------------------------------------------
// Regisro ADCON1
ADFM = 1; // Formato de ADRES = 0000 00xx xxxx xxxx
ADCS2 = 0; // Como seleccionamos Oscilador RC interno, nos da igual 0 o 1
ADCON1 &= 0xF0; // Configuracion de los puertos. Todos en AN

// Registro ADCON0
// La seleccion del Canal la hacemos en el bucle lectura analogica

ADCS1 = 1; // Oscilador interno RC. Hay que tener en cuenta tb el valor de ADCS2 en ADCON1
ADCS0 = 1; // ADCON0 |= 0xE0


ADON = 1; // CAD activo
__delay_ms(15); // Para que se active el ADC
// Fin configuracion CAD ------------------------------------------------------------

while(1)
{
ADCON0 &= 0xC7; // Seleccion del canal 0
GO_DONE = 1; // Hacemos la conversion.
while (GO_DONE); // hasta que se termina.
valor_AD_0 = (ADRESH << 8)| ADRESL; // Leemos el valor convertido

pulso0_alto = valor_AD_0 / DIVISOR; // Manejamos el servo

servo0_alto = pulso_angulo_minimo + pulso0_alto;
servo0_bajo = longitud_pulso - servo0_alto;

__delay_ms(15);

ADCON0 = (ADCON0 |= 0x08) & 0xCF; // Seleccion del canal 1
GO_DONE = 1; // Hacemos la conversion.
while (GO_DONE); // hasta que se termina.
valor_AD_1 = (ADRESH << 8)| ADRESL; // Leemos el valor convertido

pulso1_alto = valor_AD_1 / DIVISOR; // Manejamos el servo

servo1_alto = pulso_angulo_minimo + pulso1_alto;
servo1_bajo = longitud_pulso - servo1_alto;

RC2 = ~RC2; // Damos señal al servo
while(servo0_alto--) // y temporizamos
__delay_us(1);

RC2 = ~RC2; // quitamos señal al servo
while(servo0_bajo--) // y temporizamos
__delay_us(1);

RC3 = ~RC3; // Damos señal al servo
while(servo1_alto--) // y temporizamos
__delay_us(1);

RC3 = ~RC3; // quitamos señal al servo
while(servo1_bajo--) // y temporizamos
__delay_us(1);
}
}
 
Atrás
Arriba