A continuación el siguiente programa mostrara una manera sencilla de controlar un servomotor con ayuda de un potenciometro y el uso de los timers 0 y 1.
DESCRIPCIÓN:
El timer0 realizara una interrupción cada 32,7 ms aproximadamente para lo cual se utilizo el timer en modo normal con lo cual realizara la lectura del canal 0 del ADC y el resultado de la conversión la almacenara en OCR1A con lo que el servo motor cambiara de posición así como su velocidad. El timer1 esta configurado para que el pin PB1 controle al servomotor proporcionando una frecuencia de 50Hz y un ancho de pulso variable determinado por el potenciometro.
/*
* servo_timer1.c
*
* Created: 30/10/2013 14:23:13
* Author: NEBURESS.KYLL
*/
#include <avr/io.h>
#ifndef F_CPU
#define F_CPU 8000000UL // XTAL de 8 MHz
#endif
#include <avr/interrupt.h>
#define bitclear(sfr,bit) (_SFR_BYTE(sfr)&=~(_BV(bit)))
#define bitset(sfr,bit) (_SFR_BYTE(sfr) |= (_BV(bit)))
#define togglebit(sfr,bit) (_SFR_BYTE(sfr)^=(_BV(bit)))
unsigned char SERVO_VEL(){
//LEER
bitset(ADCSRA,ADSC);
while(!(ADCSRA&&(1<<ADIF))){}
return ADCH;
}
//interrupción cada 32.7ms
ISR(TIMER0_OVF_vect)
{
//MUEVE MOTOR
OCR1A=SERVO_VEL();
}
//inicializacion del timer0
void initimer0(){
//PREESCALAMIENTO 1024
bitset(TCCR0B,CS02);
bitclear(TCCR0B,CS01);
bitset(TCCR0B,CS00);
//MODO NORMAL
bitclear(TCCR0B,WGM02);
bitclear(TCCR0A,WGM01);
bitclear(TCCR0A,WGM00);
TCNT0=0;
}
//habilitación de la interrupción del timer0 en modo normal
void interrupcion(){
bitset(TIMSK0,TOIE0);
sei();
}
//habilitación de fast pwm para control de servomotor
void PWM(){
//SALIDA NO INVERTIDA FAST PWM
bitset(TCCR1A,COM1A1);
//FAST PWM
bitset(TCCR1B,WGM13);
bitset(TCCR1B,WGM12);
bitset(TCCR1A,WGM11);
//PREESCALER 64
bitset(TCCR1B,CS11);
bitset(TCCR1B,CS10);
ICR1=2499;
}
//habilitación de canal 0 del ADC
void INITADC(){
//FUENTE DE VOLTAJE
bitclear(ADMUX,REFS1);
bitset(ADMUX,REFS0);
//CANAL 0
bitclear(ADMUX,MUX3);
bitclear(ADMUX,MUX2);
bitclear(ADMUX,MUX1);
bitclear(ADMUX,MUX0);
//JUSTIFICADO A LA DERECHA
bitset(ADMUX,ADLAR);
//PREESCALER DE 64
bitset(ADCSRA,ADPS2);
bitset(ADCSRA,ADPS1);
//HABILITAR ADC
bitset(ADCSRA,ADEN);
}
int main(void)
{
bitset(DDRB,DDB1);
interrupcion();
initimer0();
INITADC();
PWM();
while(1)
{
}
}
LINK
https://mega.co.nz/#!818nmTRC!dfNNvToziWGWHdZaeFjG4AhruecWmCZxs2PDdyVcDDQ
No hay comentarios:
Publicar un comentario