原理:分别用脉冲的上升沿和下降沿出发单片机,下降沿给出中断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重装载值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)