📄 c8051.c
字号:
//c8051
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
uchar bdata FLAG;
sbit FLAG1=FLAG^1;
sbit FLAG2=FLAG^2;
sbit P1_1=P^1;//
uchar data time,Dtime,Btime;
uint fetch_rate(void) ; //函数声明,
main()
{
char bdata JFLAG;
uint data state,Astate,Bstate,rate;
do
{
P1=0xff;//要想读端口,须先写1,然后再读
FLAG=P1;//读取P1口的状态,进行判断
TXD=0; //初始化输出为0
JFLAG=FLAG>>6;
JFLAG&=0x03; //将7、6位测试
switch(JFLAG)
{
case 0: time=2;Dtime=20;break;
case 1: time=4;Dtime=40;break;
case 2: time=6;Dtime=60;break;
case 3: time=8;Dtime=80;break;
}
Btime=Dtime;
JFLAG=FLAG>>3;
JFLAG&=0x07; //将5、4、3位测试
switch(JFLAG)
{
case 0: state=50; break;
case 1: state=100;break;
case 2: state=150;break;
case 3: state=200;break;
case 4: state=250;break;
case 5: state=300;break;
case 6: state=350;break;
case 7: state=400;break;
}
//初始化定时器、计数器
FLAG1=0;
TMOD=0x51;//0b01010001,/计数器1为16位计数器,定时器0为16为定时器
TH1=0;
TL1=0;
TH0=0x3c;
TL0=0xB0;
TR1=1;//计数器1开启计数
TR0=1;//计数器0开启计数
ET0=1;//计数器0允许中断
EA=1; //开cpu中断
rate=fetch_rate();
if(!FLAG2) //FLAG2是根据专门的设置来确定,程序中没有相应的软件设值,由硬件来完成
{
Astate=state+2*state/10;
if(rate<=state)
{
TXD=1;
do
{
rate=fetch_rate();
}
while (rate<=Astate);
TXD=0;
}
}
else
{
Bstate=state-2*state/10;
if(rate>=state)
{
TXD=1;
do
{
rate=fetch_rate();
}
while (rate>=Bstate);
TXD=0;
}
}
} while(1);
}
unsigned int fetch_rate(void)
{
uint count;
do{}
while(!FLAG1);//FLAG1为0是等待,等待满足复合计数值,当FLAG1为1是跳出循环
FLAG1=0;//所以要将FLAG1清零
count=TH1*256+TL1;
TH1=0; //清零计数器,为下一次计数做准备
TL1=0;
Dtime=Btime;//Btime只是个放置时间的不变的暂变量,对Dtime重新负值
return(count/time);
}
time0() interrupt 1 using 1 //定时器0每0.1s(100ms)中断一次,所以Dtime设置为*10正好符合题目的要求
{ //但复合计数值/定时数值为2,4,6,8s
TH0=0x3c; //通过定时器实现精确的延时
TL0=0xB0;
Dtime--;
if(Dtime==0)
{
FLAG1=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -