OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4293|回复: 7

,求帮分析程序,关于C51的等精度频率计的程序,网上找的程序,跟着看了不是很懂原理,望大佬帮助分析一下

[复制链接]

5

主题

11

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-6-16
在线时间
11 小时
发表于 2020-7-5 17:23:56 | 显示全部楼层 |阅读模式
1金钱
#include "reg51.h"
#include "intrins.h"
#include "1602.h"
unsigned char t0_hh,t1_hh;
unsigned char dis_buf[11];
sbit  RS=P2^2;
sbit RW=P2^1;         
sbit LCM1602_E=P2^0;            
sbit LCM1602_Busy=P0^7;           
sbit led = P2^6;            
bit  firstex,secondex;        (这俩是干啥的,没看懂)              
unsigned long count0,count1;     
unsigned long count;
unsigned char i,p,q;
//低频数据处理
void deal_data()                 (这整个函数都看得不是很懂,为啥adata要*10000000再除,count又是啥)
{
unsigned char i;
float adata;
count1=t1_hh*65536+TH1*256+TL1;      
count0=t0_hh*65536+TH0*256+TL0;      
adata=(float)count1*10000000/count0;   
adata=(float)adata*10;
count=(unsigned long)(adata+0.5);
for(i=7;i>0;i--)
{
  dis_buf[i]=count%10;
  count=count/10;
}                 
dis_buf[0]=count;        
dis_buf[8]=dis_buf[7];      
dis_buf[7]=dis_buf[6];
dis_buf[6]=-2;         
}
//低频液晶显示
void display()            
{

  for(i=0;i<11;i++)
  {
   lcd_char_write(i,1,dis_buf[i]+0x30);      
    lcd_delay(1);
    }
}
//外中断1
void init1() interrupt 2
{
if(firstex==0)
{
  TH1=0;
  TL1=0;
  TH0=0;
  TL0=0;
  t0_hh=0;
  t1_hh=0;
  TR1=1;
  TR0=1;
  EX1=0;
  firstex=1;
  secondex=0;
}
else
{
  TR1=0;
  TR0=0;
  secondex=1;
  EX1=0;
  q=q+1;
  if (q>2)
  {  led=1;
  }
  else
  { led=0;}
  if (q==3) q=0;
}
  
}
//定时器1中断处理
void timer1() interrupt 3
{
t1_hh++;
}
void timer0() interrupt 1
{
t0_hh++;
if(t0_hh>=20)
{
  IE1=0;
  EX1=1;
}
}
void main()           //主函数
{
lcd_system_reset();           //初始化LCD
TMOD=0x51;               //T1计数,T0定时
ET1=1;
ET0=1;                 //使能T1,T0中断
IT1=1;                 //设置外部中断1下降沿触发
string_write(0,0,"Frequence Test");   //在第一行写入字符串
EX1=1;                 //打开外部中断1的中断允许
EA=1;                  //打开总中断
while(1)
{
  if(secondex==1)
  {
   deal_data();//f存在count
   secondex=0;
   firstex=0;
   EX1=1;
   display();
  }
}
}


如题,主要是低频数据处理函数里面看的不太懂,望前辈们点拨

最佳答案

查看完整内容[请看2#楼]

整个流程就是。 初始化,遇到被测信号的下降沿,打开外部中断,清零所有计数值。关闭外部中断。 等待到t0_hh>=20 (t0计的是基频,所以20个就是一个固定的时间长度T), 满足该条件后,再打开外部中断。等到新的被测信号的下降沿来临,到来时secondex=1; (secondex作为一个标志,代表一个完整的测量) secondex=1时,测量一次完成,在主程序中进行处理。 捕获到的时间长度t0_hh*f0 捕获到被测信号的个数 t1_hh 单个被测 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

89

帖子

0

精华

高级会员

Rank: 4

积分
832
金钱
832
注册时间
2020-6-12
在线时间
300 小时
发表于 2020-7-5 17:23:57 | 显示全部楼层
本帖最后由 rektito 于 2020-7-6 16:57 编辑

整个流程就是。 初始化,遇到被测信号的下降沿,打开外部中断,清零所有计数值。关闭外部中断。  等待到t0_hh>=20  (t0计的是基频,所以20个就是一个固定的时间长度T), 满足该条件后,再打开外部中断。等到新的被测信号的下降沿来临,到来时secondex=1;  (secondex作为一个标志,代表一个完整的测量) secondex=1时,测量一次完成,在主程序中进行处理。  
捕获到的时间长度t0_hh*f0   捕获到被测信号的个数 t1_hh  单个被测信号的频率 f = t1_hh  / (t0_hh*(1/f0))  。 由于f0是基频 肯定非常大   就是10000000  -- 10Mhz,当然 也有可能是因为算出的频率被放大了 所以加了一个系数。
  firstex,secondex定义出来就是为了控制整个时序逻辑,让整个程序先进中断,关中断。 再进中断,关中断。 完成一次后处理再输出。 然后循环该过程。





回复

使用道具 举报

109

主题

5562

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10541
金钱
10541
注册时间
2017-2-18
在线时间
1908 小时
发表于 2020-7-6 11:23:16 | 显示全部楼层
帮顶~~
回复

使用道具 举报

5

主题

11

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-6-16
在线时间
11 小时
 楼主| 发表于 2020-7-6 13:24:30 | 显示全部楼层
bit  firstex,secondex;这俩定义出来是干啥的,中断函数里面会用到,但不知道具体指的啥
回复

使用道具 举报

5

主题

11

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-6-16
在线时间
11 小时
 楼主| 发表于 2020-7-6 13:45:09 | 显示全部楼层
//外中断1
void init1() interrupt 2
{
if(firstex==0)
{
  TH1=0;
  TL1=0;
  TH0=0;
  TL0=0;
  t0_hh=0;
  t1_hh=0;
  TR1=1;
  TR0=1;
  EX1=0;
  firstex=1;
  secondex=0;
}
else
{
  TR1=0;
  TR0=0;
  secondex=1;
  EX1=0;
  q=q+1;
  if (q>2)
  {  led=1;
  }
  else
  { led=0;}
  if (q==3) q=0;
}
这个外中断函数就是完全看不懂了,求大佬讲解
回复

使用道具 举报

5

主题

11

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-6-16
在线时间
11 小时
 楼主| 发表于 2020-7-6 16:24:59 | 显示全部楼层
rektito 发表于 2020-7-6 15:05
整个流程就是。 初始化,遇到被测信号的下降沿,打开外部中断,清零所有计数值。关闭外部中断。  等待到t0_ ...

感谢大兄弟指导,你说的意思我大概懂了,那个频率换算我是懂了,但是count=(unsigned long)(adata+0.5);        这又是为啥
                q=q+1;                                                                                        //
                if (q>2)
                {                led=1;
                }
                else
                { led=0;}
                if (q==3) q=0;
这一段又是干啥的呢
回复

使用道具 举报

1

主题

89

帖子

0

精华

高级会员

Rank: 4

积分
832
金钱
832
注册时间
2020-6-12
在线时间
300 小时
发表于 2020-7-6 16:50:28 | 显示全部楼层
本帖最后由 rektito 于 2020-7-6 17:52 编辑
1392125062 发表于 2020-7-6 16:24
感谢大兄弟指导,你说的意思我大概懂了,那个频率换算我是懂了,但是count=(unsigned long)(adata+0.5);         ...

如果是特别低频的信号  秒级的 。 q和LED可能是外界LED的提示, 要不然你盯着LCD 不知道到底频率测量是不是刷新了。count=(unsigned long)(adata+0.5);  应该和频率测量的范围和频率显示的范围有关。 小数部分0.05Hz以上 都被当做0.1Hz  以下都被当做0Hz   你可以运行测量看看  因为主体已经有了   然后你核对一下实际信号输入频率和adata的关系  就能知道了。
我猜测可能有0~7  , 8位LCD来显示测量结果,有1位小数,7位整数。   所以最高显示精度只能到0.1Hz。  比如计算出来是1.16Hz 。那么adata = 1.16     adata  =(float)adata*10 = 11.6 ; count=(unsigned long)(adata+0.5) = 12   经过下面的求余  最后显示就是  1.2Hz   如果是1.14Hz经过这一套 就是1.1Hz
相当于一个对第2位小数的四舍五入。


回复

使用道具 举报

5

主题

11

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2020-6-16
在线时间
11 小时
 楼主| 发表于 2020-7-6 20:04:28 | 显示全部楼层
rektito 发表于 2020-7-6 16:50
如果是特别低频的信号  秒级的 。 q和LED可能是外界LED的提示, 要不然你盯着LCD 不知道到底频率测量是不 ...

懂了懂了,谢谢大哥
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 07:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表