建议配合本专栏的文章“单片机_第6章 单片机的定时/计数器”一起使用
目录
实例1 设单片机的fosc=12MHz,采用T1定时方式1在P2.0脚上输出周期为2ms的方波。
实例2 用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。
实例3 采用T0定时方式2在P2.0口输出周期为0.5ms的方波(设fosc=12MHz)。
实例4 改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。
实例5(波形展宽) 由P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。
实例6(长延时、非对称) 采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。
实例1 设单片机的fosc=12MHz,采用T1定时方式1在P2.0脚上输出周期为2ms的方波。
实例1 设单片机的fosc=12MHz,采用T1定时方式1在P2.0脚上输出周期为2ms的方波。
分析:周期为2ms的方波由2个半周期为1ms的正负脉冲组成
方波输出原理:定时1ms后将端口输出电平取反。
1ms定时的计数初值应为:
a = 216 – t* fos / 12 = 216 – 1000* 12/ 12 = 64536 = 0xfc18
TH1 = 0xfc TL1 = 0x18
(另一种简单计算的方法:TH1=64536/256,TL1=64536%256)
注意:需要不断重装计数初值。
(1)查询方式
#include <reg51.h>
sbit P2_0 = P2^0;
main ()
{
TMOD = 0x10; //设置T1定时方式1(0001 0000B)
TR1=1; //启动T0
for(;;)
{
TH1 = 0xfc; //装载计数初值
TL1 = 0x18;
do{ } while(!TF1); //等待TF1溢出
P2_0 =!P2_0; //定时时间到P2.0反相
TF1 = 0; //TF1标志清0
}
}
(2)中断方式
中断源等情况
#include <reg51.h>
sbit P2_0=P2^0;
timer1 () interrupt 3 //T1中断函数
{
P2_0 = !P2_0; //P2.0取反
TH1 = 0xfc; //装载计数初值
TL1 = 0x18;
}
main ()
{
TMOD = 0x10; //T1定时方式1
TH1 = 0xfc; //装载计数初值
TL1 = 0x18;
EA=1; //开总中断
ET1=1; //开T1中断(总中断与部分中断的书写顺序无关紧要)
TR1=1; //启动T1,一定要最后书写,最后使用
while(1);
}
实例1仿真运行
仿真结果:生成了满足提示要求的波形
小结:方式1连续定时编程一般框架
思考(我这里只讲一点思路,大家可以自己动手实验):
1、怎样实现较长的定时?(增加一个值count来记录中断的次数,count达到一定值时让它产生反应)
2、怎样输出特定占空比的矩形波?(将高电平和低电平的时间单独表示)
实例2 用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。
实例2 用单片机实现一个频率计功能,用于测量接在P3.4引脚的脉冲波频率(<10KHz),并将测量结果显示在数码管上。
硬件: 脉冲波信号源、四位数码管
软件: T0: 计数 T1:定时1s 数码管显示(主程序)
实例3 采用T0定时方式2在P2.0口输出周期为0.5ms的方波(设fosc=12MHz)。
实例3 采用T0定时方式2在P2.0口输出周期为0.5ms的方波(设fosc=12MHz)。
编程步骤:
(1)设置TMOD;
(2)计算计数初值; ((1)(2)步骤可以调换)
(3) 选择溢出结果处理方式; (中断:中断初始化)
(4)启动定时计数器;
(5)定时或计数时间到的处理工作; (中断方式在中断函数中处理)
(6)清除溢出标志。 (仅针对查询方式)
分析:计数初值TL0= ((256-250)*12/12)%256 = 0x06,TMOD = 0x02
(1)查询方式
#include <reg51.h>
sbit P2_0 = P2^0;
main()
{
TMOD = 0x02;
TH0= TL0 = 0x06;
TR0=1;
for(;;)
{
do{} while(!TF0);
P2_0 =!P2_0;
TF0 = 0;
}
}
(2)中断方式
#include <reg51.h>
sbit P2_0=P2^0;
timer0 () interrupt 1
{
P2_0 = !P2_0; //与方式1相比,少了赋初值的部分,是因为方式2自己独特的性质
}
main()
{
TMOD = 0x02;
TH0 = TL0 = 0x06;
EA= ET0 = 1;
TR0=1;
while(1);
}
实例3仿真运行
仿真结果:生成了满足提示要求的波形
实例4 改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。
实例4 改进“计数显示器”采用的按键查询法,改为T0计数方式2 + 中断法,实现原有功能。
电路改造:按键由P3.7改为P3.4(T0)接入。
分析:T0计数方式2的初始化;定数计数N=1时的初值计算;T0中断初始化
T0计数方式2:TMOD = 0000 0110B = 0x06
计数初值: a = 2 8 – 1 = 255 = 0xff
T0中断初始化:ET0 = EA = 1
//中断方式的计数显示器
#include <reg51.h>
sbit p3_4=P3^4;
unsigned char num=0;
unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main()
{
TMOD=0x06;//00000110
EA=ET0=1;
TH0=TL0=0xff;
TR0=1;
while(1)
{
P0=led[num/10];
P2=led[num%10];
}
}
count0_srv() interrupt 1
{
num++;
if(num==100) num=0;
}
仿真结果
实例5(波形展宽) 由P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。
实例5(波形展宽) 由P3.4口输入一个低频窄脉冲信号。当该信号出现负跳变时,由P3.0口输出宽度为500μs的同步脉冲,如此往复。要求据此设计一个波形展宽程序(fosc= 6MHz)。
1、检测P3.4窄脉冲下降沿;
将定时计数器当做外部中断检测下降沿;
T0、方式2、查询方式、计数
TMOD=0x06;
TH0=TL0=0xff;
TRO=1;
while(!TF0);
TF0=0;
2、P3.0低电平展宽500us;
T0、方式2、查询方式、定时
TMOD=0x02;
TH0=TL0=0x06;
P3_0=0;
TRO=1;
while(!TF0);
TF0=0;
P3_0=1;
3、重复1、2过程
总结
//波形展宽
#include <reg51.h>
sbit P3_0=P3^0;
void main (){
TMOD = 0x06; //设置为T0计数方式2
TL0 = 0xff; //初值0xff可使1个外来脉冲即产生溢出
TR0 = 1; //启动计数器
while (1){
while (!TF0); //等待首次溢出
TF0 = 0; //清TF0溢出标志
TMOD = 0x02; //设置为T0定时方式2
TL0=0x06; //500微秒定时初值
P3_0 = 0;
while (!TF0); //等待再次溢出
TF0 = 0; //清TF0溢出标志
P3_0 = 1;
TMOD = 0x06; //设置为T0计数方式2
TL0 = 0xff; //1次溢出计数初值
}
}
方法二
#include <reg51.h>
sbit p3_0=P3^0;
void main()
{
TMOD=0x16;//T0用于计数方式2,T1用于定时方式1,00010110
TH0=TL0=0xff;
EA=1;ET0=1;ET1=1;
TR0=1;TR1=1;
while(1);
}
count0_srv() interrupt 1
{
p3_0=0;
TH1=65286/256;TL1=65286%256;//65536-250(因为这里是6MHz的晶振)=65286
}
timer1_srv() interrupt 3
{
p3_0=1;
}
仿真结果
实例6(长延时、非对称) 采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。
实例6(长延时、非对称) 采用10MHz晶振,在P2.0脚上输出周期为2.5s,高电平占空比为20%的脉冲信号。
分析:最大定时时间:10MHz->54.613ms
定时与软件计数联合
文章来源:https://www.toymoban.com/news/detail-451919.html
//pro17:P127 6.4 实例6 制定脉冲信号
#include <reg51.h>
sbit p2_0=P2^0;
unsigned char num=0;//用于占空比
unsigned char count=0; //用于使其为0.5s,即500ms=10*50ms
void main()
{
TMOD=0x01;//T0用于定时方式1,00000001
TH0=23869/256;TL0=23869%256;//65536-50000(50ms)*10/12=23869.33333
EA=1;ET0=1;
TR0=1;
while(1);
}
timer0_srv() interrupt 1
{
count++;
if(count==10)
{
count=0;
num++;
if(num==1) p2_0=0;
else if(num==5)
{
p2_0=1;
num=0;
}
}
TH0=23869/256;TL0=23869%256;
}
运行结果
文章来源地址https://www.toymoban.com/news/detail-451919.html
到了这里,关于单片机_第6章 实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!