📄 control.c
字号:
#include <reg51.h>
#include "commons.h"
sbit _p32 = P3^2;
sbit _p30 = P3^0;
sbit _p25 = P2^5;
sbit _p26 = P2^6;
sbit _p27 = P2^7;
unsigned char _pcount = 0; //定时中断总次数,每100次为一个输出总周期
unsigned char _pout = 0; //占空比对应的定时中断次数(低电平有效的周期数)
float _sigma_i = 0.0; //PWM占空比
unsigned int ad();
void da(unsigned int value); //串口DA转变
unsigned int filter(unsigned int value, unsigned char flt_idx); //数字滤波函数
void ctrl_init(void) { //定时器中断初始化
TMOD = 0x02; //定时器0方式2
TH0 = 0;
TL0 = 0;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void _ctrl_proc(void) interrupt 1 { //比例控制
if (++_pcount == 100) {
_pcount = 0;
_pout = (unsigned char)(100.0 * (1.0 - _sigma_i)); //每个总周期结束时确定下次的输出周期
}
if (_pcount < _pout) { //判断定时中断次数是否达到占空比对应的中断次数
_p25 = 1;
} else {
_p25 = 0;
}
}
void ctrl_routine(void) {
char led_buf[6];
unsigned int value;
unsigned char d;
value = filter(ad(), _menu_value[3]);//数字滤波
da(value); //D/A转换
//超限报警
if (value > _menu_value[0]) {
_p26 = 0;
_p27 = 1;
} else if (value <= _menu_value[0] && value >= _menu_value[1]) {
_p26 = 1;
_p27 = 1;
} else {
_p26 = 1;
_p27 = 0;
}
//根据比例度确定输出占空比_sigma_i
if (value > _menu_value[2]) { //大于控制目标时,占空比定为0
_sigma_i = 0;
} else {
d = (int)(100.0 * (float)value / (float)_menu_value[2]); //计算是否进入临届比例度
if (d < _menu_value[4]) { //若没有进入,占空比定为100%
_sigma_i = 1.0;
} else { //否则,计算占空比
_sigma_i = (float)(100 - d) / (float)(100 - _menu_value[4]);
}
}
if (_menu_status == MENU_OFF) {
led_buf[0] = '^';
to_string(&led_buf[1], 5, value);
print(led_buf);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -