Microchip PIC单片机论坛MICROCHIP 单片机应用专区MICROCHIP 8位单片机应用 → [原创] 有刷电机调速控制!


  共有775人关注过本帖树形打印

主题:[原创] 有刷电机调速控制!

帅哥哟,离线,有人找我吗?
cyberjok
  1楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:45 积分:220 威望:0 精华:0 注册:2010-2-23 9:32:00
[原创] 有刷电机调速控制!  发贴心情 Post By:2010-2-28 11:11:00

这里共享一下,我本人做的 有刷电机调速控制 开源代码!不要用于商业!仅供学习!

(主要用于模型飞机固定控制)

//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

 

 


支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
cyberjok
  2楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:45 积分:220 威望:0 精华:0 注册:2010-2-23 9:32:00
  发贴心情 Post By:2010-2-28 11:12:00

预览都不会显示这样的,晕啊1

支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
dianxinwuban
  3楼 个性首页 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:74 积分:265 威望:0 精华:0 注册:2009-10-28 9:10:00
  发贴心情 Post By:2010-3-1 10:56:00

呵呵 顶下



QQ:395180816,EMAIL:ben@1632bit.com,MSN:linjb180@hotmail.com
支持(0中立(0反对(0回到顶部
客人(116.205.*.*)
  4楼


  发贴心情 Post By:2010-3-1 19:33:00

这个是不是跟论坛有关啊,为什么会显示乱乱的??

支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
cyberjok
  5楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:45 积分:220 威望:0 精华:0 注册:2010-2-23 9:32:00
  发贴心情 Post By:2010-3-1 19:34:00

为什么会这么样呢,显示这么乱?

支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
梦之
  6楼 个性首页 | QQ | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:62 积分:261 威望:0 精华:0 注册:2009-8-24 15:08:00
  发贴心情 Post By:2010-3-2 9:22:00

可以用上传附件的形式


支持(0中立(0反对(0回到顶部
帅哥哟,离线,有人找我吗?
cyberjok
  7楼 个性首页 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:版主 贴子:45 积分:220 威望:0 精华:0 注册:2010-2-23 9:32:00
  发贴心情 Post By:2010-3-4 22:24:00

直接贴出来就是为了看和学习,做了附件下载,多数人会下载了,然后丢到一边去....论坛代码要有所改进啊!


支持(0中立(0反对(0回到顶部