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

📄 main.c

📁 基于RS232的键盘,也可以作为输入输出的操作面板,用于数控系统开发
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <common.h>
#include <head.h>
#include <STDIO.H>

void InitTimer( void )
{
	// 定时器0停止
	TR0 = 0;
	TR1 = 0;

	TMOD = 0x11;	// 16位计数定时
	
	PT0 = 1;		// 定时器0高优先级
	ET0 = 1;		// 允许定时器0中断	

	PT1 = 1;		// 定时器1高优先级
	ET1 = 1;		// 允许定时器1中断	

	EA = 1;			// 开启中断
}

//u_char	code cmd[] = "%01W1110013880000c35000$";

// 主程序
void main( void )
{
	u_char		idx;
	u_short		ledcnt;

	ledcnt = 65535;
	while( ledcnt ) 
	{
		ledcnt--; 
		ledcnt++; 
		ledcnt--; 
	};

	P0 = 0xff;
	P1 = 0xff;
	P2 = 0xff;
	P3 = 0xff;

	// 开启内部RAM
//	CHPENR = 0x87;
//	CHPENR = 0x59;
//	CHPCON |= 0x10;
//	CHPENR = 0;

	InitTimer( );
	EnableSerialComm( );
/*
	CommBuf.MsgCnt = 0;
	for( idx = 0; idx < 21; idx++ )
	{
		CommBuf.MsgData[idx] = cmd[idx];
		CommBuf.MsgCnt++;
	}
	idx = CalCheckCode( CommBuf.MsgData, CommBuf.MsgCnt );
	CommBuf.MsgData[CommBuf.MsgCnt] = ToHexchar( idx >> 4 );
	CommBuf.MsgCnt++;
	CommBuf.MsgData[CommBuf.MsgCnt] = ToHexchar( idx );
	CommBuf.MsgCnt++;
	CommBuf.MsgData[CommBuf.MsgCnt] = '$';
	CommBuf.MsgCnt++;
	RecvOkFlag = 1;
*/
	for ( ; ; )
	{
		// 运行指示灯
		ledcnt++;
		if ( ledcnt >= 5000 )
		{
			ledcnt = 0;
			LED = ~LED;
		}

		// 接收数据处理
		RecvMsgProce( );

		// 启动电机
		StartMotor( );

		// 如果定时器0已启动
		if ( Timer[0].MotorIdx )
		{
			idx = Timer[0].MotorIdx - 1;
			
			// 升降速方式
			if ( MotorStatus[idx].UpDwon )
			{
				// 已到达设定频率				
				if ( MotorStatus[idx].Status & PLUSE_TO_FLAG_MASK )
				{
					// 无减速标志
					if ( !(MotorStatus[idx].Status & FREQ_DWON_MASK) )
					{
						if ( Timer[0].CurPluseNum < Timer[0].DwonPluse )
							MotorStatus[idx].Status |= FREQ_DWON_MASK;	
					}
					else
					{
						if ( !Timer[0].SecConstFlag && !Timer[0].UpDwonCnt )
						{
							Timer[0].UpDwonCnt = (MotorStatus[idx].UpDwon & 0x0f) << 1;	
							Timer[0].CurFreq -= Timer[0].FreqInc;
							if ( Timer[0].CurFreq < START_FREQ )
								Timer[0].CurFreq = START_FREQ;
							
							CalSecFreqTimerConst( 0 );
						}
					}
				}
				else
				{
					// 未到达设定频率
					if ( Timer[0].CurFreq < MotorStatus[idx].SetFreq )
					{ 
						if ( !Timer[0].SecConstFlag && !Timer[0].UpDwonCnt )
						{
							Timer[0].UpDwonCnt = (MotorStatus[idx].UpDwon & 0x0f) << 1;	
							Timer[0].CurFreq += Timer[0].FreqInc;
							if ( Timer[0].CurFreq >= MotorStatus[idx].SetFreq )
							{
								Timer[0].CurFreq = MotorStatus[idx].SetFreq;
								MotorStatus[idx].Status |= PLUSE_TO_FLAG_MASK;
								// Timer[0].DwonPluse 暂存启动总脉冲
								if ( (long)MotorStatus[idx].TotalPluseCnt > (long)Timer[0].DwonPluse )
									Timer[0].DwonPluse = MotorStatus[idx].TotalPluseCnt - Timer[0].DwonPluse;
								else
									Timer[0].DwonPluse -= MotorStatus[idx].TotalPluseCnt;
							}

							CalSecFreqTimerConst( 0 );
						}
					}
				}
			}
			else
			{
				// 非升降速,如果频率已改变
				if ( Timer[0].CurFreq != MotorStatus[idx].SetFreq )
				{ 
					if ( !Timer[0].SecConstFlag )
					{
						Timer[0].CurFreq = MotorStatus[idx].SetFreq;
						CalSecFreqTimerConst( 0 );
					}
				}
			}
		}

		// 如果定时器1已启动
		if ( Timer[1].MotorIdx )
		{
			idx = Timer[1].MotorIdx - 1;
			
			// 升降速方式
			if ( MotorStatus[idx].UpDwon )
			{
				// 已到达设定频率				
				if ( MotorStatus[idx].Status & PLUSE_TO_FLAG_MASK )
				{
					// 无减速标志
					if ( !(MotorStatus[idx].Status & FREQ_DWON_MASK) )
					{
						if ( Timer[1].CurPluseNum < Timer[1].DwonPluse )
							MotorStatus[idx].Status |= FREQ_DWON_MASK;	
					}
					else
					{
						if ( !Timer[1].SecConstFlag && !Timer[1].UpDwonCnt )
						{
							Timer[1].UpDwonCnt = (MotorStatus[idx].UpDwon & 0x0f) << 1;	
							Timer[1].CurFreq -= Timer[1].FreqInc;
							if ( Timer[1].CurFreq < START_FREQ )
								Timer[1].CurFreq = START_FREQ;
							
							CalSecFreqTimerConst( 1 );
						}
					}
				}
				else
				{
					// 未到达设定频率
					if ( Timer[1].CurFreq < MotorStatus[idx].SetFreq )
					{ 
						if ( !Timer[1].SecConstFlag && !Timer[1].UpDwonCnt )
						{
							Timer[1].UpDwonCnt = (MotorStatus[idx].UpDwon & 0x0f) << 1;	
							Timer[1].CurFreq += Timer[1].FreqInc;
							if ( Timer[1].CurFreq >= MotorStatus[idx].SetFreq )
							{
								Timer[1].CurFreq = MotorStatus[idx].SetFreq;
								MotorStatus[idx].Status |= PLUSE_TO_FLAG_MASK;
								
								if ( (long)MotorStatus[idx].TotalPluseCnt > (long)Timer[1].DwonPluse )
									Timer[1].DwonPluse = MotorStatus[idx].TotalPluseCnt - Timer[1].DwonPluse;
								else
									Timer[1].DwonPluse -= MotorStatus[idx].TotalPluseCnt;
							}

							CalSecFreqTimerConst( 1 );
						}
					}
				}
			}
			else
			{
				// 非升降速,如果频率已改变
				if ( Timer[1].CurFreq != MotorStatus[idx].SetFreq )
				{ 
					if ( !Timer[1].SecConstFlag )
					{
						Timer[1].CurFreq = MotorStatus[idx].SetFreq;
						CalSecFreqTimerConst( 1 );
					}
				}
			}
		}
	}
}

