⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 复件 mocontrol.c

📁 一个步进电机的驱动C程序
💻 C
字号:
// 目标器件: STC89C58RD+
// 系统频率: 晶振 12 M, 烧写时设置单倍速
// 硬件电路过0检测偏慢约 256 us.
// 针对 220V,50HZ.系统设计.
// 可控硅门极脉冲宽度固定为 100 us.导通角以100 us步进.

#include <STC89C58.H>
#include <intrins.h>


sbit	Drive	=	P3^7;
sbit	LED		=	P3^5;	// LED 低电平驱动.

#define uint 	unsigned int
#define uchar 	unsigned char


#define DogReset() 		WDT_CONTR=0x36


#define	vBtnVal_Null		0xF0	// ceeback/20070316
#define	vBtnVal_StartUp		0xF1	//起停
#define	vBtnVal_HiSpeed		0xF2	//高速
#define	vBtnVal_MiSpeed		0xF4	//中速
#define	vBtnVal_LoSpeed		0xF8	//低速
//#define	vBtnVal_Reverse		0x10	//反向

#define	vBtnAct_Null		0
#define	vBtnAct_Push		1
#define	vBtnAct_Pop			2
#define	vBtnAct_Keep		3


// T0 定时 10ms.作为系统计时用,
#define	vT01S				100		// 1 s = 10 ms * 100
#define	vT0HVal				0XD8
#define	vT0LVal				0XF0

#define ACTIVE_TIME			900		// 按键有效持续时间 900 

#define	WaitSpeed			0
#define	HiSpeed				1
#define	MiSpeed				2
#define	LoSpeed				3


uchar	cBtnVal;			// 按钮取值
uchar	SpeedType;

uint temp;

// 定时器延时
uchar	cT01s	= vT01S;
uint	cDY_Clock;			// 时钟修改超时计时

//bit		Drive_bit  = 0;
//bit		Triger_bit = 0;		// 外部触发标志 ceeback/ 20070316
bit		b_Power;				// 电机起停标志
	#define 	STOP 	1
	#define		WORK	0
	#define 	PNP_OFF	1
	#define 	PNP_ON	0
	
uchar   open_delay_100us=0;
uint  	scr_delay_time;
uchar 	t1_int_type;	// t1 中断类型
	#define NEG_ZERO_COMPENSATE	0XFF	// 负半周过0点补偿
	#define NEG_SCR_DELAY_TIME	0XFE	// 负半周可控硅开启相对过0点延迟时间.
	#define NEG_SCR_HOLD_TIME	0XFD	// 负半周可控硅门极脉冲维持时间
	#define WAIT_POSITIVE		0XFC	// 等待正半周到达.
	#define POS_ZERO_COMPENSATE	0XFB	// 正半周过0点补偿
	#define POS_SCR_DELAY_TIME	0XFA	// 正半周可控硅开启相对过0点延迟时间.
	#define POS_SCR_HOLD_TIME	0XF9	// 正半周可控硅门极脉冲维持时间



// 定时器1延时时间宏.
#define T1_DELAY_500uS_H	0XFE
#define T1_DELAY_500uS_L	0X0C

#define T1_DELAY_500uS		0XFE0C
#define T1_DELAY_100uS		0XFF9C
#define T1_DELAY_1MS		0XFC18
#define T1_DELAY_2MS		0XF830
#define T1_DELAY_2D5MS		0XF63c	// 2.5ms
#define T1_DELAY_3MS		0XF448
#define T1_DELAY_4MS		0XF060
#define T1_DELAY_5MS		0XEC78
#define T1_DELAY_6MS		0XE890
#define T1_DELAY_7MS		0XEA48

//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------

void Para_initial(void);


/**************************************************************************
*    函数原型: void delay_ms(uint Count)
*    功    能: 延时Count个ms
**************************************************************************/
void delay_ms(register uint Count)
{
	register uchar T;

	for(;Count>0;Count--)
	{
		for(T=0;T<80;T++)
		{
			_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
			_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
		}
		DogReset();
	}
}


/**************************************************************************
*    函数原型: uchar ButtonScan(void);
*    功    能: 对按钮进行扫描,返回按钮值
**************************************************************************/
uchar key_scan(void)
{
	register uchar temp;
	
	P1   = 0XFF;
	temp = P1;
	temp &= 0x0f;
	temp =~ temp;
	
	return(temp);
}


/**************************************************************************
*    函数原型: uchar ButtonAction(void);
*    功    能: 按钮动作类型
	 返 回 值: 当按钮为空,  返回值为vBtnType_Null=0
	 		   当按钮按下时,返回值为vBtnType_Push=1
	           当按钮弹起时,按回值为vBtnType_Pop =2
	           当按钮长按时,返回值为vBtnType_Keep=3
	           当按钮同时按下时,返回值为vBtnVal_All=0x30
*************************************************************************/
uchar ButtonAction(void)
{
	uchar cButton;

	cButton=key_scan();
	if(cButton==cBtnVal)
	{
		if(cButton==vBtnVal_Null)	// 无按键
			return(vBtnAct_Null);
		
		else	// 按键保持
			return(vBtnAct_Keep);
	}
	else
	{
		delay_ms(20);
		if(key_scan()==cButton)
		{	
			//cBtnValPre=cBtnVal;
			cBtnVal=cButton;
			
			if(cButton==vBtnVal_Null)	// 按键弹起
				return(vBtnAct_Pop);
			else						// 按键按下
				return(vBtnAct_Push);
		}
	}
}

/**************************************************************************
*    函数原型: void ButtonHandle(void);
*    功    能: 处理按钮输入
**************************************************************************/
void ButtonHandle(void)
{
	uchar cBtnType;
	
	DogReset();
	cBtnType=ButtonAction();
	if(cBtnType==vBtnAct_Push)
	{
		switch(cBtnVal)
		{
			case vBtnVal_StartUp:
				b_Power=!b_Power;
				LED = b_Power;	// 驱动LED.
				if(b_Power==STOP)
					Para_initial();
				else	// ceeback added 2007.03.16
				{
					//b_Power		= 	WORK;
					SpeedType	=	WaitSpeed;
					cDY_Clock	=	ACTIVE_TIME;
				}
				break;
				
			case vBtnVal_HiSpeed:
				if(b_Power == WORK)
				{
					SpeedType	=	HiSpeed;
					TR1         = 0;	// 一直导通.
					Drive       = PNP_ON;
					cDY_Clock	= ACTIVE_TIME;
				}
				break;
				
			case vBtnVal_MiSpeed:
				if(b_Power == WORK)
				{
					SpeedType	=	MiSpeed;
					open_delay_100us ++;
					if(open_delay_100us>=81)
						open_delay_100us = 81;
					//open_delay_100us = 30;
					scr_delay_time = 0xFFFF - 0x64 * open_delay_100us;	// 延时以 100 us 步进.
					cDY_Clock=ACTIVE_TIME;
				}
				break;
				
			case vBtnVal_LoSpeed:
				if(b_Power == WORK)
				{
					SpeedType	=	LoSpeed;
					open_delay_100us = 55;
					scr_delay_time = 0xFFFF - 0x64 * open_delay_100us;
					//scr_delay_time = 0xe890;
					//scr_delay_time = T1_DELAY_7MS;
					cDY_Clock=ACTIVE_TIME;
				}
				break;
			default:break;
		}
	}
	DogReset();
}

/**************************************************************************
*    函数原型: void speed_control(void);
*    功    能: 处理按钮输入
**************************************************************************/
void speed_control(void) /*reentrant*/
{
	if(b_Power== WORK)
	{
		switch(SpeedType)
		{
			//case HiSpeed:	// 高速
			//	Drive = PNP_OFF;
			//	TH1= T1_DELAY_1MS_H;
			//	TL1= T1_DELAY_1MS_L;
			//	TR1 		= 1;
			//	Triger_bit 	= 1;
			//	break;
			
			/*case HiSpeed:	// 高速,一直导通.
				TR1 = 0;
				Drive = PNP_ON;
				break;*/
			case MiSpeed:
				Drive = PNP_OFF;
				TH1 = T1_DELAY_500uS_H;
				TL1 = T1_DELAY_500uS_L;
				TR1 		= 1;
				t1_int_type = NEG_ZERO_COMPENSATE;
				break;
			case LoSpeed:
				Drive = PNP_OFF;
				TH1 = T1_DELAY_500uS_H;
				TL1 = T1_DELAY_500uS_L;
				TR1 		= 1;
				t1_int_type = NEG_ZERO_COMPENSATE;
				break;
			default:break;
		}
		/*TH1 = T1_DELAY_300uS_H;
		TL1 = T1_DELAY_300uS_L;
		TR1 = 1;
		Drive = PNP_OFF;
		t1_int_type = ZERO_COMPENSATE;*/
	}
}

/**************************************************************************
*    函数原型: void Para_initial(void);
*    功    能: 处理按钮输入
**************************************************************************/
void Para_initial(void)
{
	Drive		=	PNP_OFF;
	TR1 		=   0;
	b_Power		= 	STOP;
	LED 		= 	b_Power;	// 低电平驱动LED.
	SpeedType	=	WaitSpeed;

	t1_int_type =  0X00;
	cDY_Clock  = 0xffff;
	open_delay_100us   = 0;
}


