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

📄 2007.5.31.c

📁 一个步进电机的驱动C程序
💻 C
字号:
// 目标器件: STC12C5052AD
// 系统频率: 内部时钟,4~8M.

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



sbit	Beep	=	P1^5;//蜂鸣器
sbit	Relay1	=	P3^0;//继电器1
sbit	Pulse_Input	=	P3^3;//脉冲输入
//sbit	Relay2	=	P3^1;//继电器2
//sbit	STOP	=	P1^6;//接近开关复位信号
//sbit	RETC	=	P1^7;//接近开关电源控制

#define uint 	unsigned int
#define uchar 	unsigned char


#define DogReset() 			WDT_CONTR=0x36

#define SetDriveOff()		{PCA_PWM0=0X03;}	// 使驱动口固定输出高电平.
#define SetDriveOn()		{PCA_PWM0=0X00;}	// 使驱动口固定输出高电平.

#define	vBtnVal_Null		0x00	// ceeback/20070316
#define	vBtnVal_StartUp		0x01	//起停
#define	vBtnVal_HiSpeed		0x02	//高速
#define	vBtnVal_MiSpeed		0x04	//中速
#define	vBtnVal_LoSpeed		0x08	//低速
//#define	vBtnVal_Reverse		0x10	//反向

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


// T0 定时 0.1ms.作为系统计时用,
#define	vT01ms				10
#define	vT10ms				10
#define	vT100ms				10
#define	vT01S				10		// 1 s = 10 ms * 100
#define	vT1HVal				0xff	//0xfe	//0xf6
#define	vT1LVal				0x9c	//0x0c	//0x4c

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

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


#define 		STOP 		1
#define		WORK		0


uchar	KeyNum;
uchar	cBtnVal;			// 按钮取值
uchar	SpeedType;
uchar 	ctemp;
uchar	cSpeed;

//uchar PulseCount;			//脉冲计数
uchar 	Pre_pulselength;			//脉冲长度
uint 	Fact_pulselength;			//脉冲长度

//uint 	R_pulselength;		//读取脉冲长度

//uchar Pre_Pulse;				//预设每秒脉冲数
//uchar Fact_Pulse;				//实际每秒脉冲数

// 定时器延时
uchar	cT01ms		=	vT01ms;
uchar	cT10ms		=	vT10ms;
uchar	cT100ms		= 	vT100ms;
uchar	cT01s		= 	vT01S;
uchar	StopTimer;			//电机失速保护,在连续5秒超速,则判断MOS损坏,切断继电器
uchar	changeTimer;
uchar	cDY_Clock;			// 时钟修改超时计时
uchar	autotimer;			//无速度反馈定时器,超过两秒没有速度反馈,则关闭PWM
uchar	BeepTime;

bit		b_Power;				// 电机起停标志
bit		SpeedFlag;
bit		b_PulseIn;
bit		SpeedControl;//速度控制模式选择
//bit		b_NoFeedback;
//bit		FeedbackFlag;


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

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)
{
	uchar ikey;
	ikey=~(P1&0x0f)&0x0f;
	return(ikey&0x0f);
}

/**************************************************************************
*    函数原型: uchar ButtonScan(void);
*    功    能: 对按钮进行扫描,返回按钮值
**************************************************************************/

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)
		{
			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)
	{
		BeepTime=5;
		SpeedControl=0;//快速加速或减速

		switch(cBtnVal)
		{
			case vBtnVal_StartUp:
				if(++KeyNum>3){
					KeyNum=0;
				}
				switch(KeyNum){
					case WaitSpeed:
//						EX0=0;
//						Pre_pulselength=0;
						b_Power=STOP;
						cSpeed = 0xff;
						SpeedType = StopSpeed;
						cDY_Clock = 0xff;
						break;

					case LoSpeed:
//							EX0=1;
							b_Power = WORK;
							changeTimer=10;
							cSpeed = 0xc0;
							CCAP0H 	=0xe0;
							Pre_pulselength=16;
							SpeedType	=	HiSpeed;
							cDY_Clock	= ACTIVE_TIME;
							Relay1=0;//继电器吸合
						break;

					case MiSpeed:
//							EX0=1;
							b_Power = WORK;
							cSpeed = 0xc0;
							Pre_pulselength=16;
							SpeedType	= MiSpeed;
							cDY_Clock	= ACTIVE_TIME;
							Relay1=0;//继电器吸合
						break;

					case HiSpeed:
//							EX0=1;
							b_Power = WORK;
							Pre_pulselength=8;
							cSpeed = 0x70;
							SpeedType	= LoSpeed;
							cDY_Clock	= ACTIVE_TIME;
							Relay1=0;//继电器吸合
						break;

					default:
						break;
					}
			default:
				break;
		}
	DogReset();
	}
}


/**************************************************************************
*    函数原型: void F_SpeedControl(void);
*    功    能: 启动阶段处理速度变化
**************************************************************************/
void F_SpeedControl(void){
	if(ctemp!=cSpeed){
		if(ctemp<cSpeed){
			ctemp++;
		}
		else{
			ctemp--;
		}
	}
	else{
		SpeedControl=1;
	}
	if(ctemp==0xff&&(b_Power ==	STOP)){
		Relay1=1;//继电器断开
	}

	CCAP0H	= ctemp;
}

/**************************************************************************
*    函数原型: void F_SpeedControl(void);
*    功    能: 处理速度变化(ctemp采用模糊范围控制,Pre_Pulse 脉冲采用精确控制)
**************************************************************************/
void E_SpeedControl(void){

/*	if(b_Power==STOP){
		if(ctemp!=0xff){
			ctemp++;
		}
		else{
			Para_initial();
		}
	}
	else{*/
		if(Fact_pulselength!=Pre_pulselength){
			if(Fact_pulselength>Pre_pulselength){
				if(ctemp--<0x10){
					ctemp=0x10;
				}
			}
			else{
				if(ctemp++>0xe0){
					ctemp=0xe0;
				}
			}
		}
//	}
	CCAP0H	= ctemp;
}

/**************************************************************************
*    函数原型: void Para_initial(void);
*    功    能: 参数初始化
**************************************************************************/
void Para_initial(void)
{
	SetDriveOff();
	b_Power = 	STOP;
	SpeedType	=	WaitSpeed;
	autotimer=0;
	cDY_Clock  = 0xff;
	StopTimer=0;
	changeTimer=0xff;
	ctemp=0xff;
	cSpeed = 0xff;
	SpeedFlag=0;
//	PulseCount=0;
//	FeedbackFlag=0;
	Relay1=1;//继电器断开	KeyNum=0;
	SpeedControl=0;
	Fact_pulselength=0;
//	Pre_pulselength=0;
//	b_NoFeedback=0;
//	TR1=0;
//	EX0=0;
	b_PulseIn=1;
}


/**************************************************************************
*    函数原型: void system_initial(void);
*    功    能: 系统初始化
**************************************************************************/
void system_initial(void)
{
	Relay1=1;//继电器断开
	DogReset(); 	// 已针对 STC89C58RD+ 作修改.06-04-06
	SCON	=0x50;
	TMOD	=0x12; 	// T1:Time 16bit;	T0:8位自动重装载.
	TH0 =0xff;	// T0 溢出作为PCA计数器脉冲来源.
	TL0 =0xff;		//0xFE----976Hz   0xFF----1953Hz
	TH1 =vT1HVal;	// T1:系统计时.
	TL1 =vT1LVal;
	TCON =0x55; 	// TR0=1,外部中断0,1都是下降沿触发
	IP		=0x08; 		// T1 优先级高
//	IP		=0x01; 		// INT0 优先级高

	// PWM 配置.
	CMOD 	=0X84;
	CCAPM0	=0X42;	// pca 模块0 8位PWM方式.
	CCAP0H 	=0Xff;


	Para_initial();
	IE		=0x88; // 开 T1 中断
	CR		=1;		// 启动PWM.
//	EX0=1;			//开启外部中断0,下降沿触发

	AUXR|=0x80;//T0单周期指令,PWM加快12倍
}

