📄 main.c
字号:
#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 + -