ECBM函数库V3学习笔记④-PCA捕获测量脉冲频率

利用STC单片机的PCA模块可以测量脉冲宽度

代码参考STCISP上的范例程序

 1所需硬件:

1 PWM模块 信号发生器

 2 STC8A8K单片机

2 ECBM设置,如图

 

 

由上图可以看出本次试验并没有启用PCA计数器溢出回调函数,因为计算必须在中断中快速进行。开始我也是在回调函数中计算,但数据很不稳定。取消回调函数后数据很稳定。

在nvic.c中声明如图变量

 具体代码:

unsigned char cnt=0;
volatile unsigned char finshFlag=0;  //存储PCA计时溢出次数
unsigned long count0=0;             //记录上一次的捕获值
unsigned long count1=0;             //记录本次的捕获值
unsigned long length=0;             //存储信号的时间长度

 中断中的程序

 中断程序的代码

/*-------------------------------------------------------
PCA的各种中断处理函数。
-------------------------------------------------------*/
#if ECBM_PCA_LIB_EN
void nvic_pca_function(void)interrupt 7{
    if(PCA_GET_IT_FLAG){
        PCA_CLS_IT_FLAG;
			  cnt++;
			  #if ECBM_PCA_CALLBACK_EN
			   pca_timer_callback();
        #endif
    }
		if (CCF0)
       {
        CCF0 = 0;
        count0 = count1;            //备份上一次的捕获值
        ((unsigned char *)&count1)[3] = CCAP0L;
        ((unsigned char *)&count1)[2] = CCAP0H;
        ((unsigned char *)&count1)[1] = cnt;
        ((unsigned char *)&count1)[0] = 0;
        length = count1 - count0;   //计算两次捕获的差值,即得到时间长度
	     finshFlag=1;	
	     }

main.c

#include "ecbm_core.h"  //加载库函数的头文件。
#define T    0.090422454//11.0592M时钟周期
extern unsigned char cnt; 
extern unsigned char finshFlag; 
extern unsigned long length;   
double freq;
void main(void){        //main函数,必须的。
    system_init();      //系统初始化函数,也是必须的。
	  pca_init();
	  uart_printf(1,"ECBM 测量频率测试\r\n");//打印count变量的值 
	   while(1){
			if(finshFlag)
			{
	     freq=1000000L/(length*T);
// 		 uart_printf(1,"length=%ld\r\n",length);//打印count变量的值 
			 uart_printf(1,"freq=%3.2fHz\r\n",freq);
			 delay_ms(200);
			 finshFlag=0;			
			}
    }
}

运行效果

附:STC8G1K08 P5.4输出362.83Hz        外部晶振11.0592M/240/127=362.83Hz

#include "reg51.h"

#define MCLKOCR         (*(unsigned char volatile xdata *)0xfe05)
#define CLKDIV          (*(unsigned char volatile xdata *)0xfe01)
#define CKSEL           (*(unsigned char volatile xdata *)0xfe00)
#define XOSCCR          (*(unsigned char volatile xdata *)0xfe03)
sfr     P_SW2       =   0xba;

sfr     P0M1        =   0x93;
sfr     P0M0        =   0x94;
sfr     P1M1        =   0x91;
sfr     P1M0        =   0x92;
sfr     P2M1        =   0x95;
sfr     P2M0        =   0x96;
sfr     P3M1        =   0xb1;
sfr     P3M0        =   0xb2;
sfr     P4M1        =   0xb3;
sfr     P4M0        =   0xb4;
sfr     P5M1        =   0xc9;
sfr     P5M0        =   0xca;

void main()
{
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    P_SW2 = 0x80;
    XOSCCR = 0xc0;                              //启动外部晶振
    while (!(XOSCCR & 1));                      //等待时钟稳定
	CLKDIV=0XF0;
    CKSEL = 0x01;                               //选择外部晶振
//  MCLKOCR = 0x01;                             //主时钟输出到P5.4口
//  MCLKOCR = 0x02;                             //主时钟2分频输出到P5.4口
    MCLKOCR = 0x7F;                             //主时钟4分频输出到P5.4口
//  MCLKOCR = 0x84;                             //主时钟4分频输出到P1.6口
    P_SW2 = 0x00;

    while (1);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

armcsdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值