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

📄 main.c

📁 P89LV51RD2单片机直流电机测速源码
💻 C
字号:
/*
	Main.C
	直流电机测速程序
*/


#include <REG51.H>
#include <ABSACC.H>
#include <CTYPE.H>


//定义I/O接口
sbit PWM = P1^6;	//PWM方波输出(接至MotorA,控制直流电机转速)
sbit KEY1 = P2^0;	//按键1(电机加速)
sbit KEY2 = P2^1;	//按键2(电机减速)


//定义全局变量
unsigned char DispBuf[8];	//定义数码管显示缓冲区(由T1定时中断自动扫描)
unsigned char Speed;		//预设的电机转速值,范围20~250
bit SWTR;	//软件定时器运行标志
bit SWTF;	//软件定时器溢出标志
unsigned int SWTV;	//软件定时器定时值


/*
函数:T1INTSVC()
功能:定时器T1的中断服务函数(每100μs中断一次)
*/
void T1INTSVC() interrupt 3
{
	code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	static unsigned char n = 0;
	static unsigned char t = 0;
//扫描数码管
	P0 = 0xFF;		//暂停显示
	XBYTE[0xE800] = ~DispBuf[n];	//更新扫描数据
	P0 = ~com[n];	//重新显示
	n++;
	n &= 0x07;
//产生PWM方波,驱动电机
	t++;
	if ( t < Speed )
	{
		PWM = 1;
	}
	else
	{
		PWM = 0;
	}
//模拟一个软件定时器
	if ( SWTR )
	{
		if ( --SWTV == 0 ) SWTF = 1;
	}
}


/*
函数:DispChar()
功能:在数码管上显示字符
参数:
	x:显示位置(0~7)
	c:要显示的字符(仅限0~9、AbCdEF和-)
*/
void DispChar(unsigned char x, unsigned char c)
{
	code unsigned char Tab[] =
	{//0123456789AbCdEF的数码管字型数据
		0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
		0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
	};
	unsigned char t;
	x &= 0x07;
	x = 7 - x;
	if ( c == '-' )
	{
		DispBuf[x] = 0x40;
	}
	else
	{
		t = toint(c);
		if ( t < 16 )
		{
			DispBuf[x] = Tab[t];
		}
	}
}


/*
函数:DispStr()
功能:在数码管上显示字符串
参数:
	x:起始显示位置(0~7)
	*s:要显示的字符串(其中的字符仅限0~9、AbCdEF和-)
*/
void DispStr(unsigned char x, unsigned char *s)
{
	unsigned char c;
	for (;;)
	{
		c = *s++;
		if ( c == '\0' ) break;
		DispChar(x++,c);
	}
}


/*
函数:Delay()
功能:延时0.1ms~6.5536s
参数:
	t>0时,延时(t*0.1)ms
	t=0时,延时6.5536s
*/
void Delay(unsigned int t)
{
	SWTV = t;	//软件定时器赋初值
	SWTR = 1;	//启动软件定时器
	while ( !SWTF );	//等待溢出
	SWTR = 0;	//停止软件定时器
	SWTF = 0;	//清除溢出标志
}


/*
函数:ByteToStr()
功能:字节型变量c转换为十进制字符串
*/
void ByteToStr(unsigned char idata *s, unsigned char c)
{
	code unsigned char Tab[] = {100,10};
	unsigned char i;
	unsigned char t;
	for ( i=0; i<2; i++ )
	{
		t = c / Tab[i];
		*s++ = '0' + t;
		c -= t * Tab[i];
	}
	*s++ = '0' + c;
	*s = '\0';
}


/*
函数:MeasureSpeed()
功能:测量电机转速
返回:转速值(单位:转/秒)
*/
unsigned char MeasureSpeed()
{
	TH0 = TL0 = 0;	//清除计数器T0
	TR0 = 1;		//启动计数器T0
	Delay(2500);	//延时250ms(因为直流电机转盘上正好有4个槽)
	TR0 = 0;		//停止计数
	TF0 = 0;		//清除(可能的)溢出标志
	return TL0;		//返回结果(单位:转/秒;已知电机转速不会超过100)
}


/*
函数:KeyScan()
功能:键盘扫描
返回:扫描到的键值
*/
unsigned char KeyScan()
{
	unsigned char k = '\0';
	if ( KEY1 == 0 ) k = '+';
	if ( KEY2 == 0 ) k = '-';
	return k;
}


/*
函数:SysInit()
功能:系统初始化
*/
void SysInit()
{
	unsigned char i;
	for ( i=0; i<8; i++ )
	{
		DispBuf[i] = 0x00;	//数码管初始化为全灭
	}
	Speed = 30;		//设置电机初始转速
	SWTR = 0;
	SWTF = 0;
	SWTV = 0;
	TMOD &= 0x0F;
	TMOD |= 0x20;	//设置T1为8位定时器,自动重装
	TH1 = TL1 = 0xA4;	//设置T1初值,对应100μs
	ET1 = 1;	//使能T1中断
	TR1 = 1;	//启动T1
	EA = 1;		//使能总中断
	TMOD &= 0xF0;
	TMOD |= 0x05;
}


void main()
{
	unsigned char k;
	unsigned char spd;
	unsigned char s[4];
	SysInit();
	for (;;)
	{
		for (;;)
		{
			spd = MeasureSpeed();
			ByteToStr(s,spd);
			DispStr(5,s);
			k = KeyScan();	//键盘扫描
			if ( k != '\0' ) break;		//如果有键按下,退出循环
		}
		switch ( k )		//判断键值,执行具体功能
		{
		case '+':
			if ( Speed < 250 ) Speed += 5;
			break;
		case '-':
			if ( Speed > 20 ) Speed -= 5;
			break;
		default:
			break;
		}
		for (;;)
		{
			spd = MeasureSpeed();
			ByteToStr(s,spd);
			DispStr(5,s);
			if ( KeyScan() == '\0' ) break;	//如果按键抬起,退出循环
		}
	}
}

⌨️ 快捷键说明

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