Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola
Hace unos días me he liado con la programación de los dsPIC, los cuales nunca antes había usado. Ya he conseguido hacer algunos programas y los veo ideales para el uso en robótica, ya que algunos de ellos están pensados para control de motores. Como ejemplo, el dsPIC30F2010 dispone de 6 salidas PWM (3 totalmente independientes), UART, I2C, disponen de reloj con multiplicador de frecuencia (con un cristal de 10Mhz realizan 20Millones de instrucciones por segundo, teniendo en cuenta que un PIC normal a 20MHz de cristal realiza 5mips). El puerto serie tiene buffer FIFO por hardware. Este pic puede manejar 3 motores de forma simultánea, y dispone de multitud de interrupciones. Es de 16 bits y tiene una unidad de DSP, y tiene unas instrucciones para cálculo matemático impresionantes. Todo eso con un encapsulado de 28 pin.
Si alguien lo usa, podemos intercambiar impresiones.
Saludos.
Vale, pues pego aquí lo que estuve probando. Como ya dije antes, no está limpio ni bonito porque lo estuve utilizando para aprender a manejar estos módulos y no hice luego nada con él.
Espero que sea de utilidad a alguien.#define __dsPIC30F4011__
#include <p30f4011>
#include<pwm>
#include<outcompare>
#include<timer>
#include <incap>
_FOSC( CSW_FSCM_OFF & XT_PLL16);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & PWRT_OFF & MCLR_DIS);
/*
#define FCY 32000000 // 20 MIPS
#define FPWM 20000 // 20 kHz
#define DEADTIME (unsigned int)(0.000002 * FCY)
#define _DES_FREQ 60 // 60 Hz sine wave is required
#define _DELTA_PHASE (unsigned int)(_DES_FREQ * 65536 / FPWM)
*/
#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");
/* asm("nop");asm("nop");
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);
};
}
Hola me pueden ayudar con el DSpic 30F4011, pero no tengo nada de experiencia con esto. lo voy a utilizar para mover un motor tengo que utilizar modulo CCP para generar PWM......ayuda porfavor
Yo estoy esperando para migrar a DSPic, hasta que este "disponible" en la mula el ultimo compilador de CCS, es muy reciente salio el 24 de julio la primera versión con soporte para micros Dsp y 24bits, que seguro viene con algunos bugs, si alguien tiene alguna noticia , el nombre de la version es PCD, es por linea de comandos, es un plug-ing para el IDE anterior y PCWHD la que incluye un ide nuevo.
Hola me pueden ayudar con el DSpic 30F4011, pero no tengo nada de experiencia con esto. lo voy a utilizar para mover un motor tengo que utilizar modulo CCP para generar PWM......ayuda porfavor
Dos post más arriba tienes un ejemplo para ese mismo micro
Nocturno, nocturno, tendras mas ejemplos para el dspic30f4011....es que no tengo ni la mas minima idea de como programarlo