/**************************************************************************
*    函数原型: void system_initial(void);
*    功    能: 处理按钮输入
**************************************************************************/
void system_initial(void)
{
	DogReset(); // 已针对 STC89C58RD+ 作修改.06-04-06
    SCON=0x50;
    TMOD=0x11; 	// T1,T0:Time 16bit
    TCON=0x15; 	// TR0=1,外部中断0,1都是下降沿触发
    //TH1=0xfd;	// T1 的初值根据延时要求不同而改变,在外部中断中设置.
    //TL1=0xfd;
    TH0=vT0HVal;
    TL0=vT0LVal;  
    IP=0x08; 		// T1 优先级高
    //AUXR=0x02;//ALE为1/6FOSC,外部XRAM
    
    Para_initial();
    IE=0x8F; // 开外部0,1,T0,T1中断
    EX0=0;	// 关闭外部中断0. 2007.03.19
}

/**************************************************************************
*    函数原型: void main(void);
*    功    能: 处理按钮输入
**************************************************************************/
void main(void)
{
	 system_initial();

	 while(1) 
	 {
	 	DogReset();

	 	ButtonHandle();
		if(!cDY_Clock)
			Para_initial();
	 }
}

/**************************************************************************
*    函数原型: void Trint0(void) interrupt 1 using 1;
*    功    能: 全局定时
**************************************************************************/
void T0_INT(void) interrupt 1 //using 1
{	
	TH0	=	vT0HVal;	// 时基10ms
	TL0	=	vT0LVal;

	if(!(--cT01s))
	{
		cT01s=vT01S;
		if(b_Power == WORK)	// 时钟模式的空闲等待时间
		{					
			if(cDY_Clock > 0x00)
				--cDY_Clock;
		}
	}
}


void T1_INT(void) interrupt 3 //using 1
{
	
	switch(t1_int_type)
	{
		case NEG_ZERO_COMPENSATE:	// 零点补偿完毕,接着应该进行开启可控硅之前的延时.
			Drive = PNP_OFF;
			TH1 = (uchar)(scr_delay_time>>8);
			TL1 = (uchar)(scr_delay_time);
			t1_int_type = NEG_SCR_DELAY_TIME;
			TR1 = 1;
			break;
			
		case NEG_SCR_DELAY_TIME:	// 开启之前的延时完毕后,就要开启可控硅.
			Drive = PNP_ON;
			TH1 = (uchar)(T1_DELAY_1MS>>8);	// 可控硅固定开启时间 100 us.
			TL1 = (uchar)T1_DELAY_1MS;
			t1_int_type = NEG_SCR_HOLD_TIME;
			TR1 = 1;
			break;
			
		case NEG_SCR_HOLD_TIME:		// 延时到正半周起始点.
			Drive = PNP_OFF;
			temp  = 0xD954 + open_delay_100us * 0x64+ 0X64*10;
			TH1 = (uchar)(temp>>8);
			TL1 = (uchar)(temp);
			t1_int_type = WAIT_POSITIVE;
			TR1 = 1;
			break;
			
		case WAIT_POSITIVE:
			Drive = PNP_OFF;
			TH1 = (uchar)(scr_delay_time>>8);
			TL1 = (uchar)(scr_delay_time);
			t1_int_type = POS_SCR_DELAY_TIME;
			TR1 = 1;
			break;
			
		case POS_SCR_DELAY_TIME:	// 开启之前的延时完毕后,就要开启可控硅.
			Drive = PNP_ON;
			TH1 = (uchar)(T1_DELAY_1MS>>8);	// 可控硅固定开启时间 100uS.
			TL1 = (uchar)T1_DELAY_1MS;
			t1_int_type = POS_SCR_HOLD_TIME;
			TR1 = 1;
			break;
			
		case POS_SCR_HOLD_TIME:		//	关闭t1,等待下次外部中断时再启动T1.
			Drive = PNP_OFF;
			TR1 = 0;
			t1_int_type = 0X55;
			break;
		default:break;
	}
}


/**************************************************************************
*    函数原型: void int0(void) interrupt 0 using 0;
*    功    能: 全局定时
**************************************************************************/
void int0(void) interrupt 0 //using 0
{
	//speed_control();
}

/**************************************************************************
*    函数原型: void int0(void) interrupt 2 using 2;
*    功    能: 全局定时
**************************************************************************/

void int1(void) interrupt 2 //using 2
{
	if(b_Power== WORK)
	{
		switch(SpeedType)
		{
			case MiSpeed:
				/*Drive = PNP_OFF;
				TH1 = T1_DELAY_500uS_H;
				TL1 = T1_DELAY_500uS_L;
				TR1 		= 1;
				t1_int_type = NEG_ZERO_COMPENSATE;
				break;*/
			case LoSpeed:
				Drive = PNP_OFF;
				TH1 = T1_DELAY_500uS_H;
				TL1 = T1_DELAY_500uS_L;
				TR1 		= 1;
				t1_int_type = NEG_ZERO_COMPENSATE;
				break;
			default:break;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -