下面是一个用51单片机的P3.5引脚对一个由555定时器构成的多谐振荡器的振荡频率进行测量的程序,求注释

下面是一个用51单片机的P3.5引脚对一个由555定时器构成的多谐振荡器的振荡频率进行测量的程序,求注释,第1张

void cafrequent(void) reentrant 定义cafrequent程序求振荡频率

{

long int l1=0x00;

long int h1=0x00;

float tt=0; //tt用于计算频率

TMOD=(TMOD&0x0F)|0x90; //定时器1工作于模式1(16位计数器),TR1控制运行

TH1=0x00; //计数器初值设为0x0000

TL1=0x00;

ET1=1; //timer1 使能

EA=1; //开中断

while(fw==1); 测得引脚P3^5为高电平

TR1=1; //timer1 开始计数 注:1

while(fw==0); 测得引脚P3^5为低电平

while(fw==1); 测得引脚P3^5为高电平

TR1=0; //timer1 停止计数

l1=TL1; //读当前计数值

h1=TH1;

uu=h1256+l1+inte65536; //计算总计数值 这里写成 uu=inte65536+h1256+l1 会比较直观一些 注:1

inte=0; //清累计溢出计数

tt=uu/(11059210000000/120); 求振荡周期

ff=(unsigned long int)(10/tt); //频率值 求震荡频率

}

注1:另外还有一个timer1的中断函数你没给出来。该中断函数功能就是当timer的计数值超过0xffff的时候触发中断,在中断内部将对全局变量inte 进行加一 *** 作,以记录timer1的溢出次数,实际也可以理解为16位计数器溢出后的进位,相当于第17位到32位的计数值。

起目的是当被测频率值很低的时候,16位的计数值不足以存放待测频率值的周期,所以需要额外的计数值。

如果被测信号频率远大于单片机工作频率(机器周期),可以通过外部可编程分频器降到单片机可以接受的频率范围。

如果被测信号频率稍低于单片机工作频率,可以采用单片机定时器从计数引脚输入信号,程序设定计数门限时间的方法来测量频率。

如果被测信号频率远低于单片机工作频率,那么可以采用信号输入外部中断引脚作为单片机定时器的计数门限时间,定时器以工作频率计数来测量频率。

不用的!单片机有晶振!

一般测量频率有2中方法:\

1,你用T1定时1S(只用T1是无法达到定时1s的目的的,因为时间太长,你还可以借助别的单元+1,+1的形式),然后用T0记数在这1s内通过的方波个数,这个方法不是很精确

2,用外部中断,选择下降沿触发,程序响应中断后马上开启定时器,在下个下降沿来临的时候关掉定时器就可以了(记得定时器先清零)

数码管台古老了,你用这个吧,看着还稍微有点可以,代码和电路都给你了,没有做不出来的理由,有问题加我QQ11422376745

#include "d:\c51\reg51h"

#include "d:\c51\intrinsh"

sbit LCM_RS=P3^0;

sbit LCM_RW=P3^1;

sbit LCM_EN=P3^7;

#define BUSY   0x80              //常量定义

#define DATAPORT P1

#define uchar unsigned char

#define uint   unsigned int

#define L 50

uchar str0[16],str1[16],count;

uint speed;

unsigned long time;

void ddelay(uint);

void lcd_wait(void);

void display();

void initLCM();

void WriteCommandLCM(uchar WCLCM,uchar BusyC);

void STR();

void account();

/延时K1ms,12000mhz/

void int0_isr(void) interrupt 0         /遥控使用外部中断0,接P32口/

{

unsigned int temp;

time=count;

TR0=0;

temp=TH0;

temp=((temp << 8) | TL0);

TH0=0x3c;

TL0=0xaf;

count=0;

TR0=1;

time=time50000+temp;

}

void time0_isr(void) interrupt 1        /遥控使用定时计数器1 /

{

TH0 =0x3c;

TL0 =0xaf;

count++;

}

void main(void)

{

TMOD=0x01;                       /TMOD T0选用方式1(16位定时) /

IP|=0x01;                           /INT0 中断优先/

TCON|=0x11;                         /TCON  EX0下降沿触发,启动T0/

IE|=0x83;

TH0=0x3c;

TL0=0xaf;

initLCM();

WriteCommandLCM(0x01,1);    //清显示屏

for(;;)

{

account();

display();

}

}

void account()

{

unsigned long a;

if (time!=0)

{

a=L360000000/time;

}

speed=a;

}

void STR()

{

str0[0]='S';

str0[1]='p';

str0[2]='e';

str0[3]='e';

str0[4]='d';

str0[5]=' ';

str0[6]=(speed%100000)/10000+0x30;

str0[7]=(speed%10000)/1000+0x30;

str0[8]=(speed%1000)/100+0x30;

str0[9]='';

str0[10]=(speed%100)/10+0x30;

str0[11]=speed%10+0x30;

str0[12]='k';

str0[13]='m';

str0[14]='/';

str0[15]='h';

}

void ddelay(uint k)

{

uint i,j;

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

{

for(j=0;j<60;j++)

{;}

}

}

/写指令到LCD子函数/

void WriteCommandLCM(uchar WCLCM,uchar BusyC)

{

if(BusyC)lcd_wait();

DATAPORT=WCLCM;

LCM_RS=0;                   / 选中指令寄存器/

LCM_RW=0;               // 写模式

LCM_EN=1;

_nop_();

_nop_();

_nop_();

LCM_EN=0;

}

/写数据到LCD子函数/

void WriteDataLCM(uchar WDLCM)

{

lcd_wait( );            //检测忙信号

DATAPORT=WDLCM;

LCM_RS=1;               / 选中数据寄存器  /

LCM_RW=0;           // 写模式

LCM_EN=1;

_nop_();

_nop_();

_nop_();

LCM_EN=0;

}

/lcd内部等待函数/

void lcd_wait(void)

{

DATAPORT=0xff;     //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑**

LCM_EN=1;

LCM_RS=0;

LCM_RW=1;

_nop_();

_nop_();

_nop_();

while(DATAPORT&BUSY)

{  LCM_EN=0;

_nop_();

_nop_();

LCM_EN=1;

_nop_();

_nop_();

}

LCM_EN=0;

}

/LCD初始化子函数/

void initLCM( )

{

DATAPORT=0;

ddelay(15);

WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号

ddelay(5);

WriteCommandLCM(0x38,0);

ddelay(5);

WriteCommandLCM(0x38,0);

ddelay(5);

WriteCommandLCM(0x38,1);    //8bit数据传送,2行显示,57字型,检测忙信号

WriteCommandLCM(0x08,1);    //关闭显示,检测忙信号

WriteCommandLCM(0x01,1);    //清屏,检测忙信号

WriteCommandLCM(0x06,1);    //显示光标右移设置,检测忙信号

WriteCommandLCM(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检测忙信号

}

/显示指定坐标的一个字符子函数/

void DisplayOneChar(uchar X,uchar Y,uchar DData)

{

Y&=1;

X&=15;

if(Y)X|=0x40;               //若y为1(显示第二行),地址码+0X40

X|=0x80;                    //指令码为地址码+0X80

WriteCommandLCM(X,0);

WriteDataLCM(DData);

}

/显示指定坐标的一串字符子函数/

void DisplayListChar(uchar X,uchar Y,uchar DData)

{

uchar ListLength=0;

Y&=0x01;

X&=0x0f;

while(X<16)

{

DisplayOneChar(X,Y,DData[ListLength]);

ListLength++;

X++;

}

}

void display()

{

STR();

DisplayListChar(0,0,str0);

DisplayListChar(0,1,str1);

}

以上就是关于下面是一个用51单片机的P3.5引脚对一个由555定时器构成的多谐振荡器的振荡频率进行测量的程序,求注释全部的内容,包括:下面是一个用51单片机的P3.5引脚对一个由555定时器构成的多谐振荡器的振荡频率进行测量的程序,求注释、单片机如何检测信号的频率、单片机测量脉冲频率问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/zz/10044842.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存