📄 text1.c
字号:
#include <REG52.H>
#define uint unsigned int
#define uchar unsigned char
#define tim 65535-5000
#define pwm 2000
#define T 5
sbit key0 =P2^0;
sbit key1 =P2^1;
sbit PWMB =P3^3; //PWM输出口
bit PWMX;
uint pwmh,pwml,pwmm;
uint sudu_set,sudu_now;
int e0,sudu_d;
uchar pid_b,tm=0;
uchar count;
uchar disp[5],dis =0;
uchar key,keyx;
int para[4];
char ptr =0;
uchar code numtab[5] ={ 0x40,0x20,0x10,0x04,0x08 }; //按键与显示扫描口
uchar code distab[16]={ 0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea, //数码管显示值
0x20,0xa0,0x60,0x25,0x39,0x26,0x31,0x71 };
uchar code ledtab[8] ={ 0x08,0x10,0x20,0x40,0x80 }; //LED显示
void delay(uint timer)
{
for(;timer >0;timer --);
}
void distran()
{
disp[4]=distab[para[ptr]%10]; //编码转换
disp[0]=distab[(para[ptr]/10)%10];
disp[1]=distab[(para[ptr]/100)%10];
disp[2]=distab[(para[ptr]/1000)%10];
disp[3]=~ledtab[ptr]; //选中要点亮的LED
}
void display()
{
dis=(dis+1)%5;
P2 =0xff;
P0 =disp[dis]; //扫描数码管和LED
P2 =~numtab[dis];
key0=1; key1=1; //读取按键值
if(!key0) keyx=dis+1;
if(!key1) keyx=dis+5;
}
void keyproc() //按键处理程序
{
if(key>0)
{
if(ptr!=1)
{
switch(key)
{
case 1: para[ptr]--; break; //设定速度值
case 5: para[ptr]++; break;
case 2: para[ptr]-=10; break;
case 6: para[ptr]+=10; break;
case 3: para[ptr]-=100; break;
case 7: para[ptr]+=100; break;
case 4: ptr--; break;
case 8: ptr++; break;
}
}
else
{
switch(key)
{
case 4: ptr--; break;
case 8: ptr++; break;
}
}
if(ptr>2) ptr=0;
if(ptr<0) ptr=2;
if(para[ptr]<0) para[ptr]=0;
if(para[ptr]>1000) para[ptr]=1000;
distran(); //刷新显示
}
key=0;
}
/***************PID算法********************/
void PID_Control(void)
{
sudu_now = TH1*256+TL1; //读取速度反馈值
TH1 =0;
TL1 =0;
TR1 =1;
para[1] = sudu_now*40;
if(para[1] >(sudu_set+40))
{
e0 =(para[1]-sudu_set)/4;
pwml =pwmm-e0;
if(pwml >2000)
{
pwml =2000;
}
pwmh =pwm-pwml;
pwmh =65535-pwmh;
pwml =65535-pwml;
}
else
if(para[1] <(sudu_set-40))
{
e0 =(sudu_set-para[1])/4;
pwml =pwmm+e0; //计算输出占空比
if(pwml <1)
{
pwml =1;
}
pwmh =pwm-pwml;
pwmh =65535-pwmh;
pwml =65535-pwml;
}
}
void timer0() interrupt 1 using 0 //显示扫描
{
if(!PWMX)
{
TH0 =pwmh>>8;
TL0 =pwmh;
}
else
{
TH0 =pwml>>8;
TL0 =pwml;
}
PWMX =~PWMX;
PWMB =PWMX;
}
void timer2() interrupt 5 using 2 //PWM输出
{
TF2 =0;
TH2 =tim>>8;
TL2 =tim;
tm ++;
if(tm ==T)
{
tm =0;
TR1 =0;
pid_b =1;
}
display();
}
void timer_int(void)
{
TMOD=0x51; //设置定时器0的工作模式----定时模式,定时器1的工作模式----计数模式 //51
T2CON=0x00; //T2MOD=0x00; //定时器2模式设置----定时模式(向上计数)
TH0 =tim>>8;
TL0 =tim;
TH1 =0;
TL1 =0;
TH2 =tim>>8;
TL2 =tim;
ET0 =0; //定时器0开中断
ET1 =0; //定时器1关中断
ET2 =1; //定时器2关中断
TR0 =1; //启动定时器0
TR1 =1; //启动计数器1
TR2 =1; //启动定时器2
EA = 1; //开总中断
}
void main()
{
char i;
PWMB =1;
timer_int();
for(i=0;i<3;i++)
para[i]=i; //初始化速度存储数组
distran(); //刷新显示缓存区
sudu_set = para[0];
while(1)
{
if(keyx >0)
{
key =keyx;
while(keyx!=0) {keyx=0; delay(2500);}
keyproc(); //调用按键处理程序
sudu_set =para[0];
if(sudu_set <300)
{
PWMB =1;
ET0 =0;
}
else
{
PWMB =0;
pwmm = (sudu_set/1.28)-para[2];
pwmh =pwm-pwmm;
pwmh =65535-pwmh;
pwml =65535-pwmm;
ET0 =1;
}
}
if(pid_b)
{
pid_b =0;
PID_Control(); //调用PID调速程序
count++;
if(count >10) {count=0; distran();} //刷新显示
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -