📄 2007.5.31.c
字号:
// 目标器件: STC12C5052AD
// 系统频率: 内部时钟,4~8M.
#include <STC12C2052AD.H>
#include <intrins.h>
sbit Beep = P1^5;//蜂鸣器
sbit Relay1 = P3^0;//继电器1
sbit Pulse_Input = P3^3;//脉冲输入
//sbit Relay2 = P3^1;//继电器2
//sbit STOP = P1^6;//接近开关复位信号
//sbit RETC = P1^7;//接近开关电源控制
#define uint unsigned int
#define uchar unsigned char
#define DogReset() WDT_CONTR=0x36
#define SetDriveOff() {PCA_PWM0=0X03;} // 使驱动口固定输出高电平.
#define SetDriveOn() {PCA_PWM0=0X00;} // 使驱动口固定输出高电平.
#define vBtnVal_Null 0x00 // ceeback/20070316
#define vBtnVal_StartUp 0x01 //起停
#define vBtnVal_HiSpeed 0x02 //高速
#define vBtnVal_MiSpeed 0x04 //中速
#define vBtnVal_LoSpeed 0x08 //低速
//#define vBtnVal_Reverse 0x10 //反向
#define vBtnAct_Null 0
#define vBtnAct_Push 1
#define vBtnAct_Pop 2
#define vBtnAct_Keep 3
// T0 定时 0.1ms.作为系统计时用,
#define vT01ms 10
#define vT10ms 10
#define vT100ms 10
#define vT01S 10 // 1 s = 10 ms * 100
#define vT1HVal 0xff //0xfe //0xf6
#define vT1LVal 0x9c //0x0c //0x4c
#define ACTIVE_TIME 170 // 按键有效持续时间180
#define WaitSpeed 0
#define LoSpeed 1
#define MiSpeed 2
#define HiSpeed 3
#define StopSpeed 4
#define STOP 1
#define WORK 0
uchar KeyNum;
uchar cBtnVal; // 按钮取值
uchar SpeedType;
uchar ctemp;
uchar cSpeed;
//uchar PulseCount; //脉冲计数
uchar Pre_pulselength; //脉冲长度
uint Fact_pulselength; //脉冲长度
//uint R_pulselength; //读取脉冲长度
//uchar Pre_Pulse; //预设每秒脉冲数
//uchar Fact_Pulse; //实际每秒脉冲数
// 定时器延时
uchar cT01ms = vT01ms;
uchar cT10ms = vT10ms;
uchar cT100ms = vT100ms;
uchar cT01s = vT01S;
uchar StopTimer; //电机失速保护,在连续5秒超速,则判断MOS损坏,切断继电器
uchar changeTimer;
uchar cDY_Clock; // 时钟修改超时计时
uchar autotimer; //无速度反馈定时器,超过两秒没有速度反馈,则关闭PWM
uchar BeepTime;
bit b_Power; // 电机起停标志
bit SpeedFlag;
bit b_PulseIn;
bit SpeedControl;//速度控制模式选择
//bit b_NoFeedback;
//bit FeedbackFlag;
//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------
void Para_initial(void);
/**************************************************************************
* 函数原型: void delay_ms(uint Count)
* 功 能: 延时Count个ms
**************************************************************************/
void delay_ms(register uint Count)
{
register uchar T;
for(;Count>0;Count--)
{
for(T=0;T<80;T++)
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
DogReset();
}
}
/**************************************************************************
* 函数原型: uchar ButtonScan(void);
* 功 能: 对按钮进行扫描,返回按钮值
**************************************************************************/
uchar key_scan(void)
{
uchar ikey;
ikey=~(P1&0x0f)&0x0f;
return(ikey&0x0f);
}
/**************************************************************************
* 函数原型: uchar ButtonScan(void);
* 功 能: 对按钮进行扫描,返回按钮值
**************************************************************************/
uchar ButtonAction(void)
{
uchar cButton;
cButton=key_scan();
if(cButton==cBtnVal)
{
if(cButton==vBtnVal_Null) // 无按键
return(vBtnAct_Null);
else // 按键保持
return(vBtnAct_Keep);
}
else
{
delay_ms(20);
if(key_scan()==cButton)
{
cBtnVal=cButton;
if(cButton==vBtnVal_Null) // 按键弹起
return(vBtnAct_Pop);
else // 按键按下
return(vBtnAct_Push);
}
}
}
/**************************************************************************
* 函数原型: void ButtonHandle(void);
* 功 能: 处理按钮输入
**************************************************************************/
void ButtonHandle(void)
{
uchar cBtnType;
DogReset();
cBtnType=ButtonAction();
if(cBtnType==vBtnAct_Push)
{
BeepTime=5;
SpeedControl=0;//快速加速或减速
switch(cBtnVal)
{
case vBtnVal_StartUp:
if(++KeyNum>3){
KeyNum=0;
}
switch(KeyNum){
case WaitSpeed:
// EX0=0;
// Pre_pulselength=0;
b_Power=STOP;
cSpeed = 0xff;
SpeedType = StopSpeed;
cDY_Clock = 0xff;
break;
case LoSpeed:
// EX0=1;
b_Power = WORK;
changeTimer=10;
cSpeed = 0xc0;
CCAP0H =0xe0;
Pre_pulselength=16;
SpeedType = HiSpeed;
cDY_Clock = ACTIVE_TIME;
Relay1=0;//继电器吸合
break;
case MiSpeed:
// EX0=1;
b_Power = WORK;
cSpeed = 0xc0;
Pre_pulselength=16;
SpeedType = MiSpeed;
cDY_Clock = ACTIVE_TIME;
Relay1=0;//继电器吸合
break;
case HiSpeed:
// EX0=1;
b_Power = WORK;
Pre_pulselength=8;
cSpeed = 0x70;
SpeedType = LoSpeed;
cDY_Clock = ACTIVE_TIME;
Relay1=0;//继电器吸合
break;
default:
break;
}
default:
break;
}
DogReset();
}
}
/**************************************************************************
* 函数原型: void F_SpeedControl(void);
* 功 能: 启动阶段处理速度变化
**************************************************************************/
void F_SpeedControl(void){
if(ctemp!=cSpeed){
if(ctemp<cSpeed){
ctemp++;
}
else{
ctemp--;
}
}
else{
SpeedControl=1;
}
if(ctemp==0xff&&(b_Power == STOP)){
Relay1=1;//继电器断开
}
CCAP0H = ctemp;
}
/**************************************************************************
* 函数原型: void F_SpeedControl(void);
* 功 能: 处理速度变化(ctemp采用模糊范围控制,Pre_Pulse 脉冲采用精确控制)
**************************************************************************/
void E_SpeedControl(void){
/* if(b_Power==STOP){
if(ctemp!=0xff){
ctemp++;
}
else{
Para_initial();
}
}
else{*/
if(Fact_pulselength!=Pre_pulselength){
if(Fact_pulselength>Pre_pulselength){
if(ctemp--<0x10){
ctemp=0x10;
}
}
else{
if(ctemp++>0xe0){
ctemp=0xe0;
}
}
}
// }
CCAP0H = ctemp;
}
/**************************************************************************
* 函数原型: void Para_initial(void);
* 功 能: 参数初始化
**************************************************************************/
void Para_initial(void)
{
SetDriveOff();
b_Power = STOP;
SpeedType = WaitSpeed;
autotimer=0;
cDY_Clock = 0xff;
StopTimer=0;
changeTimer=0xff;
ctemp=0xff;
cSpeed = 0xff;
SpeedFlag=0;
// PulseCount=0;
// FeedbackFlag=0;
Relay1=1;//继电器断开 KeyNum=0;
SpeedControl=0;
Fact_pulselength=0;
// Pre_pulselength=0;
// b_NoFeedback=0;
// TR1=0;
// EX0=0;
b_PulseIn=1;
}
/**************************************************************************
* 函数原型: void system_initial(void);
* 功 能: 系统初始化
**************************************************************************/
void system_initial(void)
{
Relay1=1;//继电器断开
DogReset(); // 已针对 STC89C58RD+ 作修改.06-04-06
SCON =0x50;
TMOD =0x12; // T1:Time 16bit; T0:8位自动重装载.
TH0 =0xff; // T0 溢出作为PCA计数器脉冲来源.
TL0 =0xff; //0xFE----976Hz 0xFF----1953Hz
TH1 =vT1HVal; // T1:系统计时.
TL1 =vT1LVal;
TCON =0x55; // TR0=1,外部中断0,1都是下降沿触发
IP =0x08; // T1 优先级高
// IP =0x01; // INT0 优先级高
// PWM 配置.
CMOD =0X84;
CCAPM0 =0X42; // pca 模块0 8位PWM方式.
CCAP0H =0Xff;
Para_initial();
IE =0x88; // 开 T1 中断
CR =1; // 启动PWM.
// EX0=1; //开启外部中断0,下降沿触发
AUXR|=0x80;//T0单周期指令,PWM加快12倍
}
/**************************************************************************
* 函数原型: void main(void);
* 功 能: 主程序
**************************************************************************/
void main(void)
{
system_initial();
BeepTime=5;
while(1)
{
DogReset();
ButtonHandle();
if(b_Power==WORK){
// TR1=1;
SetDriveOn();
}
/*第一档速度切换部分*/
if(SpeedType == HiSpeed){
if(!changeTimer){
SpeedFlag=!SpeedFlag;
if(!SpeedFlag){
Pre_pulselength=16;
cSpeed = 0xc0;
}
else{
Pre_pulselength=8;
cSpeed = 0x70;
}
changeTimer=10;
}
}
//
/*3分钟时间到,停止运行*/
/*此处增加判断有无转速反馈,若启动后仍没有反馈,则关断PWM输出,重新开始*/
/*失速保护,在MOS管损坏后,由于电机失速,在连续5S内一直超速,则关闭继电器,切断电机运行*/
if((StopTimer>5)|(autotimer>2)|(!cDY_Clock)|(ctemp==0xff&&(b_Power==STOP))){
Para_initial();
}
}
}
/**************************************************************************
* 函数原型: void Trint1(void) interrupt 1 using 1;
* 功 能: 全局定时
**************************************************************************/
void T1_INT(void) interrupt 3 using 2
{
TH1 = vT1HVal; // 时基0.1ms
TL1 = vT1LVal;
if(!(--cT01ms)){
cT01ms=vT01ms;
Fact_pulselength++;
if(b_PulseIn!=Pulse_Input){//&&!Pulse_Input){//每次上升沿检测脉宽,控制速度
b_PulseIn=Pulse_Input;
if(SpeedControl){
E_SpeedControl();
}
Fact_pulselength=0;
autotimer=0;
}
if(!(--cT10ms)){
cT10ms=vT10ms;
if(!SpeedControl){
F_SpeedControl();
}
if(!(--cT100ms))
{
cT100ms=vT100ms;
if(BeepTime!=0xff){//蜂鸣器计时器
if(BeepTime!=0x00){
BeepTime--;
Beep=0;
}
else{
Beep=1;
}
}
else{
Beep=1;
}
if(!(--cT01s)){
cT01s=vT01S;
if(b_Power == WORK) // 时钟模式的空闲等待时间
{
if(cDY_Clock!=0xff){
if(cDY_Clock!=0x00){
cDY_Clock--;
}
}
}
if(changeTimer!=0xff){//高低速度切换时间10S
if(changeTimer!=0x00){
changeTimer--;
}
}
if(Fact_pulselength<Pre_pulselength){//当实际检测速度大于设定值时,开始计时
StopTimer++;
}
else{
StopTimer=0;
}
if(b_Power == WORK){//没有反馈时开始计时
autotimer++;
}
}
}
}
}
}
/**************************************************************************
* 函数原型: void int0(void) interrupt 0 using 0;
* 功 能: 转速反馈,外部中断0
**************************************************************************/
/*
void int0(void) interrupt 0 using 0
{
FeedbackFlag=!FeedbackFlag;
autotimer=0;
b_NoFeedback=1;
Fact_pulselength=0;
// PulseCount++;
/* if(++PulseCount>Pre_Pulse){//也可作为复位用,判断多少脉冲为一个循环,这样便于判断起始位置
Fact_Pulse=PulseCount;
PulseCount=0;
}*/
/*}
/**************************************************************************
* END
* END
**************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -