STC15F2K60 脉宽测量程序

本文介绍如何利用STC15单片机的PCA模块进行脉冲占空比测量。主要内容包括PCA模块的基本配置、启动捕获过程及中断服务程序的设计。特别注意的是,PCA中断开启后若关闭将无法再次启用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


idata WORD cnt;                           //存储PCA计时溢出次数
idata WORD count0_tmp;                       //记录上一次的捕获值
idata WORD count1_tmp;

idata long int count0;
idata long int count1;

idata WORD result;

BYTE flag_updown;

#define CCP_S0 0x10                 //P_SW1.4
#define CCP_S1 0x20                 //P_SW1.5
sbit EPCA       =   IE^6;           //PCA中断允许位

void InitPCA()
{
    ACC = P_SW1;
    ACC &= ~(CCP_S0 | CCP_S1);      //CCP_S0=0 CCP_S1=0
    P_SW1 = ACC;                    //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2)

    CCON = 0;                       //初始化PCA控制寄存器
                                    //PCA定时器停止
                                    //清除CF标志
                                    //清除模块中断标志
    CL = 0;                         //复位PCA寄存器
    CH = 0;
    CCAP0L = 0;
    CCAP0H = 0;
    //CMOD = 0x09;                    //设置PCA时钟源为系统时钟,且使能PCA计时溢出中断
    CMOD = 0x01;    //12
}

void EnablePCA()//启动捕获
{
 flag_updown = 1;

 CCAPM0 = 0x21; //PCA模块0为16位捕获模式(上升沿捕获,可测从高电平开始的整个周期),且产生捕获中断
 CR = 0;                         //
        EPCA = 1;                       //使能PCA中断
}


/***********************************************************
功能:PCA中断服务程序,用于测定脉冲占空比:
变量:
 flag_updown : 捕获脉冲标志 置0时程序不捕获脉冲,置1时开始捕获,计算完占空比后由本函数清零 
 count0:低电平时间
 count1:高电平时间

说明:STC15单片机的PCA中断开启后关闭则无法再次开启
      关于STC15单片机的PCA中断,如果作为定时器,中断号为7  如果作为脉冲捕获,中断号为6(并非手册说明7)
      以上结论仅为本人经验

     琛琛   2013/11/3
***********************************************************/
void PCA_isr() interrupt 6 //using 1
{
    if (CF)
    {
        CF = 0;
        cnt++;                      //PCA计时溢出次数+1
    }
    if (CCF0)
    {
        CCF0 = 0;
     if(flag_updown == 1)//捕获到上升沿,开定时器,准备捕获下降沿
  {
    CR = 1;                         //PCA定时器开始工作
    CCAPM0 = 0x11;                  //PCA模块0为16位捕获模式(下降沿捕获,可测从低电平开始的整个周期),且产生捕获中断
    flag_updown = 2;
  }
  else if(flag_updown == 2)//捕获到下降沿,读取定时器,准备捕获上升沿
  {
    count0 =  CCAP0H;
    count0 = count0 << 8;
    count0 = count0 + CCAP0L;

    CCAPM0 = 0x21;                  //PCA模块0为16位捕获模式(上升沿捕获,可测从高电平开始的整个周期),且产生捕获中断
    CCAP0L = 0;
    CCAP0H = 0;
    flag_updown = 3;
  }
  else if(flag_updown == 3)//捕获到上升沿,读取定时器,完成一次检测
  {
    EA = 0;
    CR = 0;                         //关闭PCA定时器
                  //EPCA = 0;                       //关闭PCA中断   关闭之后打不开了
    flag_updown = 0;
    //LED = 0;  

    count1 =  CCAP0H;
    count1 = count1 << 8;
    count1 = count1 + CCAP0L;
   
   // count1_tmp = count1;
   // count0_tmp = count0; 

    result = (10*count0+500)/count1;
    //result = ((float)count0/(float)count1)*10;

    count0 = 0;
    count1 = 0;
    CL = 0;                         //复位PCA寄存器
               CH = 0;
    CCAP0L = 0;
               CCAP0H = 0;
    cnt = 0;
    
    //SendData('A'); //测试能否完成一次测试标志 如果可以完成一次测试,则串口输出'A'  
    
    EA = 1;
  }
    }
}

### STC15F2K60S2单片机实现呼吸灯效果 要实现STC15F2K60S2单片机上的呼吸灯效果,可以通过PWM(调制)技术来调节LED亮度。具体方法是利用定时器中断生成不同占空比的PWM信号,从而模拟灯光逐渐变亮和变暗的过程。 以下是具体的代码示例: #### 头文件与初始化设置 为了适配STC15F2K60S2的功能特性,需引入对应的头文件`STC15F2K60S2.h`[^3]。此头文件支持更多特定功能引脚的操作,例如P4端口。 ```c #include <STC15F2K60S2.h> // 使用适合该芯片的头文件 sbit LED = P1^0; // 定义LED连接到P1.0引脚 unsigned char Brightness = 0; // 当前亮度值 unsigned char Direction = 1; // 控制增减方向 (1表示增加, 0表示减少) ``` #### 定时器配置 通过配置定时器T0作为PWM波形发生的基础时间基准。这里设定为模式1(16位自动重载),并开启中断。 ```c void Timer0_Init() { TMOD |= 0x01; // 设置T0工作于模式1 TH0 = 0xFC; // 预设初值用于约每毫秒触发一次中断 TL0 = 0x18; ET0 = 1; // 开启T0中断允许 TR0 = 1; // 启动T0计数 } ``` #### 中断服务程序设计 在每次进入定时器溢出中断时调整LED点亮的时间比例即改变其视觉上感知的明暗程度。 ```c void Timer_ISR(void) interrupt 1 { static unsigned int Counter=0; if(++Counter >= 256){ Counter = 0; LED = 0; // 关闭LED以便准备下一个周期 } if(Counter <= Brightness){ LED = 1; // 根据当前亮度决定是否打开LED } if(Direction && Brightness<255){ Brightness++; // 如果处于上升阶段则提高亮度 }else{ if(!Direction && Brightness>0){ Brightness--; // 下降阶段降低亮度 } } if(Brightness>=255 || Brightness<=0){ Direction=!Direction; // 达到极限后反转变化趋势 } } ``` 以上代码片段展示了如何使用软件方式产生近似正弦曲线样式的光强过渡效果[^4]。 #### 主函数部分 最后,在主循环里只需保持运行状态即可让上述机制持续作用。 ```c void main(){ EA = 1; // 总中断使能 Timer0_Init(); // 初始化定时器 while(1); // 循环等待 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值