void StartMotor( void )
{
	bit		dir;
	BYTE	i, tidx;

	for( i = 0; i < MAX_MOTOR_NUM; i++ )
	{
		// 已启动		
		if ( MotorStatus[i].Status & MOTOR_RUN_MASK )
			continue;
	
		// 无命令
		if ( !(MotorStatus[i].Dir & DIR_FLAG_MASK) )
			continue;
		
		tidx = 2;
		if ( !Timer[0].MotorIdx )
			tidx = 0;
		if ( !Timer[1].MotorIdx )
			tidx = 1;
	
		// 没有空余定时器
		if ( tidx == 2 )
			break;

		// 设定升降速
		Timer[tidx].DwonPluse = MotorStatus[i].TotalPluseCnt;
		if ( MotorStatus[i].UpDwon )
		{
			Timer[tidx].CurFreq = START_FREQ;
			Timer[tidx].FreqInc = MotorStatus[i].UpDwon >> 4;
			Timer[tidx].UpDwonCnt = (MotorStatus[i].UpDwon & 0x0f) << 1;
		}
		else
		{
			Timer[tidx].CurFreq = MotorStatus[i].SetFreq;
			Timer[tidx].FreqInc = 0;
			Timer[tidx].UpDwonCnt = 0;
		}
			
		// 计算定时器常数
		CalSecFreqTimerConst( tidx );
		Timer[tidx].TimerConstCntH = Timer[tidx].SecTimerConstCntH;	
		Timer[tidx].TimerConstH = Timer[tidx].SecTimerConstH;
		Timer[tidx].TimerConstL = Timer[tidx].SecTimerConstL;
		Timer[tidx].SecConstFlag = 0;
		// 记录当前总脉冲,供双向使用
		Timer[tidx].CenrerPluse = (WORD)MotorStatus[i].TotalPluseCnt;

		// 启动标志
		MotorStatus[i].Status |= MOTOR_RUN_MASK;

		switch( MotorStatus[i].Dir & DIR_FLAG_MASK )
		{
			case 1:		// 正转
			case 2:		// 反转
				if ( (MotorStatus[i].Dir & DIR_FLAG_MASK) == 1 ) 
					dir = 0;
				else
					dir = 1;
				
				// 脉冲数量
				Timer[tidx].CurPluseNum = MotorStatus[i].CmdPluseNum * 2;
				break;	
			
			case 3:		// 双向
				dir = 0;

				// 脉冲数量
				Timer[tidx].CurPluseNum = (MotorStatus[i].CmdPluseNum >> 16) * 2;
				
				// 更新命令脉冲,减少中断程序运算
				MotorStatus[i].CmdPluseNum = (MotorStatus[i].CmdPluseNum & 0xffff) * 2 + Timer[tidx].CurPluseNum;
				break;
		}
		
		// 置运转方向
		switch( i )
		{
			case 0:
				DIR0 = dir;
				break;
			case 1:
				DIR1 = dir;
				break;
			case 2:
				DIR2 = dir;
				break;
			case 3:
				DIR3 = dir;
				break;
			case 4:
				DIR4 = dir;
				break;
			case 5:
				DIR5 = dir;
				break;
		}

		// 启动定时器
		Timer[tidx].MotorIdx = i + 1;
		Timer[tidx].IntCnt = 0;
		if ( !tidx )
		{
			LastTimer0ST = 1;
			LastTimer0WST = 1;
			Timer0EndIntFlag = 0;
			TL0 = 0;
			TH0 = 0;
			ET0 = 1;
			// 模拟中断
			TF0 = 1;
		}
		else
		{
			LastTimer1ST = 1;
			LastTimer1WST = 1;
			Timer1EndIntFlag = 0;
			TL1 = 0;
			TH1 = 0;
			ET1 = 1;
			// 模拟中断
			TF1 = 1;
		}
	}
}

void CalSecFreqTimerConst( u_char tidx )
{
	DWORD	tmp;

	// 0x196e6b - 定时器每秒能计数次数除2
	tmp = 0x196e6b / (DWORD)Timer[tidx].CurFreq - 12;
	Timer[tidx].SecTimerConstCntH = *((BYTE idata*)&tmp + NMSB);

	tmp &= 0xffff;
	tmp = 0 - tmp;
	Timer[tidx].SecTimerConstH = *((BYTE idata*)&tmp + NLSB);
	Timer[tidx].SecTimerConstL = tmp;
	Timer[tidx].SecConstFlag = 1;
}

//	中断号
//	外部中断0		0
//	定时器0			1
//	外部中断1		2
//	定时器1			3
//	串行通信		4
//	定时器2			5

#define	DWordDec( ) 			\
	do { 						\
		if ( *tmpptr )			\
			(*tmpptr)--;		\
		else					\
		{						\
			*tmpptr = 0xff;			\
			tmpptr--;				\
			if ( *tmpptr )			\
				(*tmpptr)--;		\	
			else						\
			{							\
				*tmpptr = 0xff;			\
				tmpptr--;				\
				if ( *tmpptr )			\
					(*tmpptr)--;		\	
				else					\
				{						\
					*tmpptr = 0xff;			\
					tmpptr--;				\
					if ( *tmpptr )			\
						(*tmpptr)--;		\			
					else					\
						*tmpptr = 0xff;		\
				}			\
			}				\
		}					\
	} while( 0 )

#define	DWordInc( ) 		\
	do { 					\
		(*tmpptr)++;		\
		if ( !(*tmpptr) )	\
		{					\
			tmpptr--;		\
			(*tmpptr)++;		\
			if ( !(*tmpptr) )	\
			{					\
				tmpptr--;		\
				(*tmpptr)++;		\
				if ( !(*tmpptr) )	\
				{					\
					tmpptr--;		\
					(*tmpptr)++;	\
				}		\
			}			\
		}				\
	} while( 0 )

	
void timer_0(void) interrupt 1 using 2
{
	TimerEndTmpFlag = 0;
	if ( Timer0EndIntFlag )
	{
		Timer[0].IntCnt = 0;
		TimerEndTmpFlag = 1;
		if ( Timer[0].SecConstFlag )
		{
			Timer[0].TimerConstCntH = Timer[0].SecTimerConstCntH;
			Timer[0].TimerConstH = Timer[0].SecTimerConstH;
			Timer[0].TimerConstL = Timer[0].SecTimerConstL;
			Timer[0].SecConstFlag = 0;
		}		
	}

	TR0 = 0;
	if ( Timer[0].IntCnt == Timer[0].TimerConstCntH )
    {
		Timer0EndIntFlag = 1;

		TL0 += Timer[0].TimerConstL;
		TH0 = Timer[0].TimerConstH;
	}
	else
	{
		Timer0EndIntFlag = 0;
	}
	TR0 = 1;
	Timer[0].IntCnt++;

	if ( !TimerEndTmpFlag )
		return;

	if ( Timer[0].UpDwonCnt )
		Timer[0].UpDwonCnt--;

	switch( Timer[0].MotorIdx )
	{
		// 电机0
		case 1:
			if ( MotorStatus[0].Status & MOTOR_STOP_CMD_MASK )
			{
				// 双向
				if ( (MotorStatus[0].Dir & DIR_FLAG_MASK) == DIR_FLAG_MASK )
				{
					if ( Timer[0].CenrerPluse == (WORD)MotorStatus[0].TotalPluseCnt )
					{
						// 只保留零点记录标志
						MotorStatus[0].Status &= ZERO_RECORD_MASK;	
						MotorStatus[0].Dir = 0;

						// 关定时器0
						TR0 = 0;
						ET0 = 0;
						Timer[0].MotorIdx = 0;
						break;
					}
				}
				else
				{
					// 只保留零点记录标志
					MotorStatus[0].Status &= ZERO_RECORD_MASK;	
					MotorStatus[0].Dir = 0;
	
					// 关定时器0
					TR0 = 0;
					ET0 = 0;
					Timer[0].MotorIdx = 0;
					PUL0 = 1;
					break;
				}
			}
		
			// 改变输出电平
			PUL0 = ~PUL0;
	
			// 增减脉冲总数量

⌨️ 快捷键说明

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