利用8051单片机定时器T0测量某正脉冲的宽度 这个问题你弄懂了 能给我看看你的程序么 我研究很久没有搞懂

利用8051单片机定时器T0测量某正脉冲的宽度 这个问题你弄懂了 能给我看看你的程序么 我研究很久没有搞懂,第1张

原理:分别用脉冲的上升沿和下降沿出发单片机,下降沿给出中断2停止计数,最后换算出高电平宽度=计数周期数×一个计数的时间。

脉冲有间隔性的特征,因此我们可以把脉冲作为一种信号。脉冲信号的定义由此产生:

相对于连续信号(在整个信号周期内短时间中都有的信号),大部分脉冲信号周期内是没有信号的。就象人的脉搏一样。脉冲信号一般指数字信号,它已经是一个周期内有一半时间(甚至更长时间)有信号。计算机内的信号就是脉冲信号,又叫数字信号。

最大脉宽计算:知道计数器中断的产生是从全1变为全0产生溢出中断,所以计数器的处置设定为00H,如果让其工作在方式1计数下,最大计数值为2^16=65536,那么最大计数脉冲宽度就是655362us。

扩展资料:

脉宽由信号的周期和占空比确定,其计算公式是脉宽W=T×P(T:周期,P:占空比)。例如在飞思卡尔的S12dg128寄存器中的具体的

占空比计算方式是:

左对齐方式:

占空比=[(PWMPERx-PWMDTYx)/PWMPERx]×100%

中心对齐方式:

占空比=[PWMDTYx/PWMPERx]×100%

周期的计算公式:

左对齐方式:

输出周期=通道周期×PWMPERx

中心对齐方式:

输出周期=通道周期×PWMPERx×2

脉宽的计算方法就不言而喻了。

参考资料来源:百度百科-脉冲宽度

参考资料来源:百度百科-脉冲

呵呵,这个是一个单片机的问题,我可以给你解释,但是必须把分给我

#include <reg51h> 头文件包含

#include <mathh>

#define uchar unsigned char 用Uchar 定义unsigned char

#define uint unsigned int

#define ON 0 //电动机开关的宏

#define OFF 1

sbit PWM=P3^5; //与电动机通信的端口 定时器1外部中断

sbit MP=P3^4; //定时器0外部中断

bit FLAG=0; //数据是否需要显示的标志

uchar code dispbit[6]={0x20,0x10,0x08,0x04,0x02,0x01}; //选择led的六个中的一个

uchar code seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//0——9显示代码

//0,1,2,3,4,5,6,7,8,9

uchar disbuf[6]={0,0,0,0,10,10}; //数据缓冲区,j就是屏幕显示的缓冲数据

uint temp[6]; //显示速度分成显示字符的缓冲区

uint discount=0; //显示位数的定位

uint timecount=0; //定时的次数

uint T0count=0; //to计数器的溢出次数

uint hus=0;

uint k=60;

uint Vc;

uint Vs;

uint tm=3000; //外部定时器1的初始值,就是测转最多多少次

uint x;

void t0_serv() interrupt 1 //外部定时器0中断延时定时器到了,TOCUNT加一,时间

{ T0count++;

}

void t1_serv() interrupt 3 //外部定时器1中断延时定时器到了响应中断

{

PWM=1;

TH1=(65536-tm)/256; /定时器1初始化

TL1=(65536-tm)%256;

hus++;

if(hus==tm) //是否到3000次

{ PWM=0;

TH1=(25536+tm)/256; //定时器0初始化

TL1=(25536+tm)%256;

}

timecount++; //时间加一

if(timecount==250) //最多多少时间

{

//FLAG=1; //需要显示啦

TR0=0; //初始化

hus=0;

timecount=0;

Vc=T0count65536+TH0256+TL0;

Vs=144;

if(abs(Vc-Vs)>5) //得到的值与144相比

{ tm=abs(k(Vc-Vs));

T0count=0;

TR0=1;

TR1=1;

ET0=1;

ET1=1;

EA=1;

}

FLAG=1;

TR0=0;

timecount=0;

}

P0=dispbit[discount];

P1=seg[disbuf[discount]];

discount++;

if(discount==6)

{ discount=0;

}

}

void main()

{ uint i;

TMOD=0x15; //设置定时器启动模式

TH0=0;//定时器0的初始值

TL0=0;

TH1=(65536-tm)/256;//定时器1的初始值

TL1=(65536-tm)%256;

TR0=1; //启动定时器

TR1=1;

ET0=1;//启动两个中断

ET1=1;

EA=1; //开中断

while(1)

{ if(FLAG==1)

{ FLAG=0;

x=T0count65536+TH0256+TL0;//显示初始化 0

for(i=0;i<6;i++)

{temp[i]=0;

}

i=0;

while(x/10)

{

temp[i]=x%10;//将x放入缓冲区

x=x/10;

i++;

}

temp[i]=x;

for(i=0;i<6;i++)

{

disbuf[i]=temp[i];//将临时缓冲区的数据放入显示缓冲区

}

timecount=0;//定时器的归零初始化

T0count=0;

TH0=0;

TL0=0;

T0count=0;

TR0=1;

}

}

}

PWM(脉宽调制)重装载值是指在PWM周期结束后,重新开始新的PWM周期前需要等待多长时间。这个值通常由控制器或微处理器内部的寄存器来设置。

要改变PWM重装载值,可以按照以下步骤进行:

1 查找控制器或微处理器手册中有关PWM模块的章节,并查看相关寄存器和位域说明。

2 找到与PWM重装载值相关的寄存器和位域,并确定需要修改哪些参数以更改该值。

3 使用编程语言(如C、C++等)编写代码,在程序中使用相应函数或指令将所需参数写入对应的寄存器中,从而实现修改 *** 作。

4 将修改后的程序下载到目标设备上并测试其效果。如果发现问题,则需要进一步检查代码和硬件电路是否存在问题,并进行修正。

请注意,在进行任何修改之前,请务必备份原始数据以防止意外情况发生。同时也建议在实际 *** 作过程中谨慎行事,避免造成不可逆转的损失。

#define TEST_IN PA0 //要测试的信号

#define F_TEST_IN PA1 //要测试信号的反向,加一个反向门得到的

main()

{

unsigned long low_cnt,high_cnt;

while(1)

{

while(TEST_IN); //确保TEST_IN = 0;

low_cnt = 0;

high_cnt = 0;

while(!TEST_IN); //确保TEST_IN = 1;

while(TEST_IN) high_cnt++; //计算高电平数量

while(F_TEST_IN) low_cnt++; //计算低电平数量

//以下添加其他的处理代码。

}

}

这个应该能够保证到精度。十分浪费CPU时间就是。但是如果只有这一个任务还是OK的。

你说的用外部中断的方法也可以。

思路1 采用timer来进行计数。遇到相应的边沿后中断,停计数器。然后进行相应的处理。

思路2 直接用循环来检测,当然如果这个地方用循环检查的话,不如就不用中断了,直接用软件来实现上升沿下降沿的识别。也就是我写的程序一样了。

提示,思路1的话明显的会觉得有点问题。因为是硬件计数。至于精度问题,你看下程序就可以感觉出来。还有精度主要取决于检测的始终。与中断什么的没有任何关系。只是用中断给人感觉比较实时。

你的第二个想法有点看不懂。如果说你是想用AD转换来进行占空比的分析的话,那太笨了。根本就是自找麻烦。

以上就是关于利用8051单片机定时器T0测量某正脉冲的宽度 这个问题你弄懂了 能给我看看你的程序么 我研究很久没有搞懂全部的内容,包括:利用8051单片机定时器T0测量某正脉冲的宽度 这个问题你弄懂了 能给我看看你的程序么 我研究很久没有搞懂、这是个调速系统的C语言程序,谁能帮我注解一下各语句的主要功能、怎么改变pwm重装载值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9542173.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存