📄 mainkey01ok.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;
#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; //程序正常标志
UINT timeFireSignal; //点火信号周期(0.1ms单位)
UINT timeOilSignal; //喷油信号宽度(0.1ms单位)
UINT outTimeFire,outTimeDelay; //输出点火时间
UINT inputAngle,keyAngle,tkAngle; //当前角度/键盘输入角度
UCHAR keydown;
static UINT time0Count,time0Count1,time0Count2,time0Key; //计数器
volatile UINT base,i; // 基本定时单元
UCHAR outSignalStart; //输出信号开始标志
void firePrev(); //点火信号处理
void outPrev(); //输出信号处理
void keyPrev(); //键盘处理
//--------------------------------------------------------------------------
// 变量初始化子程序
//--------------------------------------------------------------------------
void init()
{
inputAngle = 60;
timeOilSignal = 0;
outTimeFire = 0;
time0Count = 0;
time0Count1 = 0;
time0Count2 = 0;
time0Key = 0;
keydown = 0;
OilSignal = 0;
lastOilSignal = 0;
FireSignal = 0;
lastFireSignal = 0;
outSignalStart =0x00;
outTimeDelay = 0xFFFF;
tkAngle = 0xFF;
}
//--------------------------------------------------------------------------
// 系统初始化,初始化寄存器
//--------------------------------------------------------------------------
void initsys()
{
EA = 1;
ET0 = 1;
ET1 = 1;
PT1 = 1;
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;
}
//--------------------------------------------------------------------------
// 主程序
//--------------------------------------------------------------------------
void main(void)
{
init();
initsys();
while(1){
firePrev(); //处理点火信号
outPrev(); //输出信号处理
if(TSignal&SI_HSEC) // 半秒消息信号
{
TSignal&=~SI_HSEC; // 清除半秒消息信号标志
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;
}
}else{
OilSignal=0x00;
if(lastOilSignal==0xFF){ //喷油信号上升沿
timeOilSignal = time0Count1;
outTimeDelay = outTimeFire;
time0Count2 = 0;
outSignalStart = 0xFF;
}
}
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; //清零
outTimeFire = timeFireSignal*25;
timeFireSignal = outTimeFire/3;
outTimeFire = timeFireSignal*inputAngle;
timeFireSignal = outTimeFire/6;
outTimeFire = timeFireSignal/500;
}
FireSignal = 0x00;
fireLed = 0;
}
//--------------------------------------------------------------------------
//输出信号处理
//--------------------------------------------------------------------------
void outPrev()
{
if(outSignalStart==0xFF){
if(time0Count2>outTimeDelay)
{
// EA = 0;
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()
{
if(keyAngle>30)
keyAngle = 0;
XBYTE[P8155IA] = 0xFF;
keynum = ~XBYTE[P8155IC];
if((keynum&0x01) == 0x01){ //下8
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){
tkAngle = keyAngle*10;
keyAngle = tkAngle + i + 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){ //列扫描有键按下
tkAngle = keyAngle*10;
keyAngle = tkAngle + i;
tkAngle = i+1;
keydown = 2;
break;
}
}
}else{
time0Key = 0;
keydown = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -