这里共享一下,我本人做的 有刷电机调速控制 开源代码!不要用于商业!仅供学习!
(主要用于模型飞机固定控制)
//qq:122579167
#ifndef
_MAIN_H_
#define
_MAIN_H_
#include
<htc.h>
__CONFIG(INTIO
&
WDTEN
&
PWRTEN
&
MCLREN
&
BOREN
&
PROTECT
&
CPD);
#define
TMR1_RELOAD(V) (TMR1L
= (V),TMR1H
= ((V)>>8))
#define
TMR1_STOP() (TMR1ON
=
0)
#define
TMR1_START() (TMR1ON
=
1)
#define
IS_PPM_INV
0
#define
IS_OUT_INV
0
#define
VBATT_PROTECT
1
#define
MOTOR_OUT
GPIO2
#define
PPM_IN
GPIO5
#define
ON (!IS_OUT_INV)
#define
OFF (IS_OUT_INV)
#define
MOTOR_ON() (MOTOR_OUT
=
ON)
#define
MOTOR_OFF() (MOTOR_OUT
=
OFF)
#define
IS_MOTOR_ON() (MOTOR_OUT
==
ON)
#define
IS_MOTOR_OFF() (MOTOR_OUT
==
OFF)
#define
INSTALL_MEASURE_TIMER() do{\
TMR1_RELOAD(0);\
TMR1_START();\
}while(0)
#define
STOP_MEASURE_TIMER() (TMR1_STOP())
#define
GET_TIMER_VALUE() ((TMR1H<<8) |
TMR1L)
#define
T1200US (1200)
#define
T800US (800)
#define
T2500US (2500)
#endif
#include
"main.h"
volatile
unsigned
char
g_width
=
0;
volatile
unsigned
int
g_startWidth=
0;
//
//.error start position
//
static
void
ErrorHint(void)
{
unsigned
char
j,k;
for(j=0;
j<100;
j++)
{
MOTOR_ON();
TMR1_RELOAD(65535-20);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
MOTOR_OFF();
TMR1_RELOAD(65535-700);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
}
for(k=0;
k<3;
k++)
{
TMR1_RELOAD(0);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
}
MOTOR_OFF();
}
//
//.DC MOTOR STANDBY (SHOW MOTOR CAN BE CONTROL BY PPM SIGNAL)
// (TONE 1.5KHZ)
//
static
void
ReadyHint(void)
{
unsigned
char
i,j,k;
for(i=0;
i<3;
i++)
{
for(j=0;
j<100;
j++)
{
MOTOR_ON();
TMR1_RELOAD(65535-30);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
MOTOR_OFF();
TMR1_RELOAD(65535-800);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
}
for(k=0;
k<6;
k++)
{
TMR1_RELOAD(0);
TMR1_START();
TMR1IF
=
0;
while(!TMR1IF)
CLRWDT();
}
}
MOTOR_OFF();
}
//
//.wait ppm signal
//.get start position
//
static
void
WaitRunCondition(void)
{
unsigned
char
ppmConfirm
=
0;
GIE
=
0;
Wait:
#if
IS_PPM_INV
while(PPM_IN)
CLRWDT();
INSTALL_MEASURE_TIMER();
TMR1IF
=
0;
while(!PPM_IN)
CLRWDT();
STOP_MEASURE_TIMER();
g_startWidth
=
GET_TIMER_VALUE();
#else
while(!PPM_IN)
CLRWDT();
INSTALL_MEASURE_TIMER();
TMR1IF
=
0;
while(PPM_IN)
CLRWDT();
STOP_MEASURE_TIMER();
g_startWidth
=
GET_TIMER_VALUE();
#endif
if((TMR1IF)||(g_startWidth
>
T1200US))
{
ErrorHint();
ppmConfirm
=
0;
goto
Wait;
}
if(g_startWidth
<
T800US)
{
ppmConfirm
=
0;
goto
Wait;
}
if(++ppmConfirm
<
3)
goto
Wait;
g_startWidth
+=
40;
ReadyHint();
GPIF
=
0;
PIR1
=
0x00;
GIE
=
1;
}
//
//.measure ppm width
//
static
void
MeasurePPMWidth (void)
{
unsigned
int
ppmWidth;
#if
IS_PPM_INV
while(PPM_IN)
CLRWDT();
TMR1_RELOAD(0);
while(!PPM_IN)
CLRWDT();
TMR1_STOP();
ppmWidth
= (TMR1H<<8)|TMR1L;
TMR1_START();
#else
while(!PPM_IN)
CLRWDT();
TMR1_RELOAD(0);
while(PPM_IN)
CLRWDT();
TMR1_STOP();
ppmWidth
= (TMR1H<<8)|TMR1L;
TMR1_START();
#endif
if((ppmWidth
<
T2500US) && (ppmWidth
>
T800US))
{
if(ppmWidth
<=
g_startWidth)
{
ppmWidth
=
0;
}
else
{
ppmWidth
= (unsigned
long)(ppmWidth-g_startWidth)*255/1000;
if(ppmWidth
>
255 )
ppmWidth
=
255;
}
g_width
=
ppmWidth;
}
}
//
//.GP0(PPM) Digital Input GP1(Battery referance voltage input) GP2 ESC output
// GP3(POWER UP RESET INPUT) GP4,5 no used!
//.CVREF=2.49V (Battery voltage < 7v (2.7k/(5.1k+2.7k)RR NETWORK))
//.TIMER0 use for ESC
//
static
void
InitDevice(void)
{
OSCCAL
=
__osccal_val();
GPIO
=
0B11111111;
TRISIO
=
0B00101011;
MOTOR_OFF();
IOCB
=
0B00000000;
CMCON
=
0B01000100;
VRCON
=
0B10101100;
WPU
=
0B00110101;
OPTION
=
0B00000001;
T1CON
=
0B00000000;
PIE1
=
0B00000000;
INTCON
=
0B01101000;//
}
//
//application entry-point function
//
void
main(void)
{
InitDevice();
WaitRunCondition();
for(;;)
{
MeasurePPMWidth();
}
}
//
// .DC MOTOR SPEED CONTROL (ESC)
// .PPM TIMEOUT CHECK
// .BATTERY VOLTAGE MONITOR
//
static
void
interrupt
InterruptHandle (void)
{
//ppm signal time out
if(TMR1IF)
{
TMR1IF
=
0;
g_width
=
0;
MOTOR_OFF();
return;
}
//DC MOTOR Speed Control
T0IF
=
0;
if(g_width
<
10)
{
MOTOR_OFF();
TMR0
=
0;
goto
nextInt;
}
if(g_width
>
230)
{
MOTOR_ON();
TMR0
=
0;
goto
nextInt;
}
if(IS_MOTOR_OFF())
{
TMR0
=
255
-
g_width;
MOTOR_ON();
}
else
{
TMR0
=
g_width;
MOTOR_OFF();
}
//Battery voltage monitor
nextInt:
if(CMIF)
{
CMIF
=
0;
if(COUT)
{
#if
VBATT_PROTECT
MOTOR_OFF();
while(1)
CLRWDT();
#endif
}
}
}
//end files