#define __dsPIC30F4011__
#include <p30f4011.h>
#include<pwm.h>
#include<outcompare.h>
#include<timer.h>
#include <incap.h>
_FOSC( CSW_FSCM_OFF & XT_PLL16);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & PWRT_OFF & MCLR_DIS);
#define LED PORTEbits.RE0
#define MOT1_ENABLE PORTEbits.RE1 // activado = 1, desactivado = 0
#define MOT2_ENABLE PORTEbits.RE2 // activado = 1, desactivado = 0
// Calibrado para FUTABA S-3003
#define DutyMinimo 1000
#define DutyMaximo 6000
#define PeriodoPWM 0x200 // 50Hz
// Frecuencia = MIPS / ( (period+1) * PRESCALER)
// Frecuencia = 20.000.000 / (25.000 * 16) = 50
int Interrupt_Count = 0 , Int_flag, count;
unsigned int timer_first_edge, timer_second_edge;
int i;
/********************************************************/
void DelayUs(unsigned int v) { // pierde 8+2
/********************************************************/
while(v != 0){
asm("nop");asm("nop");
asm("nop");asm("nop");
asm("nop");asm("nop");
asm("nop");asm("nop");
asm("nop");asm("nop");
v--;
}
}
/******************************************************/
void DelayMs(unsigned int v) {
/******************************************************/
while (v != 0 ){ DelayUs(1000); v--;}
}
int PWM1(int Duty) // Módulo Output Compare Module
{
T3CON = 0x8010;// activamos Timer3 con prescaler = 8
PR3 = 0xC34F ; // frecuencia = 1 / ((PR3+1) * PRESCALER * MIPS)
// PR3 = MIPS / (Frecuencia * PRESCALER ) - 1
// PR3 = 20000000 / ( 50Hz * 8 ) - 1 = 49999 = C34F
OpenOC1 (OC_IDLE_CON & OC_TIMER3_SRC & OC_PWM_FAULT_PIN_DISABLE, 0, 0);
SetDCOC1PWM (Duty);
}
int Servo1(int Grados)
{
int Duty;
T3CON = 0x8010;// activamos Timer3 con prescaler = 8
PR3 = 0xC34F ; // frecuencia = 1 / ((PR3+1) * PRESCALER * MIPS)
// PR3 = MIPS / (Frecuencia * PRESCALER ) - 1
// PR3 = 20000000 / ( 50Hz * 8 ) - 1 = 49999 = C34F
OpenOC1 (OC_IDLE_CON & OC_TIMER3_SRC & OC_PWM_FAULT_PIN_DISABLE, 0, 0);
Duty = (DutyMaximo-DutyMinimo)/180*Grados+DutyMinimo;
SetDCOC1PWM (Duty);
}
void InicializaPWM () // Módulo de control de motores
{
unsigned int period;
unsigned int sptime;
unsigned int config1;
unsigned int config2;
unsigned int config3;
period = PeriodoPWM;
sptime = 0x0;
config1 = (PWM_EN & PWM_OP_SCALE1 & PWM_IPCLK_SCALE1 & PWM_MOD_FREE);
config2 = (PWM_MOD3_IND & PWM_PEN3H & PWM_PDIS2H & PWM_PDIS1H & PWM_PEN3L & PWM_PDIS2L & PWM_PDIS1L);
config3 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN);
OpenMCPWM(period,sptime,config1,config2,config3);
PTCON = PTCON & 0xFF03;
}
void Duty (int Canal, int Porcentaje)
{
unsigned int dutycyclereg;
unsigned int dutycycle;
unsigned char updatedisable;
dutycyclereg = Canal;
// el Duty tiene un bit más que el periodo, y se rota una vez a la izquierda
dutycycle = ((int)((long)Porcentaje * (long) PeriodoPWM / (long)100)) << 1;
updatedisable = 0;
SetDCMCPWM(dutycyclereg,dutycycle,updatedisable);
}
void Motor (int Canal, int Sentido, int Potencia)
// Canal: 1 o 2, motor izquierdo o motor derecho
// Sentido: 0 o 1, adelante o atrás
// Potencia: de 0 a 100
{
if (Canal==2)
if (Sentido==0)
PORTF= (PORTF & 0xFC) | 0x02;
else
PORTF= (PORTF & 0xFC) | 0x01;
if (Canal==1)
if (Sentido==0)
PORTF= (PORTF & 0xCF) | 0x20;
else
PORTF= (PORTF & 0xCF) | 0x10;
Duty (Canal, Potencia);
}
int main()
{
int i, Porcentaje;
InicializaPWM();
Duty (3,50);
while (1);
for (i=1;i<100;i=i+10)
{
Porcentaje = i * PeriodoPWM / 100;
Duty (3,Porcentaje );
DelayMs(1000);
};
}