📄 retarder.c
字号:
#include <REG768.H>
#include <stdio.h>
#include <intrins.h>
//常变量定义区,端口位定义
sbit SDA=P1^3; //I2c数据传送位
sbit SCL=P1^2; //I2c时钟控制位
sbit Inputsignal1=P0^3;
sbit Inputsignal2=P0^4;
sbit Inputsignal3=P0^5; //设定为外部7档的输入口
sbit Inputsignal0=P0^6; //有些产家在档位突变之下定义的另外一脚
sbit speed=P1^4; //INT1为外部里程表信号输入口
sbit brakeLamp=P0^7; //刹车灯信号标记
sbit speedStatus1=P1^1;
sbit speedStatus2=P1^0; //选取多少公里以下不工作。
sbit speedStatus3=P0^2;//三种速度状态的选择
sbit pwm0=P0^1;
sbit pwm1=P1^6;
sbit pwm2=P1^7;
sbit pwm3=P0^0; //P0.0,P1.7,P1.6,P0.1为外部PWM输出控制口
//变量定义区
#define unchar unsigned char //宏指令8位无符号整型
#define min1Fre 0x30 //Retarder工作时最低频率选择位1
#define min2Fre 0x40 //Retarder工作时最低频率选择位2
#define min3Fre 0x50 //Retarder工作时最低频率选择位3
unsigned long OldspeedSignal; //判断外部脉冲多少
unsigned long NewspeedSignal;
bit status=1; //判断工作状态进入缓速要求
void initData(void);
void fnc0Level(void);
void fnc1Level(void);
void fnc2Level(void);
void fnc3Level(void);
void fnc4Level(void);
void fnc5Level(void);
void fnc6Level(void);
void fncSameLevel(void);
void fncSundenLevel(void); //速度突变档的控制
void OutputPwm(unchar road,unchar pwmH,unchar pwmL);
unchar getStatus(void);
void delay(unsigned int k);
void main(void)
{
unchar value=0;
bit flag;
flag=1; //判断速度是否大于所需要的缓速器工作的值
P1=0x0FF;
initData();
value=0;
_nop_();
do
{
/*在速度低于瓶限值是缓速器不工作.speed
*/
while(flag)
{
if (speedStatus1==1)
{
if(OldspeedSignal>min1Fre) flag=0,status=1;
}
if (speedStatus2==1)
{
if(OldspeedSignal>min2Fre) flag=0,status=1;
}
if (speedStatus3==1)
{
if(OldspeedSignal>min3Fre) flag=0,status=1;
}
}
while(status)
{
value=getStatus();
switch(value)
{
// case (0x01<value<0x0C): fnc0Level(); break;
case 0: fnc0Level(); break; //空挡
case 1: fncSameLevel(); break; //横速
case 2: fnc1Level(); break; //档位1
case 3: fnc2Level(); break; //档位2
case 4: fnc3Level(); break; //档位3
case 5: fnc4Level(); break; //档位4
case 6: fnc5Level(); break; //档位5
case 7: fnc6Level(); break; //档位6
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:fncSundenLevel(); break; //档位突变
default: break;
}
}
}while(1);
}
//空挡下不利用DIVM的值来进行分解频率的采样
//由于车速对对单片机周期而言太慢了:该信号取自里程表的信号
void fnc0Level(void)
{
unchar value;
DIVM=0x00;
brakeLamp=0;
value=getStatus();
if (value==0)
{
OutputPwm(0,0,0); //关掉制动力
delay(1000);
status=0; //退回速度侦测,是否要进入速度制动范围
}
else status=1; //返回判断档位
}
////////////////////////////
//横速档,开TIMER0取判断多少时间来进行横速改为延时来判断
void fncSameLevel(void)
{
unsigned long temp;//temp为当前按下横速档的值
bit flag=1;
unchar road,pwmH,pwmL;
unchar value;
// TR0=1;
temp=OldspeedSignal;
do
{
if(temp<OldspeedSignal)
{
//减少制动力
road--;
OutputPwm(road,pwmH,pwmL);
}
if(temp>OldspeedSignal)
{
//增加制动
road++;
OutputPwm(road,pwmH,pwmL);
}
delay(1000);
value=getStatus();
if(value=0) status=0,flag=0; //退回速度侦测,是否要进入速度制动范围
if(value<9) flag=0; //返回判断档位
}while(flag);
// TR0=0;
}
void fnc1Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==2) flag=0;
} while(flag);
}
void fnc2Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==3) flag=0;
} while(flag);
}
void fnc3Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==4) flag=0;
} while(flag);
}
void fnc4Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==5) flag=0;
} while(flag);
}
void fnc5Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==6) flag=0;
} while(flag);
}
void fnc6Level(void)
{
unchar CYCH,CYCL,value;
bit flag;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00;
CPSW4=pwmH; //各两位控制每个极性的高电平
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
do
{
value=getStatus();
if (value==7) flag=0;
} while(flag);
}
void initData(void)
{
Inputsignal1=1;
Inputsignal2=1;
Inputsignal3=1;
Inputsignal0=1;
speedStatus1=1;
speedStatus2=1;
speedStatus3=1;//三种速度状态的选择
speed=1; //定义为数据输入方式
// SP=0x50; //设置堆栈地址为50H
DIVM=0x00; //CPU时钟2分频
/* When the DIVM register is set to some value N (between 1 and 255),
the CPU clock is divided by 2 * (N + 1).*/
P0M1=0x00; //P0 MODE1 and MODE2
P0M2=0xFF; //P0端口定义
//21~28==00
// ACC=0x00;
// B=0x10;
TMOD=0x01;
//01:16-bit Timer/Counter “THn” and “TLn” are cascaded; there is no presc
//for time1 and time0 as enble, not count and INT
EA=1; //总中断允许;
// TR0=1; //启动定时器0;
TCON=0xC8;
TMOD=0x10;
TR1=1; //启动定时器0
//Timer 0 Run control bit. Set/cleared by software to turn Timer/Counter 0 on/off.
IT1=1;
/*Interrupt 1 Type control bit. Set/cleared by software to specify falling edge/low level triggered
external interrupts.*/
ET0=1; //定时器0中断使能
EX1=1; //INT1中断使能
IP0=0x78;
IP0H=0x7B;
/*Each interrupt source can be individually programmed to one of four
priority levels by setting or clearing bits in the IP0, IP0H, IP1, and
IP1H registers*/
brakeLamp=0; //清除刹车标记回到初始状态
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制 最大值为3FF;
}
//控制几路输出,并控制占空比
void OutputPwm(unchar road,unchar pwmH,unchar pwmL)
{
unchar CYCH,CYCL;
CNSW0=CYCL; //四路共用一个周期
CNSW1=CYCH; //周期控制
CPSW0=pwmL;
CPSW1=pwmL;
CPSW2=pwmL;
CPSW3=pwmL;
CPSW4=pwmH; //各两位控制每个极性的高电平
//宽度固定
switch(road)
{
case 1: CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00; break;
case 2: CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00; break;
case 3: CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00; break;
case 4: CPSW0=pwmL,CPSW1=0x00,CPSW2=0x00,CPSW3=0x00; break;
case 5: CPSW0=pwmL,CPSW1=0x00,CPSW2=pwmL,CPSW3=0x00; break;
// case 3: CPSW0=pwmL,CPSW1=pwmL,CPSW2=0pwmL,CPSW3=0x00; break;
// case 4: CPSW0=pwmL,CPSW1=pwmL,CPSW2=0pwmL,CPSW3=pwmL; break;
default: break;
}
PWMCON0=0xC2; //启动PWM,使用新数据,高电平有效
}
void switchNum(unchar n)
{
unchar value;
switch (n)
{
case 0: value=0x7E; break;
case 1: value=0x0C; break;
case 2: value=0xB6; break;
case 3: value=0x9E; break;
case 4: value=0xCC; break;
case 5: value=0xDA; break;
case 6: value=0xFA; break;
case 7: value=0x0E; break;
case 8: value=0xFE; break;
case 9: value=0xDE; break;
default:break;
}
P0=value;
}
unchar getStatus(void) //是否需延时来增加判断的可靠性
{
unchar value=0;
value=value|Inputsignal0; //位或
value=value<<1; //左移一位
value=value|Inputsignal1; //位或
value=value<<1; //左移一位
value=value|Inputsignal2; //位或
value=value<<1; //左移一位
value=value|Inputsignal3; //位或
// value=value<<1; //左移一位
printf("value is %d",value);
value=value&0x0F;
return value;
}
void delay(unsigned int k)
{
unsigned int i,j;
for(i=0;j<k;i++)
for(j=0;j<100;j++);
}
void timer0(void) interrupt 5 using 1
{
/* CLR TF0
PUSH ACC
PUSH PSW
CLR TR0
MOV TL0,#00H
MOV TH0,#23H
DJNZ B,LOOP
MOV 25H,21H
MOV 21H,#00H
MOV 26H,22H
MOV 22H,#00H
MOV 27H,23H
MOV 23H,#00H
MOV 28H,24H
MOV 24H,#00H
MOV B,#10H
LOOP:
SETB TR0
POP PSW
POP ACC
RETI
/*TF0 = 0;
*/
}
///////////////////////////////////////////////
//利用timer1和INT1记录外部中断次数,来判断速度
void timer1(void) interrupt 4 using 1
{
unsigned long x;
TR1=0; //暂停定时器1
OldspeedSignal=NewspeedSignal;
NewspeedSignal=0;
TH1=0x00; //对timer1重新赋值
TL1=0x00;
TR1=1; //开定时器1
}
//////可利用TIMER1当记数器
void int1(void) interrupt 3 using 1
{
NewspeedSignal++;
}
/* PUSH ACC
PUSH PSW
INC 24H
MOV A,24H
CJNE A,#09H,GOON
MOV 24H,#00H
INC 23H
MOV A,23H
CJNE A,#09H,GOON
MOV 23H,#00H
INC 22H
MOV A,22H
CJNE A,#09H,GOON
MOV 22H,#00H
INC 21H
GOON:
POP PSW
POP ACC
RETI */
//}
/* ORG 0FD00H
DB 28H*/
/*void start(void)
{
EA=1; //总中断允许;
TR0=1; //启动定时器0;
//Timer 0 Run control bit. Set/cleared by software to turn Timer/Counter 0 on/off.
IT1=1;
/*Interrupt 1 Type control bit. Set/cleared by software to specify falling edge/low level triggered
external interrupts.*/
/* ET0=1; //定时器0中断使能
EX1=1; //INT1中断使能
IP0=0x78;
IP0H=0x7B;
/*Each interrupt source can be individually programmed to one of four
priority levels by setting or clearing bits in the IP0, IP0H, IP1, and
IP1H registers*/
//}//read out data to adjust which status is?
/* ACC=0x00;
AC=Inputsignal0;
ACC=ACC<<1;
AC=Inputsignal1;
ACC=ACC<<1;
AC=Inputsignal2;
ACC=ACC<<1;
AC=Inputsignal3;
ACC=ACC<<1;*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -