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

📄 main.c

📁 此文件是一个完整的发动机转速表,用步进电机实现指示功能,利用HOLTECK的HT46R232作为MCU.
💻 C
字号:
/********************************************************************************************************
* Filename   : main.C
* Programmer : 
* 描述: 
*********************************************************************************************************
*/
#define USER_MAIN_GLOBALS
#include "..\includes\includes.h"
#if FK_EventFlag_EN
#include "..\framework\FKEventFlagBit-HT.H"
#endif
#include "..\src\LCD.H"

void main(void)                  //主程序
{  
    InitialMCU();
    ActObjInit();
    #if FK_KEY_EN
        KeyInit();
    #endif  
    #if FK_TMR_EN  
        TmrInit();
    #endif      
    #if FK_DISP_EN 
        DispInit();
    #endif
    CPU_Init();//初始化函数
    TmrStart(0,1);//
    TmrStart(1,2);//
    TmrStart(2,3);//
    asm("clr wdt");            //清看门狗      
    while(1){
        if(Tmr0OutEn){ 
            Tmr0OutEn = FALSE; 
            Tmr_ActObj();
            asm("clr wdt");            //清看门狗
        }
        asm("clr wdt");            //清看门狗
        ActObjScheduler();
    }
}
	
void  Tmr_ActObj (void)
{
    INT8U   i;
    for (i = 0; i < TMR_MAX_TMR; i++) {
        if (TmrCtrTbl[i] != 0) {
            if((-- TmrCtrTbl[i]) == 0){
                switch(i){
                    case 0:
                        ActObjSet(6);
                        TmrCtrTbl[0] = 1;
                        break;
                    case 1:
                        TmrCtrTbl[1] = 2;
                        break;
                    case 2:
                        TmrCtrTbl[2] = 3;
                        break;
                }
            }
        }
    }
}	

void CountMotTheer()         //计算表针应在的位置
{
	INT16U cp;
    INT16U cd;
    cp=NowFast;                               //读出当前的时速
    cd=(((INT32U)MAXSTEEP*10000/MAXHOURFAST)*cp)/10000;             //计算出当前表针应在的位置
    if(cd>MAXSTEEP)
        cd=MAXSTEEP;
    if(cd<0)
       cd=0;
    
	if(StartSeat<cd){
		RightLeft=1;                          //标志正转
		RunGap=(INT16S)(cd-StartSeat);        //原为:RunGap=cd-StartSeat;
        asm("nop");
    }else if(StartSeat>cd){
    	RightLeft=0;                          //标志反转
    	RunGap=(INT16S)(StartSeat-cd);
    	asm("nop");
    	if(cd<1){                          //如果是0速让指针多回几步
		   RunGap=(INT16S)(StartSeat-cd+5);  //原为:RunGap=StartSeat-cd+5;
		   if(RunGap>10)
		       NowChangeFiles=17;
		}else RunGap=(INT16S)(StartSeat-cd);  //原为:RunGap=StartSeat-cd;
	}
    if(RunGap>=360){
	    ChangeRun=1;
	    NowChangeFiles=14;
    }else if(RunGap>=300){
        ChangeRun=1;
	    NowChangeFiles=10;
    }else if(RunGap>=240){
        ChangeRun=1;
	    NowChangeFiles=6;
    }else if(RunGap>=200){
        ChangeRun=1;
	    NowChangeFiles=4;
    }else if(RunGap>=180){
        ChangeRun=1;
	    NowChangeFiles=3;
    }else if(RunGap>=160){
        ChangeRun=1;
	    NowChangeFiles=2;
    }else if(RunGap>120){
  	    ChangeRun=1;
	    NowChangeFiles=1;
    }else if(RunGap<=90){
  	    ChangeRun=1;
  	    NowChangeFiles=0;
   }
}  

void CPU_Init(void)             //初始化程序
{
    _pac=0x21;             //PA0,PA5为输入外,其它全部设定成输出状态
    _pa = 0;
    _pbc= 0 ;              //PB全为输出
    _pb = 0; 
    _pdc=0xf0;             //PD0-3为输出,其它位为输出          
    _pd = 0x10;
    _pfc = 0;              //全部设为输出
    _pf = 0;
    
    _intc0=0x6e;                 //使能定时器0,1,和外部中断, T0F=1,EIF1=1,ET0I=1,EEI0=1,EMI=0;
    _intc1=0x01;                 //使能定时器1中断,时基0.25US  (8/4)/8
    _tmr0c=0x92;                 //定时器0为定时模式,时钟4分频,T0M1=1,T0M0=0,T0ON=1,T0PSC0--2=1;
    _tmr0h=0xf8;                 //重装定时器0值
    _tmr0l=0x30;                 //重装定时器0值
    
    _tmr1c=0x90;                 //势能定时器1为定时模式,系统已经四分频
    _tmr1h=0xf8;                 //重装定时器值
    _tmr1l=0x30;                 
	
	  PWMDate1=250;
    PWMDate2=250;
    MOUT1=1;                    //上电初始化输出口
    MOUT2=1;
    MOUT3=1;
    MOUT4=1;
    PWMNumb=0;
    StartSeat=0;                 //当前的指针位置
    RightLeft=1;                 //当前为正向转动指针
    RunGap=0;                    //当前需要运行的距离
    AddSteep=0; 
    NowChangeFiles=0;  
    
    LastFast=0;
    SpeBufStat = 0;
    NowFast=0; 
    SizatReturn = 0;
    
    StartSeat=0;                 //当前的指针位置                 //
	  BStartInit=1;                //正常工作状态
	  _tmr1l=ChangeTemr0Date_l[0];    //设置当前为最低速
    _tmr1h=ChangeTemr0Date_h[0];    //设置当前为最低速    
	  ChangeFiles=0;
	  OS_EXIT_CRITICAL();          //打开总中断 
}

void Delay(INT16U numb)
{
    INT16U i,j;
    for(i=0;i<numb;i++){
       for(j=0;j<10;j++){
           _nop_();
           asm("clr wdt");
       }
    }
}
 

void CountRunSeep(void)                       //计算当前的车时速
{  
	INT32U cp,cj,cd;
	_emi=0;                                //关总中断                     
	cd=Speed_CountRxImpNumb;               //读出计到的脉冲数
	Speed_CountRxImpNumb = 0;
	_emi=1;                                //开总中断
	if(cd>=1){
	    cd=cd*4;                        //计算出1S内收到的脉冲数
	    cd=(60*cd)/ENGSEEPLONG;        //计算出秒速度 /MIN 
	}
	if((cd>LastFast+10)||(cd<LastFast-10)){
		LastFast=(INT16U)cd;
		NowFast = (INT16U)cd;                   //输出当前的时速
		if(NowFast >= 3500 ){
		   NowFast = 3500; 
		}
	}
} 

