|
使用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示波器显示
-
信号源设置3万HZ显示
-
信号源设置3万HZ示波器显示
-
30万测量显示
-
240HZ测量显示
-
-
Keil代码.7z
49.02 KB, 下载次数: 22, 下载积分: 黑币 -5
评分
-
查看全部评分
|