OpenEdv-开源电子网

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

STC89C52做的频率计,测量结果不对,求助!!

[复制链接]

3

主题

7

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2019-5-7
在线时间
7 小时
发表于 2019-5-15 11:10:29 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 muscle 于 2019-5-15 12:42 编辑

这个里面我用了两块板子,一块作为信号发生部分,一块作为检测部分。
信号发生部分代码如下:
#include <reg52.h>

sbit out = P2^7;

sbit led5 = P1^4;
sbit led6 = P1^5;
sbit led7 = P1^6;

sbit key1 = P3^3;
sbit key2 = P3^4;

sbit led_s1 = P1^0;
sbit led_s2 = P1^1;
sbit led_s3 = P1^2;
sbit led_s4 = P1^3;

unsigned int cnt = 0;
unsigned int ctl_freq = 100;

//共阳极数码管真值表
unsigned char code buf[10] = {
                0xc0,0xf9,0xa4,0xb0,0x99,
                0x92,0x82,0xf8,0x80,0x90
};

void delay_10ms(void)   //误差 -0.000000000023us
{
    unsigned char a,b;
    for(b=249;b>0;b--)
        for(a=17;a>0;a--);
}

void delay_100us(void)   //误差 -0.217013888889us
{
    unsigned char a,b;
        for(b=1;b>0;b--)
        for(a=43;a>0;a--);
}

/*****************************************
名称:数码管显示函数
功能:显示获取的温湿度值
参数:   
    @ temp: 高两位显示的值
    @ humi: 低两位显示的值
******************************************/
void show(unsigned int y)
{
    char one = y%10;
    char ten = y/10%10;
    char hun = y/100%10;
    char ths = y/1000%10;

        led_s1 = 0;
    led_s2 = 1;
    led_s3 = 1;
    led_s4 = 1;
    P0 = buf[one];
    delay_100us();
    P0 = 0xff;

    led_s1 = 1;
    led_s2 = 0;
    led_s3 = 1;
    led_s4 = 1;
    P0 = buf[ten];
     delay_100us();
    P0 = 0xff;

    led_s1 = 1;
    led_s2 = 1;
    led_s3 = 0;
    led_s4 = 1;
    P0 = buf[hun];
    delay_100us();
    P0 = 0xff;

    led_s1 = 1;
    led_s2 = 1;
    led_s3 = 1;
    led_s4 = 0;
    P0 = buf[ths];
    delay_100us();
    P0 = 0xff;

}

int main(void)
{

    TMOD = 0x01;
    TH0  = 0xff;
    TL0  = 0xfb;
    TR0 = 1;
    ET0 = 1;
        EA  = 1;

    while(1)
    {

                show(ctl_freq);

                if(0 == key1)
                {
                        delay_10ms();
                        if(0 == key1)
                        {
                                while(!key1);

                                if(ctl_freq<1000)
                                        ctl_freq++;
                        }
                }

                if(0 == key2)
                {
                        delay_10ms();
                        if(0 == key2)
                        {
                                while(!key2);

                                if(ctl_freq>1)
                                        ctl_freq--;
                        }
                }

        

    }
}

  //5us触发
void timer_interrupt1(void) interrupt 1
{
        cnt++;

        TH0  = 0xff;
       TL0  = 0xfb;
           
        if(cnt >= ctl_freq)
        {
                out = ~out;
                cnt = 0;
        }         
}
ctl_freq初值为100,即500us的高电平,500us的低电平,两者相互转换。周期为1ms,频率为1000Hz,但是用示波器测出来频率为150Hz,这是第一个问题。

检测部分主函数代码如下:
void  main()
{

        timer0_init();
        timer1_init();

    delay(10);                 //延时

    lcd_init();                //初始化LCD  
                  
    show_lcd();

     while(1)
         {
                 if(cnt_timer == 50)
            {
                TR1 = 0;
                        ET1 = 0;
                        TR0 = 0;
                        ET0 = 0;

                freq = (cnt_x*65536+TL1+TH1*256);
                TL1 = 0;
                TH1 = 0;
                cnt_timer = 0;
                cnt_x = 0;
               
                        del_data();
                        show_lcd();

                        TR1 = 1;
                        ET1 = 1;
                        TR0 = 1;
                        ET0 = 1;
            }

}
定时器中断代码如下:
void timer_interrupt1(void) interrupt 3
{
        cnt_x++;
        TL1 = 0x00;
        TH1 = 0x00;
}

void timer_interrupt0(void) interrupt 1
{
        cnt_timer++;
        TL0 = 0xb8;
        TH0 = 0x00;
}

此时检测部分测出来的频率为533Hz,与计算的结果和示波器的结果都不一样。

1557888883319.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10553
金钱
10553
注册时间
2017-2-18
在线时间
1910 小时
发表于 2019-5-15 12:52:18 | 显示全部楼层
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2019-5-7
在线时间
7 小时
 楼主| 发表于 2019-5-15 15:03:34 | 显示全部楼层
已经解决检测端的,把定时器赋值给错了。。
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2019-5-7
在线时间
7 小时
 楼主| 发表于 2019-5-15 15:06:03 | 显示全部楼层
信号发生部分因为定时器中断5us触发一次,但是里面执行代码耗费时间挺多,影响了翻转时间,导致频率不对,改成100us的中断之后号很多了,如果有大佬指点5us写法的话,感激不尽。
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2019-5-29
在线时间
13 小时
发表于 2019-5-29 15:29:56 | 显示全部楼层
检测部分的程序可以私法给我参考一下嘛 我最近也在做这个 学校里面的课题设计 没办法 求助
回复

使用道具 举报

0

主题

18

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2015-10-16
在线时间
71 小时
发表于 2020-2-23 13:52:07 | 显示全部楼层
muscle 发表于 2019-5-15 15:06
信号发生部分因为定时器中断5us触发一次,但是里面执行代码耗费时间挺多,影响了翻转时间,导致频率不对, ...

对于频率发生的MCU
        利用Timer2的频率输出功能,TMOD2 =0x02,自动在P1.0上产生输出脉冲。都不需要开启Timer2的中断。MCU如果想要修改时钟频率,只需在主程序中修改RCAP2H和RCAP2L值就可以了。
对于对于检测脉冲频率的MCU
      利用Timer2的captue捕获功能,在T2EX脚有下降沿时,将TH2/TL2放置在RCAP2H和RCAP2L中,并产生中断。只需在中断中根据RCAP2H和RCAP2L计算反推频率。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-1 05:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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