void interrupt Timer1Int(void) @0x0C    //定时器1中断函数1Ms
{   
    _ton1 = 0;          //关闭定时器
 	if(ChangeFiles>5){
 	    _tmr1l=ChangeTemr0Date_l[ChangeFiles-5]; 
 	    _tmr1h=ChangeTemr0Date_h[ChangeFiles-5];
 	    NowFilesDate=ChangeNumbSeep[ChangeFiles];
 	}else{
 	    _tmr1l=LowChangeTemr0Date_l[ChangeFiles];
 	    _tmr1h=LowChangeTemr0Date_h[ChangeFiles];
 	    NowFilesDate=ChangeNumbSeep[ChangeFiles];
 	}

 	if(SizatReturn == 1){
 	    _ton1 =1;          //打开
        if(RunGap>0){               //如果需要运动的位置不为零
    	    RunGap--;
    	    PWMNumb++;
            if(PWMNumb>23)
                PWMNumb=0;            
    	    PWMDate1=PWMOutDate1[PWMNumb];//往反方向转
            PWMDate2=PWMOutDate2[PWMNumb];
            PWMDate3=PWMOutDate3[PWMNumb];
            PWMDate4=PWMOutDate4[PWMNumb];
            StartSeat--;                     //当前位置减减少
            if(StartSeat<0)
                StartSeat=0;	
        }else {
            SizatReturn = 0;
        	ChangeFiles=0;             //变为最低速
        } 	
 	}else{      //在没有掉电的情况下正常工作
        _ton1 =1;          //打开
     	TEXT=1;
        if(BStartInit==1){          //如果是在工作状态
            ChangeRun=1;            //标志需要加速
    	    if(RunGap>0){
    	        if(ChangeRun){           //如果需要改变速度
    	            AddSteep++;          
    	            if(RunGap>90){       //如果没到减速区
    		            if(AddSteep>=NowFilesDate){         //改变一次速度
    			            AddSteep=0;
    			            if(ChangeFiles<=NowChangeFiles)
    			                ChangeFiles++;
    				        if(ChangeFiles>17)
    				            ChangeFiles=17;
    		            }
    		        }else{                  //减速区
    		           if(AddSteep>=NowFilesDate){         //改变一次速度
    			            AddSteep=0;
    			            if(ChangeFiles>=1)
    				            ChangeFiles--;
    				        if(ChangeFiles<=0){
    				            ChangeFiles=0;
    				        }
    		           }
                    }
                }
    	    }
    	}
    	
    	if(ChangeFiles>5){
            if(RunGap>0){               //如果需要运动的位置不为零
        	    RunGap--;
        	    PWMNumb++;
                if(PWMNumb>23)
                    PWMNumb=0;
                if(RightLeft==1){                    //往返正向转
                    PWMDate4=PWMOutDate1[PWMNumb];
                    PWMDate3=PWMOutDate2[PWMNumb];
                    PWMDate2=PWMOutDate3[PWMNumb];
                    PWMDate1=PWMOutDate4[PWMNumb];
                    StartSeat++;                     //当前位置增加
                 }else if(RightLeft==0){             //往反方向转
            	    PWMDate1=PWMOutDate1[PWMNumb];
                    PWMDate2=PWMOutDate2[PWMNumb];
                    PWMDate3=PWMOutDate3[PWMNumb];
                    PWMDate4=PWMOutDate4[PWMNumb];
                    StartSeat--;                     //当前位置减减少
                    if(StartSeat<0)
                        StartSeat=0;
                } 	
            }else {
            	ChangeFiles=0;             //变为最低速
            } 	
        }else{
        	ChangeSteep++;
        	if(ChangeSteep>=SlowDate[ChangeFiles]){
        		ChangeSteep=0;
        		if(RunGap>0){               //如果需要运动的位置不为零
            	    RunGap--;
            	    PWMNumb++;
                    if(PWMNumb>23)
                        PWMNumb=0;
                    if(RightLeft==1){                    //往返正向转
                        PWMDate4=PWMOutDate1[PWMNumb];
                        PWMDate3=PWMOutDate2[PWMNumb];
                        PWMDate2=PWMOutDate3[PWMNumb];
                        PWMDate1=PWMOutDate4[PWMNumb];
                        StartSeat++;                     //当前位置增加
                     }else if(RightLeft==0){             //往反方向转
                	    PWMDate1=PWMOutDate1[PWMNumb];
                        PWMDate2=PWMOutDate2[PWMNumb];
                        PWMDate3=PWMOutDate3[PWMNumb];
                        PWMDate4=PWMOutDate4[PWMNumb];
                        StartSeat--;                     //当前位置减减少
                        if(StartSeat<0)
                            StartSeat=0;
                    } 	
                }else {
            	   ChangeFiles=0;             //变为最低速
                } 	
            }	
        	
        }	
       TEXT=0;  
    }
} 

void interrupt Timer0Int(void) @0x08     //定时器0中断,1ms中断
{
    Speed_AllPulseTime++;
    Speed_ErrorTime++;
    if(Speed_ErrorTime>=250){                   //采样时间到标志一组数据接收完成
    	Speed_OneOver=1;
    }
    if(Speed_ErrorTime>=1000){
    	Speed_PulseNumb=0;
    	Speed_ErrorTime=0;
    	LastFast=0;
    	NowFast = 0;
    	ActObjReadySet |= 0x40;//ActObjSetISR(8);
    }
    
    if(_pa0==0){    //检测是否掉电
       asm("nop");
       asm("nop");
       if(_pa0==0){
           ChangeFiles = 18; //加速转子
           SizatReturn = 1;
		   RunGap=(INT16S)(StartSeat);
       }
    }
    
    ADErrorTime++;
    if(ADErrorTime >= 20 ){
        ADErrorTime = 0;
        Tmr0OutEn = TRUE;
    }  
}

void interrupt Int0Int(void) @0x04   //外部中断0函数,车速
{   
    if(SPEED==0){
    	asm("nop");
    	asm("nop");
    	asm("nop");
    	if(SPEED==0){
    	    Speed_PulseNumb++;
    	} 	
        if(Speed_OneOver){              //一组数据采集完成
            asm("clr wdt");
            Speed_OneOver=0; 
            Speed_ErrorTime = 0;
            Speed_CountRxImpNumb = Speed_PulseNumb  ;
            Speed_PulseNumb = 0;
            ActObjReadySet |= 0x80;//ActObjSetISR(8);   	   
        }
    }         
        _eif=0;                      //清外部中断1标志位
}

void InitialMCU(void)//MCU初始化
{
    //先清RAM
    INT8U i;
    #asm
    mov	a,40h
	mov	[01h],a
clrram:
	clr	[00h]
	inc [01h]
	mov	a,0ffh
	sub	a,[01h]
	snz	[0ah].2
	jmp	clrram	
	#endasm
}

⌨️ 快捷键说明

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