?? 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 + -