找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1676|回复: 3
收起左侧

使用stc32g12k128单片机的高精度脉冲频率测量例程

[复制链接]
ID:1039438 发表于 2022-10-9 16:38 | 显示全部楼层 |阅读模式
    使用mcu对脉冲频率进行测量有多种方法,最基本的是定时长脉冲计数法和周期测量法。其中定时长计数法适合高频脉冲测量,其测量能力和精度由Mcu的端口速度和系统时钟限定。周期测量法适合低频端脉冲测量。这两种方式在中间频率上都存在明显的误差。
本例程给出了一种基于stc32g12k128的频率测量方法。采用系统时钟11059200HZ时适合频率是200HZ——900KHZ。根据需要可以向高端或低端扩展,是一种简单的宽频率范围的测量程序。
    本例程在提高测量精度方面是从三个角度着手。一是两端对齐,就像用尺子测量棍子时所做的,把棍子两端与尺子的刻度对齐,方能测量准确。在测量时把脉冲信号与时钟信号正确对齐,来提高测量精度。二是采用双精度时钟,这与游标卡尺的原理相似,一个大刻度尺子粗测,一个小刻度尺子用来精测。三是增加测量时间长度。取较长的时间测量,可以使误差相对去减小。
    例程中使用PWMA的ccp1通道的外时钟模式一对脉冲信号进行计数,信号输入在P1.0口,定时器T0做主时间定时,使用12T模式,初值为0,以获得更多测量时长。定时器T1进行精测计时,采用1T模式,以提高测量精度。利用PWMA的上升沿中断来启动和结束计数和计时,获得好的对齐效果。
    在需要向高频端扩展时,可以提高系统时钟频率(如改为33177600)和对被测信号进行分频(当前未开分频,可以分频值为2—8分频),把测量频率的上限扩展到20M以上,这时的限制在于mcu端口本身的速度。需要向低频端扩展时,可以把T1定时器改为12T模式,测量频率下限则为15HZ。
扩展时还需要修改程序内的两个计算常数。如果想同时向两个方向扩展,则需要修改程序流程,增加频段选择的相关操作。
    如果想进一步提高测量精度,则需要采用外置高精度高稳定度晶振。并对程序中影响测量精度的语句进行补偿(给T1定时器设一个初值)。相信该例程本身能够满足专业测量频率的需要。
    下面给出例程主体,包括主程序和配置程序。未列出的程序包括显示屏的驱动程序和各种头文件。在附件中有完整程序供初学者参考和使用。
附图中显示屏上的第二行为被测频率的计数值,第三行为两个定时器的计数值之和。被测频率的计数值会出现正负一个数的变动,定时器测量值也会随之变动,但测结果不受影响。

单片机源程序如下:
#include "STC32G.H"
#include "stc32_12864driver.h"
#include "mcu_initial.h"
#include "initial_lcd.h"
#include "chinese_zhouqi.h"
unsigned long int cnt1=10,cnt2,cnt3;//cnt1的初值是为指示程序是否进入测量状态。cnt2,cnt3是调试时用到的参数
bit first=0;//程序走向控制参数,初值不影响测量结果
void main(void)
{
        mcu_initial();
        initial_lcd();
        clear_screen();
transfer_chine_word(1,0,pin);
transfer_chine_word(1,16,lu);
        PWMA_SR1=0;//中断标志位清零
        PWMA_CR1|=0x01; //使能计数器
        PWMA_IER=0x02;//开捕获中断,用于捕获第一次中断
        while (1)
{      
        digit6_display(1,32,(cnt1*(1105920000/(cnt3+1)))/100);//输出频率
        digit6_display(3,32,cnt1);//显示精确捕获计数
        digit6_display(5,32,cnt3);//显示总计时器值,该值以1T的精度显示超过12T的定时计数值
}
}
void t0_isr() interrupt 1 //定时
{
        TR1=1;
        TR0=0;
        PWMA_SR1=0;//中断标志位清零
        PWMA_IER=0x02;//开捕获中断,用于捕获第二次中断
}

