📄 复件 mocontrol.c
字号:
// 目标器件: STC89C58RD+
// 系统频率: 晶振 12 M, 烧写时设置单倍速
// 硬件电路过0检测偏慢约 256 us.
// 针对 220V,50HZ.系统设计.
// 可控硅门极脉冲宽度固定为 100 us.导通角以100 us步进.
#include <STC89C58.H>
#include <intrins.h>
sbit Drive = P3^7;
sbit LED = P3^5; // LED 低电平驱动.
#define uint unsigned int
#define uchar unsigned char
#define DogReset() WDT_CONTR=0x36
#define vBtnVal_Null 0xF0 // ceeback/20070316
#define vBtnVal_StartUp 0xF1 //起停
#define vBtnVal_HiSpeed 0xF2 //高速
#define vBtnVal_MiSpeed 0xF4 //中速
#define vBtnVal_LoSpeed 0xF8 //低速
//#define vBtnVal_Reverse 0x10 //反向
#define vBtnAct_Null 0
#define vBtnAct_Push 1
#define vBtnAct_Pop 2
#define vBtnAct_Keep 3
// T0 定时 10ms.作为系统计时用,
#define vT01S 100 // 1 s = 10 ms * 100
#define vT0HVal 0XD8
#define vT0LVal 0XF0
#define ACTIVE_TIME 900 // 按键有效持续时间 900
#define WaitSpeed 0
#define HiSpeed 1
#define MiSpeed 2
#define LoSpeed 3
uchar cBtnVal; // 按钮取值
uchar SpeedType;
uint temp;
// 定时器延时
uchar cT01s = vT01S;
uint cDY_Clock; // 时钟修改超时计时
//bit Drive_bit = 0;
//bit Triger_bit = 0; // 外部触发标志 ceeback/ 20070316
bit b_Power; // 电机起停标志
#define STOP 1
#define WORK 0
#define PNP_OFF 1
#define PNP_ON 0
uchar open_delay_100us=0;
uint scr_delay_time;
uchar t1_int_type; // t1 中断类型
#define NEG_ZERO_COMPENSATE 0XFF // 负半周过0点补偿
#define NEG_SCR_DELAY_TIME 0XFE // 负半周可控硅开启相对过0点延迟时间.
#define NEG_SCR_HOLD_TIME 0XFD // 负半周可控硅门极脉冲维持时间
#define WAIT_POSITIVE 0XFC // 等待正半周到达.
#define POS_ZERO_COMPENSATE 0XFB // 正半周过0点补偿
#define POS_SCR_DELAY_TIME 0XFA // 正半周可控硅开启相对过0点延迟时间.
#define POS_SCR_HOLD_TIME 0XF9 // 正半周可控硅门极脉冲维持时间
// 定时器1延时时间宏.
#define T1_DELAY_500uS_H 0XFE
#define T1_DELAY_500uS_L 0X0C
#define T1_DELAY_500uS 0XFE0C
#define T1_DELAY_100uS 0XFF9C
#define T1_DELAY_1MS 0XFC18
#define T1_DELAY_2MS 0XF830
#define T1_DELAY_2D5MS 0XF63c // 2.5ms
#define T1_DELAY_3MS 0XF448
#define T1_DELAY_4MS 0XF060
#define T1_DELAY_5MS 0XEC78
#define T1_DELAY_6MS 0XE890
#define T1_DELAY_7MS 0XEA48
//-----------------------------------------------------------------------------
// 函数声明
//-----------------------------------------------------------------------------
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)
{
register uchar temp;
P1 = 0XFF;
temp = P1;
temp &= 0x0f;
temp =~ temp;
return(temp);
}
/**************************************************************************
* 函数原型: uchar ButtonAction(void);
* 功 能: 按钮动作类型
返 回 值: 当按钮为空, 返回值为vBtnType_Null=0
当按钮按下时,返回值为vBtnType_Push=1
当按钮弹起时,按回值为vBtnType_Pop =2
当按钮长按时,返回值为vBtnType_Keep=3
当按钮同时按下时,返回值为vBtnVal_All=0x30
*************************************************************************/
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)
{
//cBtnValPre=cBtnVal;
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)
{
switch(cBtnVal)
{
case vBtnVal_StartUp:
b_Power=!b_Power;
LED = b_Power; // 驱动LED.
if(b_Power==STOP)
Para_initial();
else // ceeback added 2007.03.16
{
//b_Power = WORK;
SpeedType = WaitSpeed;
cDY_Clock = ACTIVE_TIME;
}
break;
case vBtnVal_HiSpeed:
if(b_Power == WORK)
{
SpeedType = HiSpeed;
TR1 = 0; // 一直导通.
Drive = PNP_ON;
cDY_Clock = ACTIVE_TIME;
}
break;
case vBtnVal_MiSpeed:
if(b_Power == WORK)
{
SpeedType = MiSpeed;
open_delay_100us ++;
if(open_delay_100us>=81)
open_delay_100us = 81;
//open_delay_100us = 30;
scr_delay_time = 0xFFFF - 0x64 * open_delay_100us; // 延时以 100 us 步进.
cDY_Clock=ACTIVE_TIME;
}
break;
case vBtnVal_LoSpeed:
if(b_Power == WORK)
{
SpeedType = LoSpeed;
open_delay_100us = 55;
scr_delay_time = 0xFFFF - 0x64 * open_delay_100us;
//scr_delay_time = 0xe890;
//scr_delay_time = T1_DELAY_7MS;
cDY_Clock=ACTIVE_TIME;
}
break;
default:break;
}
}
DogReset();
}
/**************************************************************************
* 函数原型: void speed_control(void);
* 功 能: 处理按钮输入
**************************************************************************/
void speed_control(void) /*reentrant*/
{
if(b_Power== WORK)
{
switch(SpeedType)
{
//case HiSpeed: // 高速
// Drive = PNP_OFF;
// TH1= T1_DELAY_1MS_H;
// TL1= T1_DELAY_1MS_L;
// TR1 = 1;
// Triger_bit = 1;
// break;
/*case HiSpeed: // 高速,一直导通.
TR1 = 0;
Drive = PNP_ON;
break;*/
case MiSpeed:
Drive = PNP_OFF;
TH1 = T1_DELAY_500uS_H;
TL1 = T1_DELAY_500uS_L;
TR1 = 1;
t1_int_type = NEG_ZERO_COMPENSATE;
break;
case LoSpeed:
Drive = PNP_OFF;
TH1 = T1_DELAY_500uS_H;
TL1 = T1_DELAY_500uS_L;
TR1 = 1;
t1_int_type = NEG_ZERO_COMPENSATE;
break;
default:break;
}
/*TH1 = T1_DELAY_300uS_H;
TL1 = T1_DELAY_300uS_L;
TR1 = 1;
Drive = PNP_OFF;
t1_int_type = ZERO_COMPENSATE;*/
}
}
/**************************************************************************
* 函数原型: void Para_initial(void);
* 功 能: 处理按钮输入
**************************************************************************/
void Para_initial(void)
{
Drive = PNP_OFF;
TR1 = 0;
b_Power = STOP;
LED = b_Power; // 低电平驱动LED.
SpeedType = WaitSpeed;
t1_int_type = 0X00;
cDY_Clock = 0xffff;
open_delay_100us = 0;
}
/**************************************************************************
* 函数原型: void system_initial(void);
* 功 能: 处理按钮输入
**************************************************************************/
void system_initial(void)
{
DogReset(); // 已针对 STC89C58RD+ 作修改.06-04-06
SCON=0x50;
TMOD=0x11; // T1,T0:Time 16bit
TCON=0x15; // TR0=1,外部中断0,1都是下降沿触发
//TH1=0xfd; // T1 的初值根据延时要求不同而改变,在外部中断中设置.
//TL1=0xfd;
TH0=vT0HVal;
TL0=vT0LVal;
IP=0x08; // T1 优先级高
//AUXR=0x02;//ALE为1/6FOSC,外部XRAM
Para_initial();
IE=0x8F; // 开外部0,1,T0,T1中断
EX0=0; // 关闭外部中断0. 2007.03.19
}
/**************************************************************************
* 函数原型: void main(void);
* 功 能: 处理按钮输入
**************************************************************************/
void main(void)
{
system_initial();
while(1)
{
DogReset();
ButtonHandle();
if(!cDY_Clock)
Para_initial();
}
}
/**************************************************************************
* 函数原型: void Trint0(void) interrupt 1 using 1;
* 功 能: 全局定时
**************************************************************************/
void T0_INT(void) interrupt 1 //using 1
{
TH0 = vT0HVal; // 时基10ms
TL0 = vT0LVal;
if(!(--cT01s))
{
cT01s=vT01S;
if(b_Power == WORK) // 时钟模式的空闲等待时间
{
if(cDY_Clock > 0x00)
--cDY_Clock;
}
}
}
void T1_INT(void) interrupt 3 //using 1
{
switch(t1_int_type)
{
case NEG_ZERO_COMPENSATE: // 零点补偿完毕,接着应该进行开启可控硅之前的延时.
Drive = PNP_OFF;
TH1 = (uchar)(scr_delay_time>>8);
TL1 = (uchar)(scr_delay_time);
t1_int_type = NEG_SCR_DELAY_TIME;
TR1 = 1;
break;
case NEG_SCR_DELAY_TIME: // 开启之前的延时完毕后,就要开启可控硅.
Drive = PNP_ON;
TH1 = (uchar)(T1_DELAY_1MS>>8); // 可控硅固定开启时间 100 us.
TL1 = (uchar)T1_DELAY_1MS;
t1_int_type = NEG_SCR_HOLD_TIME;
TR1 = 1;
break;
case NEG_SCR_HOLD_TIME: // 延时到正半周起始点.
Drive = PNP_OFF;
temp = 0xD954 + open_delay_100us * 0x64+ 0X64*10;
TH1 = (uchar)(temp>>8);
TL1 = (uchar)(temp);
t1_int_type = WAIT_POSITIVE;
TR1 = 1;
break;
case WAIT_POSITIVE:
Drive = PNP_OFF;
TH1 = (uchar)(scr_delay_time>>8);
TL1 = (uchar)(scr_delay_time);
t1_int_type = POS_SCR_DELAY_TIME;
TR1 = 1;
break;
case POS_SCR_DELAY_TIME: // 开启之前的延时完毕后,就要开启可控硅.
Drive = PNP_ON;
TH1 = (uchar)(T1_DELAY_1MS>>8); // 可控硅固定开启时间 100uS.
TL1 = (uchar)T1_DELAY_1MS;
t1_int_type = POS_SCR_HOLD_TIME;
TR1 = 1;
break;
case POS_SCR_HOLD_TIME: // 关闭t1,等待下次外部中断时再启动T1.
Drive = PNP_OFF;
TR1 = 0;
t1_int_type = 0X55;
break;
default:break;
}
}
/**************************************************************************
* 函数原型: void int0(void) interrupt 0 using 0;
* 功 能: 全局定时
**************************************************************************/
void int0(void) interrupt 0 //using 0
{
//speed_control();
}
/**************************************************************************
* 函数原型: void int0(void) interrupt 2 using 2;
* 功 能: 全局定时
**************************************************************************/
void int1(void) interrupt 2 //using 2
{
if(b_Power== WORK)
{
switch(SpeedType)
{
case MiSpeed:
/*Drive = PNP_OFF;
TH1 = T1_DELAY_500uS_H;
TL1 = T1_DELAY_500uS_L;
TR1 = 1;
t1_int_type = NEG_ZERO_COMPENSATE;
break;*/
case LoSpeed:
Drive = PNP_OFF;
TH1 = T1_DELAY_500uS_H;
TL1 = T1_DELAY_500uS_L;
TR1 = 1;
t1_int_type = NEG_ZERO_COMPENSATE;
break;
default:break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -