📄 pwm.c
字号:
#include <reg52.h>
#include <intrins.h>//包含_nop()函数
#define uchar unsigned char
#define uint unsigned int
sbit Dat=P1^0; //595数据输入端
sbit Sclk=P1^2; //595上升沿输出端
sbit Lclk=P1^1;//595存储寄存器输入
sbit output=P3^5;
sfr P3M0=0xb1;//STC单片机强上拉推挽模式,在此模式下,系统自动设置为强上拉
sfr P3M1=0Xb2;
/*SFR0xb0为特殊功能寄存器的P3口地址,0xb1,0xb2为功能设置位*/
uchar code BitTab[4]={0x0e,0x0d,0x0b,0x07};//数码管位选择(00001110,00001101,00001011,00000111)
uchar code DispTab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //数码管字符显示
uchar temp1=0;
uchar temp2=0;
uchar keyvalue;
uchar scanf=0;
uchar chuli=0;
uchar keyci=0;
uchar DispT1=0;
uchar DispT2=0;
uchar DispT3=0;
uchar scanT=0x88;
uchar ydc=0;
uchar yfc=0;
uchar yec=0;
uchar shezhi=0;
uchar shezhif;
uchar timeflag;
uchar time;
uchar Aba=0;
uchar Abb=0;
uchar Bbb=8;
uchar Cbb=1;
uchar aim1=0;
uchar aim2=0;
uchar aim3=0;
uchar ain1=0;
uchar ain2=0;
uchar ain3=0;
uchar Hpl=0;
uchar Lpl=0;
uchar Hf=0;
uchar Lf=0;
uchar Hcishu=0;
uchar Lcishu=0;
uchar yhc=0;yic=0;yjc=0;ykc=0;ylc=0;ymc=0; //变量定义
void SendData(uchar SendDat1,uchar SendDat2) //595发送数据
{
uchar i;
uchar j;
Lclk=0;//低电平时,数据更新
for(i=0;i<8;i++)
{
Sclk=0;//低电平时,读数据
for(j=8;j>0;j--);//短延时
if((SendDat1&0x80)==0)
Dat=0;
else Dat=1;
Sclk=1;//数据更新完成
for(j=8;j>0;j--);
SendDat1=SendDat1<<1;
}
for(i=0;i<8;i++)
{
Sclk=0;
for(j=8;j>0;j--);
if((SendDat2&0x80)==0)
Dat=0;
else Dat=1;
Sclk=1;
for(j=8;j>0;j--);
SendDat2=SendDat2<<1;
}
Lclk=1;//上升沿数据发送
for(j=8;j>0;j--);
Lclk=0;
}
void Disp1()
{
if(temp1<50)
{
SendData(BitTab[keyci-1],DispT1);
}
if(temp1>=50)
{
SendData(0xff,0xc0);
}
if(temp1==100)
{
temp1=0;
}//字符闪烁
SendData(BitTab[keyci],DispT2);
SendData(BitTab[keyci+1],DispT3);//修改后不闪烁位字符不变
}
void Disp2()
{
if(temp1<50)
{
SendData(BitTab[keyci-1],DispT2);
}
if(temp1>=50)
{
SendData(0xff,0xc0);
}
if(temp1==100)
{
temp1=0;
}
SendData(BitTab[keyci-2],DispT1);
SendData(BitTab[keyci],DispT3);
}
void Disp3()
{
if(temp1<50)
{
SendData(BitTab[keyci-1],DispT3);
}
if(temp1>=50)
{
SendData(0xff,0xc0);
}
if(temp1==100)
{
temp1=0;
}
SendData(BitTab[keyci-3],DispT1);
SendData(BitTab[keyci-2],DispT2);
}
void Disp4()
{
if(timeflag==0)
{
SendData(BitTab[0],DispTab[Abb]);
SendData(BitTab[1],DispTab[Bbb]);
SendData(BitTab[2],DispTab[Cbb]);
}//倒计时结束或者停止键按下后数码管显示当前值。
if(timeflag==1)
{
SendData(BitTab[Aba],DispTab[Abb]);
SendData(BitTab[Aba+1],DispTab[Bbb]);
SendData(BitTab[Aba+2],DispTab[Cbb]);
SendData(BitTab[Aba+3],0x88);
if(time==200)//倒计时,5ms扫描一次,200次为一秒
{
time=0;//每1秒更新数据
if(Abb==0)
{
Abb=10;
if(Bbb==0)
{
Bbb=10;
Cbb=0;
}
Bbb--;
}
Abb--;
if((Abb==0)&&(Bbb==0)&&(Cbb==0)) //数码管全为0后置停止标志位
{
timeflag=0;
}
}
}
}
void scan()
{
uchar key;
if(shezhi!=0)//设置键按下后才可以扫描光标和+,-键
{
SendData(0x67,scanT); //矩阵键盘扫描方法,发第一行01100111,重要的是第四个0
P1=P1|0x18;
key=P1;
key=key&0x18;//保护现场,读键值
if(key!=0x18)
{
temp2++;
if((temp2==50)&&(key!=0x18))//去键盘抖动
{
temp2=0;
if(key==0x08)
{
chuli=1;
keyvalue=1;//光标键
}
if(key==0x10)
{
chuli=1;
keyvalue=2;//+键
}
}
}
}
SendData(0x57,scanT);//扫描第二行01010111,重要的是第三个0
key=P1|0xe7;
key=key&0x18;
if(key!=0x18)
{
temp2++;
if((temp2==50)&&(key!=0x18))
{
temp2=0;
if(shezhi!=0)
{if(key==0x08)
{
chuli=1;
keyvalue=3;//-键
}
}
if(timeflag==0)
{
if(key==0x10)
{
chuli=1;
keyvalue=4;//设置键
}
}
}
}
SendData(0x37,scanT);//扫描第三行00110111,重要的是第二个0
key=P1|0xe7;
key=key&0x18;
if(key!=0x18)
{
temp2++;
if((temp2==50)&&(key!=0x18))
{
temp2=0;
if(key==0x08)
{
chuli=1;
keyvalue=5;//启动键
}
if(key==0x10)
{
chuli=1;
keyvalue=6;//停止键
}
}
}
}
void deal()//按键处理程序
{
if(keyvalue==1)//光标键处理
{
keyci++;
if(keyci==1)//第一位
{
if(shezhi==1)//高电平时间
{
DispT1=DispTab[aim1];
DispT2=DispTab[aim2];
DispT3=DispTab[aim3];
Disp1();
}
if(shezhi==2)//低电平时间
{
DispT1=DispTab[ain1];
DispT2=DispTab[ain2];
DispT3=DispTab[ain3];
Disp1();
}
if(shezhi==3)//倒计时时间
{
DispT1=DispTab[Abb];
DispT2=DispTab[Bbb];
DispT3=DispTab[Cbb];
Disp1();
}
}
if(keyci==2)//第二位
{
if(shezhi==1)
{
DispT2=DispTab[aim2];
}
if(shezhi==2)
{
DispT2=DispTab[ain2];
}
if(shezhi==3)
{
DispT2=DispTab[Bbb];
}
Disp2();
}
if(keyci==3)//第三位
{
if(shezhi==1)
{
DispT3=DispTab[aim3];
}
if(shezhi==2)
{
DispT3=DispTab[ain3];
}
if(shezhi==3)
{
DispT3=DispTab[Cbb];
}
Disp3();
}
if(keyci==4)
{keyci=1;}
}
if(keyvalue==2)//+键处理程序
{
if(keyci==1)
{
if(shezhi==1)
{
yhc++;//按一次字符值+1
if(yhc==10)
{
yhc=0;
}
aim1=yhc;
DispT1=DispTab[yhc];
Disp1();
}
if(shezhi==2)
{
yic++;
if(yic==10)
{
yic=0;
}
ain1=yic;
DispT1=DispTab[yic];
Disp1();
}
if(shezhi==3)
{
yec++;
if(yec==10)
{
yec=0;
}
Abb=yec;
DispT1=DispTab[Abb];
Disp1();
}
}
if(keyci==2)
{
if(shezhi==1)
{
yjc++;
if(yjc==10)
{
yjc=0;
}
aim2=yjc;
DispT2=DispTab[yjc];
Disp2();
}
if(shezhi==2)
{
ykc++;
if(ykc==10)
{
ykc=0;
}
ain2=ykc;
DispT2=DispTab[ykc];
Disp2();
}
if(shezhi==3)
{
yfc++;
if(yfc==8)
{
yfc=0;
}
Bbb=yfc;
DispT2=DispTab[Bbb];
Disp2();
}
}
if(keyci==3)
{
if(shezhi==1)
{
if(ylc==6)
{
ylc=0;
}
aim3=ylc;
DispT3=DispTab[ylc];
ylc++;
Disp3();
}
if(shezhi==2)
{
if(ymc==6)
{
ymc=0;
}
ain3=ymc;
DispT3=DispTab[ymc];
ymc++;
Disp3();
}
if(shezhi==3)
{
if(ydc==2)
{
ydc=0;
}
Cbb=ydc;
DispT3=DispTab[Cbb];
Disp3();
ydc++;
}
}
}
if(keyvalue==3)//-键处理程序
{
if(keyci==1)
{
if(shezhi==1)
{
DispT1=DispTab[yhc];
aim1=yhc;
if(yhc==0)
{
yhc=10;
}
yhc--;
Disp1();
}
if(shezhi==2)
{
DispT1=DispTab[yic];
ain1=yic;
if(yic==0)
{
yic=10;
}
yic--;
Disp1();
}
if(shezhi==3)
{
if(yec==0)
{
yec=10;
}
yec--;
Abb=yec;
DispT1=DispTab[Abb];
Disp1();
}
}
if(keyci==2)
{
if(shezhi==1)
{
DispT2=DispTab[yjc];
aim2=yjc;
if(yjc==0)
{
yjc=10;
}
Disp2();
yjc--;
}
if(shezhi==2)
{
DispT2=DispTab[ykc];
ain2=ykc;
if(ykc==0)
{
ykc=10;
}
Disp2();
ykc--;
}
if(shezhi==3)
{
Bbb=yfc;
DispT2=DispTab[Bbb];
if(yfc==0)
{
yfc=8;
}
Disp2();
yfc--;
}
}
if(keyci==3)
{
if(shezhi==1)
{
if(ylc==0)
{
ylc=6;
}
ylc--;
aim3=ylc;
DispT3=DispTab[ylc];
Disp3();
}
if(shezhi==2)
{
if(ymc==0)
{
ymc=6;
}
ymc--;
ain3=ymc;
DispT3=DispTab[ymc];
Disp3();
}
if(shezhi==3)
{
if(ydc==0)
{
ydc=1;
}
ydc--;
Cbb=ydc;
DispT3=DispTab[Cbb];
Disp3();
}
}
}
if(keyvalue==4)//设置键
{
shezhi++;
if(shezhi==4)
{
shezhi=1;
}
if(shezhi==3)
{
ylc=0;
ymc=0;
}
switch(shezhi)
{
case 1:scanT=0x89; break;
case 2:scanT=0xcf; break;
case 3:scanT=0xbf; break;
default:break;//第四位控制,为H则为高电平设置时间,L为低电平设置时间,-为倒计时时间
}
}
if(keyvalue==5)//启动键
{
shezhi=0;//设置状态归0
keyci=0; //光标位置归0
timeflag=1;//倒计时位置1
time=0;
Hcishu=0;
Lcishu=0;
Hpl=aim3*100+aim2*10+aim1;//计算高电平倒计时时间
Lpl=ain3*100+ain2*10+ain1;//计算低电平倒计时时间
ET1=1;//开定时器1中断
Disp4();
}
if(keyvalue==6)
{
timeflag=0;//倒计时位置0,停止倒计时
ET1=0; //关定时器1中断
Disp4();
}
}
void main()
{
P3M0=0x00;//00000000
P3M1=0x20;//00100000,设置为3.5受控,从右边数,第6位为P3.5位,设置为01,高电平推挽强上拉模式
TMOD=0x11;
ET0=1;
TH0=(65536-5000)/256;//定时器0设置为5ms
TL0=(65536-5000)%256;
TH1=(65536-1000)/256;//定时器1设置为1ms
TL1=(65536-1000)%256;
TR0=1;
TR1=1;
EA=1;//定时器初始化
output=0;
while(1)
{
if(scanf==1)//扫描标志位
{
scanf=0;
scan();
}
if(chuli==1)//处理标志位
{
chuli=0;
deal();
}
if(keyci==1)
{Disp1();}
if(keyci==2)
{Disp2();}
if(keyci==3)
{Disp3();}
if(shezhi==0)
{Disp4();}
if(timeflag==1)
{
if(Hf==1)//Hf=1时,发高电平
{
output=1;
}
if(Lf==1)//Lf=1时,发低电平
{
output=0;
}
}
}
}
void Timer0() interrupt 1 using 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
scanf=1;
temp1++;
time++;
}
void Time1() interrupt 3 using 2
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
Hcishu++;
if(Hcishu<=Hpl)//高电平时,Hf=1
{
Hf=1;
}
if(Hcishu>Hpl)
{
Hf=0;
Lcishu++;
if(Lcishu<=Lpl)//低电平时,Lf=1
{
Lf=1;
}
if(Lcishu>Lpl)
{
Lf=0;
Hcishu=0;
Lcishu=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -