一、定时器计时1秒控制LED闪烁
#include "reg52.h"
sfr AUXR = 0X8E;
sbit LED = P3^6;
int cnt = 0;
void Timer0Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void main()
{
Timer0Init();
LED = 1;
while(1)
{
if(TF0 == 1)
{
TL0 = 0x00;
TH0 = 0xDC;
cnt++;
TF0 = 0;
if(cnt == 100)
{
cnt = 0;
LED = !LED;
}
}
}
}
二、中断实行两路并行
#include "reg52.h"
sfr AUXR = 0X8E;
sbit LED1 = P3^6;
sbit LED2 = P3^7;
int cnt = 0;
void Timer0Init(void) //10毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;//打开定时器0的中断
EA = 1;//打开总中断
}
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main()
{
Timer0Init();
LED1 = 1;
LED2 = 1;
while(1)//一直执行的
{
LED2 = 0;
Delay500ms();
LED2 = 1;
Delay500ms();
}
}
void Timer0Handler() interrupt 1 //检测到才执行
{
TF0 = 0;
TL0 = 0x00;
TH0 = 0xDC;
cnt++;
if(cnt == 100)
{
cnt = 0;
LED1 = !LED1;
}
}
三、SG90舵机旋转
#include "reg52.h"
sfr AUXR = 0X8E;
sbit LED = P3^6;
sbit SG90 = P3^1;
int cnt = 0;
int jd;
void Delay2000ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 15;
j = 2;
k = 235;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Timer0Init(void) //500微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
void main()
{
SG90 = 1;
Timer0Init();
while(1)
{
jd = 3;
cnt = 0;
Delay2000ms();
jd = 1;
cnt = 0;
Delay2000ms();
}
}
void Timer0Handler() interrupt 1
{
TF0 = 0;
TL0=0x33;
TH0=0xFE;
cnt++;
if(cnt<jd)
{
SG90 = 1;
}
else
{
SG90 = 0;
}
if(cnt == 40)
{
cnt = 0;
SG90 = 1;
}
}
四、超声波测距
#include <reg52.h>
sbit LED=P3^7;
sbit Trig=P3^5;
sbit Echo=P3^4;
sfr AUXR=0x8E;
double time;
double dis;
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
void Delay300ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 3;
j = 26;
k = 223;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Timer0Init(void) //71.1106毫秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时初值
TR0 = 0; //初始化不计时
}
void TrigInit()//开始发送超声波
{
Trig=0;
Trig=1;
Delay10us();
Trig=0;
}
void Bc_Dis()
{
while(Echo==0);
TR0=1;//当发送波形时,Echo为1,立刻跳出while(Echo==0)循环,立马启动计时器
while(Echo==1);
TR0=0;//当波形回来时,Echo为0,跳出循环,立刻停止计时器
time=(TH0*256+TL0)*1.085/1000000;//以S为单位
dis=time*17000;//以cm为单位,路程折返
if(dis<15)
{
LED=0;//灯亮是给低电平
}
else
{
LED=1;
}
Delay300ms();
}
void main()
{
while(1)
{
Timer0Init();//循环到此处时,每次过来都给计数器清零。
TrigInit();//重新发送超声波,间距300ms
Bc_Dis();//超声波测距
}
}
五、智能垃圾桶
舵机用定时器0,超声波用定时器1
#include "reg52.h"
sbit LED1 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit LED2 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口
sbit Trig = P1^5;
sbit Echo = P1^6;
sbit SG90 = P1^4;
sbit SW1 = P2^1;
sbit Virbate = P3^2;//3.2口是外部中断口,当有电压来临时,中断其他服务程序,执行此程序。
sfr AUXR=0x8E;
int cnt=0;
int jd;
char jd_bak;
int mark_vibrate=0;
double dis;
double time;
void Timer0Init(void) //500微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x33; //设置定时初值
TH0 = 0xFE; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1;//打开总中断
ET0 = 1;//打开定 时器0的中断
}//计时器0管舵机,主要记录0.5ms时间
void Timer1Init(void) //71.111毫秒@11.0592MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x00; //设置定时初值
}//计时器1管超声波收发时间
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 2;
while (--i);
}
void Delay200ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 2;
j = 103;
k = 147;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay600ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Trigbegin()//超声波开始发送波
{
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
}
void OpenLight()//开盖灯
{
LED1 = 0;
LED2 = 1;
}
void CloseLight()//关盖灯
{
LED1 = 1;
LED2 = 0;
}
void SG90Init()//舵机初始化
{
cnt = 0;//开盖关盖从0计时
jd = 1;//初始化舵机为关盖状态
SG90=1;
}
void SG90_0()//舵机中断关盖
{
jd = 1;
jd_bak = jd;
cnt = 0;
Delay200ms();
}
void SG90_90()//舵机中断开盖
{
jd = 3;
if(jd_bak!=jd)//下次进来如果还和标志位相等,就不用延时,直接90°
{
cnt = 0;
Delay600ms();//在这600ms里PWM波不断地让舵机重复90°,所以舵机臂不下降
}
jd_bak=jd;//把标志位赋值给他,下次若手未动,则不延时,舵机直接90°不动。
}
double getdis()
{
Trigbegin();
while(Echo == 0);
TR1=1;//开始计时
while(Echo == 1);
TR1=0;//停止计时
time=(TH1*256+TL1)*1.085/1000000;//以S为单位计时
TH1=0x00;
TL1=0x00;
Delay200ms();
return (time*17000);
}
void ExInit()//51单片机在P3^2定义中断口
{
EX0 = 1;//打开外部中断
IT0 =0;//低电平触发中断
}
void main()
{
Timer0Init();//舵机开始计时,中断时跳到定时器0中断函数处
Timer1Init();
ExInit();
SG90Init();
while(1)
{
dis=getdis();//从获取距离这一刻开始计时
if(dis<=10||mark_vibrate == 1||SW1 == 0)
{
OpenLight();
SG90_90();
mark_vibrate = 0;//开盖的时候不管震动
}
else
{
CloseLight();
SG90_0();
}
}
}
void Timer0() interrupt 1//定时器0中断,由硬件调用,软件部分继续执行
{
cnt++;
TL0 = 0x33;
TH0 = 0xFE;
if(cnt < jd)
{
SG90 = 1;
}
else
{
SG90 = 0;
}
if(cnt == 40)
{
cnt = 0;
SG90=1;//又开始进入下一个周期,从头开始
TL0 = 0x33;
TH0 = 0xFE;
}
}
void Ex0_Handler() interrupt 0//外部中断
{ //中断来临标志位为1
mark_vibrate = 1;
}