void PWMA_isr() interrupt 26//用来启动和停止计数器,输出测量数值
{
first=!first;
        if(first)
{
        TR1=0;//停定时器
        cnt1=(PWMA_CCR1H<<8)+PWMA_CCR1L; //CCp1 捕获值输出
        cnt2=(TH1<<8)+TL1;//读计时器
/*
        cnt2=TH1;
        cnt2=(cnt2<<8);
        cnt2=cnt2+TL1;
        */
        cnt3=cnt2+(65535*12);        //两个定时器的计时值之和
        //下一次测量的初始化
        TL1 = 0x00;                //设置定时初始值
        TH1 = 0x00;                //设置定时初始值
        TL0 = 0x00;                //设置定时初始值
        TH0 = 0x00;                //设置定时初始值
        PWMA_EGR|=0x01;//产生一次更新事件,可用来使计数器初始化,硬件自动清零
        PWMA_SR1=0;//中断标志位清零
        PWMA_IER=0x02;//开捕获中断,用于捕获第一次中断
        PWMA_CR1|=0x01; //使能计数器
}
else
{
        TR0=1;//开T0定时器
        PWMA_SR1=0;//中断标志位清零
        PWMA_IER=0;//关捕获中断
}

}
#include "mcu_initial.h"
#include "STC32G.H"
void mcu_initial(void)
{
P_SW1=0x04;//选择P2.2,2.4,2.4.2.5输出SPI
EAXFR = 1; //使能访问 XFR
CKCON = 0x00; //设置外部数据总线速度为最快
WTST = 0x00; //设置程序代码等待参数,        
        P1M0=0x00;   //P1配置为高阻,其中的P1.6为双向。P1.0输入被检测脉冲
        P1M1=0xbf;
                P2M0=0xFF;//P2为推挽,其实双向模式也可
        P2M1=0x00;
        P3M1|=0x04;
        P3M0&=0xfb;//把P3.2设置为高阻端,用于外部模式二输入被测信号,本程序中没用到

        AUXR &= 0x7F;                //定时器0时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0;                //设置定时初始值
        TH0 = 0;                //设置定时初始值4ms,11M
        TF0 = 0;                //清除TF0标志
      
        AUXR |= 0x40;                //定时器1时钟1T模式
        TMOD &= 0x0F;                //设置定时器T1模式
        TL1 = 0x00;                //设置定时初始值
        TH1 = 0x00;                //设置定时初始值
        TF1 = 0;                //清除TF1标志

        HSSPI_CFG2=0X20;//开高速SPI模式,方便使用33M时钟
        SPSTAT=0x00;
        SPCTL=0xd3;                                                                                 

        MCLKOCR=0x82;//P1.6输出2分频系统时钟,提供一个方便的测试信号源

//外部模式一
        PWMA_PS=0x00;//选择P1.0输入外部信号
        PWMA_CCER1=0x00;//关cc1通道,准备写CCMR1
        PWMA_CCMR1=0x01;//PWMA_CCMR1.CC1S=01//IC1映射在TI1FP1上。设置为输入模式,关滤波,关预分频器
        PWMA_CCER1=0X01;//选择cc1p上升沿极性.使能cc1p
        PWMA_SMCR=0x57;//选中外部触发输入。上升沿触发,复位模式,输入通道在TI1FP1,资料参考值为0x57
        PWMA_SR1=0;//中断标志位清零
        PWMA_SR2=0;//重复捕获中断标志位清零

        EA=1;
        ET0=1;
}

信号源设置8400HZ显示

信号源设置8400HZ显示

信号源设置8400HZ示波器显示

信号源设置8400HZ示波器显示

信号源设置3万HZ显示

信号源设置3万HZ显示

信号源设置3万HZ示波器显示

信号源设置3万HZ示波器显示

30万测量显示

30万测量显示

240HZ测量显示

240HZ测量显示

Keil代码.7z

49.02 KB, 下载次数: 22, 下载积分: 黑币 -5

评分

参与人数 2黑币 +104 收起 理由
STC庄伟 + 4 赞一个!
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:1017706 发表于 2022-10-12 14:57 | 显示全部楼层
不错,我过来看看学习下
回复

使用道具 举报

ID:1047952 发表于 2022-10-17 08:48 | 显示全部楼层
这用到了  STC-ISP 的 调试显示接口了,毕竟 普通的 LCD 显示能力太弱了
回复

使用道具 举报

ID:1038726 发表于 2022-10-17 08:55 | 显示全部楼层
我也去STC申请样品测试一下,程序有了,直接照抄啦
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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