/**************************************************************************
*    函数原型: void main(void);
*    功    能: 主程序
**************************************************************************/
void main(void)
{
	 system_initial();

	 BeepTime=5;

	 while(1)
	 {
	 	DogReset();
	 	ButtonHandle();

		if(b_Power==WORK){
//			TR1=1;
			SetDriveOn();
		}

/*第一档速度切换部分*/
		if(SpeedType == HiSpeed){
			if(!changeTimer){
				SpeedFlag=!SpeedFlag;
				if(!SpeedFlag){
					Pre_pulselength=16;
					cSpeed = 0xc0;
				}
				else{
					Pre_pulselength=8;
					cSpeed = 0x70;
				}
				changeTimer=10;
			}
		}
//
/*3分钟时间到,停止运行*/
/*此处增加判断有无转速反馈,若启动后仍没有反馈,则关断PWM输出,重新开始*/
/*失速保护,在MOS管损坏后,由于电机失速,在连续5S内一直超速,则关闭继电器,切断电机运行*/
		if((StopTimer>5)|(autotimer>2)|(!cDY_Clock)|(ctemp==0xff&&(b_Power==STOP))){
			Para_initial();
		}
	 }
}

/**************************************************************************
*    函数原型: void Trint1(void) interrupt 1 using 1;
*    功    能: 全局定时
**************************************************************************/
void T1_INT(void) interrupt 3 using 2
{
	TH1	=	vT1HVal;	// 时基0.1ms
	TL1	=	vT1LVal;


	if(!(--cT01ms)){
		cT01ms=vT01ms;

		Fact_pulselength++;
		if(b_PulseIn!=Pulse_Input){//&&!Pulse_Input){//每次上升沿检测脉宽,控制速度
			b_PulseIn=Pulse_Input;
			if(SpeedControl){
				E_SpeedControl();
			}
			Fact_pulselength=0;
			autotimer=0;
		}

		if(!(--cT10ms)){
			cT10ms=vT10ms;

			if(!SpeedControl){
				F_SpeedControl();
			}

			if(!(--cT100ms))
			{
				cT100ms=vT100ms;

				if(BeepTime!=0xff){//蜂鸣器计时器
					if(BeepTime!=0x00){
						BeepTime--;
						Beep=0;
					}
					else{
						Beep=1;
					}
				}
				else{
					Beep=1;
				}


				if(!(--cT01s)){
					cT01s=vT01S;


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

					if(changeTimer!=0xff){//高低速度切换时间10S
						if(changeTimer!=0x00){
							changeTimer--;
						}
					}

					if(Fact_pulselength<Pre_pulselength){//当实际检测速度大于设定值时,开始计时
						StopTimer++;
					}
					else{
						StopTimer=0;
					}

					if(b_Power == WORK){//没有反馈时开始计时
						autotimer++;
					}
				}
			}
		}
	}
}

/**************************************************************************
*    函数原型: void int0(void) interrupt 0 using 0;
*    功    能: 转速反馈,外部中断0
**************************************************************************/
/*
void int0(void) interrupt 0 using 0
{
	FeedbackFlag=!FeedbackFlag;
	autotimer=0;
	b_NoFeedback=1;
	Fact_pulselength=0;
//	PulseCount++;
/*	if(++PulseCount>Pre_Pulse){//也可作为复位用,判断多少脉冲为一个循环,这样便于判断起始位置
		Fact_Pulse=PulseCount;
		PulseCount=0;
	}*/
/*}
/**************************************************************************
*   END
*   END
**************************************************************************/

⌨️ 快捷键说明

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