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

📄 main0627.c

📁 发动机控制
💻 C
字号:
//说明:
//在P10和P11输入信号后,在P12上输出预定波形

#include <reg51.h>
#include <stdio.h> 
#include <intrins.h>
#include <absacc.h>

#define UINT unsigned int 
#define UCHAR unsigned char
                               //8155地址 宏定义
#define P8155CW 0x0200         //控制字地址
#define P8155IA 0x0201         //A口
#define P8155IB 0x0202         //B口
#define P8155IC 0x0203         //C口

UCHAR   keynum;

unsigned long    temp;

#define  SI_HSEC   0x01           //节拍信号
#define  SI_WIDTH   0x08          //模拟喷油脉冲宽度
UCHAR    TSignal;                 //半秒信号

UCHAR FireSignal;       //点火信号当前标志
UCHAR lastFireSignal;   //点火信号前1ms标志

UCHAR OilSignal;       //喷油信号当前标志
UCHAR lastOilSignal;   //喷油信号前1ms标志

sbit testLed=P1^5;       //模拟尖脉冲点火信号
sbit simLed=P1^6;        //模拟喷油信号

sbit OutSignal=P1^2;     //输出断口
sbit oilLed=P1^4;        //喷油信号高
sbit fireLed=P1^3;       //点火信号为高
sbit runLed=P1^7;        //程序正常标志
sbit keyLed=P1^0;

UINT timeFireSignal;     //点火信号周期(0.1ms单位)
UINT timeOilSignal;      //喷油信号宽度(0.1ms单位)

UINT outTimeFire,outTimeDelay;       //输出点火时间
UINT inputAngle;                     //当前角度/键盘输入角度
UCHAR keydown;
UCHAR I1,I2;

static UINT time0Count,time0Count1,time0Count2,time0Key;   //计数器
volatile UINT base,i;                                      // 基本定时单元

UCHAR outSignalStart,outStart;   //输出信号开始标志

void  firePrev();       //点火信号处理
void  outPrev();        //输出信号处理
void  keyPrev();        //键盘处理
//--------------------------------------------------------------------------
// 变量初始化子程序
//--------------------------------------------------------------------------
void init()
{
	inputAngle = 0x00;
	timeOilSignal = 0;
	outTimeFire = 0;
	time0Count = 0;
	time0Count1 = 0;
	time0Count2 = 0;
	time0Key = 0;
	keydown = 0;
	
	OilSignal = 0;
	lastOilSignal = 0;
	FireSignal = 0;
	lastFireSignal = 0;
	
	outSignalStart =0x00;
//	outStart = 0x00;
	outTimeDelay = 0xFFFF;	
}
//--------------------------------------------------------------------------
// 系统初始化,初始化寄存器
//--------------------------------------------------------------------------
void initsys()
{	
        EA = 1;                      //全局中断允许
        ET0 = 1;                     //定时器中断允许
        ET1 = 1;
        PT1 = 1;                     //T1中断优先级最高
	TMOD = 0x11;                 //T0工作方式1,计时1ms
	TH0=0xFE;
	TL0=0x0C;
	TR0 = 1;                     //启动T0;
	
	TH1=0xFF;
	TL1=0xFE;
	TR1 = 0;                     //启动T1;
	//外部中断1
	IT1=1;                       //负跳变触发
	EX1=1;                       //外中断1允许
		
	fireLed = 0;
	oilLed = 0;
	OutSignal = 1;               //输出信号断口初值
	//8155 INIT
	XBYTE[P8155CW] = 0x43;       //定义8155控制字 
}
//--------------------------------------------------------------------------
// 主程序
//--------------------------------------------------------------------------
void main(void)
{  
   init();          //变量初始化
   initsys();       //系统初始化
   while(1){
   	firePrev(); //处理点火信号   
//   	outPrev();  //输出信号处理
        if(TSignal&SI_HSEC)          // 0.4秒消息信号
    	{
           TSignal&=~SI_HSEC;	     // 清除0.4秒消息信号标志
           runLed = !runLed;         // 程序运行正常指示灯
    	}
    	keyPrev();  //键盘处理
   }
}
//--------------------------------------------------------------------------
// 中断1子程序
//--------------------------------------------------------------------------
void intersvr1(void) interrupt 2 using 1
{
       FireSignal=0xFF;
}
//--------------------------------------------------------------------------
// T1中断子程序
//--------------------------------------------------------------------------
void time1(void) interrupt 3 using 1
{	
	OutSignal = 1;
	TR1 = 0;
}
//--------------------------------------------------------------------------
// T0中断子程序
//--------------------------------------------------------------------------
void time0(void) interrupt 1 using 1
{
     TH0=0xFE;
     TL0=0x0C;
     time0Count++;          //点火信号周期计数
     time0Key++;            //键盘延时,去抖动
     
     time0Count1++;         //喷油脉冲宽度计数
     time0Count2++;         //输出信号延时计数
          
     //喷油信号检测
     if( (P1&0x02) == 0x02){
     	OilSignal = 0xFF;
        if(lastOilSignal!=0xFF){ //喷油信号上升沿
	    time0Count1=0;
	    outTimeDelay = outTimeFire;
	}
	/*//---------------------------------------------------------
	if(time0Count2>outTimeDelay){     //延时没有喷油脉冲宽度多,则开始喷油
	    if(outStart==0x00){
           	OutSignal = 0;                        //置输出为低电平
           	time0Count2 = 0;                      //计数器清零
           	outSignalStart = 0x00;
           	outStart = 0xFF;
           	timeOilSignal = 0xF0;                 //
            }
        }*/
	//----------------------------------------------------------
     }else{
        OilSignal=0x00;
        if(lastOilSignal==0xFF){ //喷油信号下降沿
	//    if(outStart == 0x00){
	        timeOilSignal = time0Count1;
	//        outTimeDelay = outTimeFire;
	        time0Count2 = 0;
	        outSignalStart = 0xFF;
	/*    }else{
	        timeOilSignal = outTimeDelay;	                      
	        //装定时器
	        TH1 = (0xFFFF-timeOilSignal*500)/256;
	        TL1 = (0xFFFF-timeOilSignal*500)%256;
	        TR1 = 1;
	        outSignalStart = 0x00;
	        time0Count2 = 0;                      //计数器清零
	        outStart == 0x00;
	    }*/
	}
     }
     lastOilSignal = OilSignal;
     
     if(++base==800){      //0.4秒信号
     	base = 0;
     	TSignal|=SI_HSEC;
     }     
     //产生模拟输入信号
     if(base%200==0) 
        testLed = 0;
     else
        testLed = 1;
     
     if(base>402&&base<402+SI_WIDTH){
     	simLed = 1;
     }else if(base>2&&base<2+SI_WIDTH){
     	simLed = 1;
     }else
        simLed = 0;   
}
//--------------------------------------------------------------------------
//点火信号处理
//--------------------------------------------------------------------------
void  firePrev()
{
	if(FireSignal==0xFF)      //点火信号到
    	{
   	   fireLed = 1;
   	   timeFireSignal = time0Count;  //记录
      	   time0Count = 0;               //清零     
      	   
      	   I1 = timeFireSignal>>2;
      	   I2 = inputAngle>>3;
      	   outTimeFire = ((I1*I2)>>4);
      	}
      	FireSignal = 0x00;
      	fireLed = 0;
}
//--------------------------------------------------------------------------
//输出信号处理
//--------------------------------------------------------------------------
void  outPrev()
{
	if(outSignalStart==0xFF){	   
           if(time0Count2>outTimeDelay){              	
               TH1 = (0xFFFF-timeOilSignal*500)/256;
               TL1 = (0xFFFF-timeOilSignal*500)%256;
               TR1 = 1;
               OutSignal = 0;                        //置输出为低电平
               time0Count2 = 0;                      //计数器清零
               outSignalStart = 0x00;
           }
	}else{
	   if(time0Count2>timeOilSignal){
           	TR1 = 0;
           	OutSignal = 1;
           	time0Count2 = 0;
           }
	}
}
//--------------------------------------------------------------------------
//键盘处理
//--------------------------------------------------------------------------
void  keyPrev()
{	
	XBYTE[P8155IA] = 0xFF;
    	keynum = ~XBYTE[P8155IC];
    	    	
    	if((keynum&0x01) == 0x01){ //下8
    	   runLed = 1;    	   
    	 /*  if(keydown==1) return;  //本次按键已经生效
    	   
    	   if(time0Key<20)         //延时10ms 去抖动
    	       return;
    	   
    	   for(i=0;i<8;i++){      //列扫描
    	       XBYTE[P8155IA] = ~(SI_HSEC<<i);
    	       keynum = XBYTE[P8155IC];    	       
    	       if( (keynum&0x01) == 0x01){   //列扫描有键按下    	              	           
    	           if(i<2){
    	           	keyLed = 1;
    	           	tkAngle = keyAngle*10;
    	           	keyAngle = tkAngle + i;
    	           	keyAngle += 8;
    	           }else if(i==4){       // 确定
    	                if(keyAngle<300)
    	                   inputAngle = keyAngle;
    	                keyAngle = 0;
    	           }else if(i==7){       //取消
    	           	keyAngle = 0;
    	           }
    	   	   break;
    	       }
    	   }*/
    	}else if((keynum&0x02) == 0x02){ //上8
    	   if(keydown==2) return;        //本次按键已经生效    	   
    	   if(time0Key<20)               //延时10ms 去抖动
    	       return;
    	   
    	   for(i=0;i<8;i++){             //列扫描
    	       XBYTE[P8155IA] = ~(SI_HSEC<<i);
    	       keynum = XBYTE[P8155IC];    	       
    	       if( (keynum&0x02) == 0x02){   //列扫描有键按下
    	       	   if(i==0){                 //归零
    	       	   	inputAngle = 0x00;
    	       	   }else if(i==1){           //步厂10增加
    	       	      inputAngle+=10;
    	       	   }else if(i==2){           //步长20增加
    	       	      inputAngle+=20;
    	       	   }else if(i==5){           //步长10减少
    	       	      inputAngle-=10;
    	       	   }
    	       	   if(inputAngle>512)        //太大归零
    	       	     inputAngle=0;
    	   	   keydown = 2;
    	   	   break;
    	       }
    	   }
    	}else{
    	   time0Key = 0;
    	   keydown = 0;    	   
    	}
}

⌨️ 快捷键说明

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