基于C8051F340单片机的可编程计数器PCA0边沿触发的捕捉方式C程序

一、前言

C8051F340单片机的可编程技术阵列PCA0,可以工作在边沿触发的捕捉模式。
在该方式,CEXn引脚上出现的电平跳变导致PCA捕捉PCA计数器/定时器的值并将其装入到对应模块的16位捕捉/比较寄存器(PCA0CPLn和PCA0CPHn)。PCA0CPMn寄存器中的CAPPn和CAPNn位用于选择触发捕捉的电平变化类型:上升沿、下降沿。当捕捉发生时,PCA0CN中的捕捉/比较标志(CCFn)被置‘1’并产生中断请求(如果CCF中断被允许)。当转向中断服务程序时,CCFn位不能被硬件自动清除,必须用软件清0。如果CAPPn和CAPNn位都被设置辑‘1’,可以通过直接读CEXn对应端口引脚的状态来确定本次捕捉是由上升沿触发还是由下降沿触发。

二、程序展示

1、程序简介

本程序中应用定时器2产生方波通过P0.1输出,然后通过P0.0引入到PCA0。硬件上需要将P0.0和P0.1短接。

2、头文件部分

#include <c8051f340.h> 
#define SYSCLK       12000000 
#define T0_RELOAD 120   // 120为10us
#define T2_RELOAD 3000  //3000为250us
sfr16 PCA0CP0 = 0xFB;   
sfr16 TMR2RL = 0xCA;   
sfr16 TMR2 = 0xCC;  
sbit T2_OUT = P0^1;      // 用于测试的方波源
void OSCILLATOR_Init (void);
void PORT_Init (void);
void PCA0_Init (void);
void T2_Init (void);

3、主程序部分

main ()
{
   PCA0MD = 0x00;        // 关闭看门狗
   PORT_Init ();        //端口初始化
   OSCILLATOR_Init ();  // 晶振初始化
   PCA0_Init ();        //PCA0初始化
   T2_Init ();      // 定时器2初始化

   EA = 1;

   while (1)
   {
      if (TF2H)
      {
         T2_OUT = ~T2_OUT;       // 通过定时器250us翻转一次P0.1的输出
         TF2H = 0;               // 清定时器2溢出标志
      }

   };
}

4、晶振初始化程序

void OSCILLATOR_Init (void)
{
   OSCICN = 0x83;   // 使用内部晶振12M
   CLKSEL = 0x00;   
}

5、端口初始化程序

void PORT_Init (void)
{
   XBR0    = 0x00;
   XBR1    = 0x41;   //将CEX0配置到P0.0,
   P0MDOUT |= 0x02;  //设置 P0.1为推挽输出
}

6、PCA0初始化程序

void PCA0_Init (void)
{
   TMOD &= 0xF0;       // 清定时器0
   TMOD |= 0x02;      //8位自动重载
   CKCON |= 0x04;      //使用系统时钟
   TH0 = 0xFF-T0_CLOCKS;   // 设置T0重载值
   TL0 = 0xFF-T0_CLOCKS;   //设置初始值

   PCA0CN = 0x00;   //清除所有标志
   PCA0MD = 0x04;   //使用T0作为时基
   PCA0CPM0 = 0x21;  // 设置上升沿捕捉

   EIE1 |= 0x10;    // 允许PCA中断

   CR = 1;
   TR0 = 1;    // 启动定时器0
}

7、定时器2初始化程序

void T2_Init (void)
{

   CKCON |= 0x10;  // 使用系统12M

   TMR2RL = 0XFFFF-T2_RELOAD;    // 重载值
   TMR2 = 0XFFFF-T2_RELOAD;      

   TMR2CN = 0x04;            // 设置定时器2工作在16位自动重载模式
}

8、PCA0 中断程序

void PCA0_ISR (void) interrupt 11
{
   static unsigned int current_value, previous_value;
   static unsigned int capture_period;

   if (CCF0)  //如果中断是由CCF0引起
   {
      CCF0 = 0;  //清CCF0                      
      current_value = PCA0CP0;

      // 计算捕捉时间
      capture_period = current_value - previous_value;

      // 更新上一次的值
      previous_value = current_value;

   }
   else       // 中断如果由其他引起
   {
      PCA0CN &= ~0x86;   // 清除其他中断标志
   }
}
  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xll_007

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

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

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

打赏作者

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

抵扣说明:

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

余额充值