阅读数:476
学51也算有一段时间了 以前学的相当的粗糙 很多原理性的东西 都不知道 今天上课的时候听老师说 这个LOW的单片机可以测量脉宽 去手册上看了一下 加上课本上说的 卧槽 真的可以 哈哈 直接上手册上的来说吧 就是这个东西 TMOD寄存器中的那个GATE位 很明显 手册中说道 当这位置1的时候 只有在INT0(P3.2)引脚为高电平的时候 并且TR0或者TR1置位的时候 定时/计数器才打开 我们就可以利用这个特点来测量一个脉冲的高电平的宽度 就是这个高电平的持续时间 那么怎么测量呢 说一下思路 首先 我们让门控位GATE=1 并且启动定时/计数器 TR0 但是这时候寄存器TH0 TL0里面的数值并不会增加 因为INT0这个引脚上还没高电平 我们把要测量的脉冲接到P3.2这个引脚上 当高电平来的时候 TH0和TL0里面的数值就开始每过一个机器周期增加一 知道P3.2引脚上的高电平消失 当高电平消失的时候 自然 TH0和TL0也就停止计数了 这时候我们把TH0和TL0里面的数值读出来 根据时钟和机器周期的关系就可以的出来高电平的时间了 这里 简单算一下 吧 好算一点 假设晶振频率是12MHZ那么机器周期就是1US 如果读出来 TH0+TL0=50000 那么这个高电平的持续时间就是50mS 能明白不 !!! 我用仿真做了一下 得出的结果基本正确 这里说一下仿真的问题 就是 仿真里面好像默认的51的晶振频率是12MHZ 即使你搭建外部晶振电路也不能改变改变频率 还要复位貌似也不太好用 哎呀 算了 这个不太影响 直接上代码 上图 看一下 下面的代码 我仿真里面设置的脉冲频率是1KHZ 占空比是50% 由这个代码得到的高电平的时间 理论值是500us 测得位501us 我觉得基本正确
# include
# define uint unsigned int
# define uchar unsigned char
uchar code table1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint High,Low;
sbit K=P3^2;
sbit led0=P2^0;
sbit led1=P2^1;
sbit led2=P2^2;
sbit led3=P2^3;
void delay(uint k) //延时函数 这个延时是为了数码管
{
uint i,j;
for(i=k;i>0;i--)
for(j=113;j>0;j--) ;
}
void Init_T0()
{
TMOD=0x09;
TH0=0;
TL0=0;
}
void Display(disnum)
{
led0=1;
P0=table1[disnum/1000];
delay(3);
P0=0xff;
led0=0;
led1=1;
P0=table1[disnum%1000/100];
delay(3);
P0=0xff;
led1=0;
led2=1;
P0=table1[disnum%100/10];
delay(3);
P0=0xff;
led2=0;
led3=1;
P0=table1[disnum%10];
delay(3);
P0=0xff;
led3=0;
}
void Message_Width()
{
while(K);
TR0=1;
while(!K);
while(K);
TR0=0;
High=TH0;
Low=TL0;
}
void main()
{
while(1)
{
Init_T0();
Message_Width();
Display(High*256+TL0);
}
}
此代码得到下图
但是无意间让我发现了一个很无奈的问题 我觉得上面的数码管写的太小学生了 于是想让程序少几行 把数码管的函数变更了一下 但是测得脉宽长度居然不一样了 多了8个us即使两个函数执行时间不一样 可是我实在数码管显示函数之前就把脉宽测量完成了 啊 为啥会多这个8us呢 有哪位大佬看到希望指点一下 啊 下面附上代码和图
# include
# define uint unsigned int
# define uchar unsigned char
uchar code table1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar code table2[]={0x01,0x02,0x04,0x08};
uchar table3[4]={0};
uint High,Low,n;
sbit K=P3^2;
void delay(uint k) //延时函数 这个延时是为了数码管
{
uint i,j;
for(i=k;i>0;i--)
for(j=113;j>0;j--) ;
}
void Data_Process(disnum)
{
table3[0]= disnum/1000;
table3[1]= disnum%1000/100;
table3[2]= disnum%100/10;
table3[3]= disnum%1000;
}
void Display()
{
uchar i;
for(i=0;i<4;i++)
{
P2=table2[i];
P0=table1[table3[i]];
delay(3);
P0=0xff;
P2=0;
}
}
void Init_T0()
{
TMOD=0x09;
TH0=0;
TL0=0;
}
void Message_Width()
{
while(K);
TR0=1;
while(!K);
while(K);
TR0=0;
High=TH0;
Low=TL0;
}
void main()
{
while(1)
{
Init_T0();
Message_Width();
Data_Process(High*256+TL0);
Display();
}
}
上一篇:51单片机的代码存储问题
下一篇:51单片机的各种周期
推荐阅读最新更新时间:2024-03-16 16:08