搜索
bottom↓
回复: 2

(转)比较/ 捕捉/PWM (CCP)模块

[复制链接]

出0入0汤圆

发表于 2014-9-24 16:44:44 | 显示全部楼层 |阅读模式
http://www.cnblogs.com/wangh0802 ... /07/22/2604074.html

PIC18F452(有两个ccp)每个CCP(捕捉/ 比较/PWM )模块有一个16位寄存器,它可以用作16位捕捉寄存器、16位比较寄存器或PWM 主/ 从占空比寄存器。除了特殊事件触发器之外,CCP1的操作和CCP2相同。

  捕捉/ 比较/PWM 寄存器1(CCPR1)由两个 8 位寄存器组成:CCPR1L (低字节)和 CCPR1H(高字节)。CCP1CON 寄存器控制CCP1 的操作。

  捕捉/ 比较/PWM 寄存器2(CCPR2)由两个 8 位寄存器组成:CCPR2L (低字节)和 CCPR2H(高字节)。CCP2CON 寄存器控制CCP2 的操作。

      CCP模式-定时器资源:捕捉:Timer1或Timer3;比较:Timer1或Timer3;PWM:Timer2。
  给CCPRx一个值,  开定时器 TMR1计数.   定时器可以零开始计数,不断和CCPRx的数据对比,如果相同则相应动作. (纯自动的,设定好CCPRx 并开启CCP模块就可以, )CCPRx不能自加.
CCP1CON 寄存器/CCP2CON 寄存器。

      捕捉模式:在捕捉模式下,当RC2/CCP1 引脚上有事件发生时,CCPR1H:CCPR1L即捕捉TMR1 或TMR3 寄存器的16位计数值。事件定义如下:
•     每个下降沿发生
•     每个上升沿发生
•     每4 个上升沿发生
•     每16个上升沿发生
     由控制位 CCP1M3:CCP1M0(CCP1CON<3:0>)来选择上述 4 种事件之一。当发生捕捉事件时,中断请求标志位 CCP1IF(PIR1<2> )置 1 ;该位必须用软件清零。如果在读出寄存器CCPR1中的值之前发生另一个捕捉,那么之前捕捉的值将会被覆盖。捕捉模式的改变会产生错误的捕捉中断。用户应保持
CCP1IE 位(PIE1<2> )为 0 以免发生错误中断,并且应该在任何操作模式改变后清零标志位CCP1IF。

    通过设置CCP1M3:CCP1M0位可以选择四种预分频值设置。只要CCP模块关闭或没有设置为捕捉模式,就可将预分频器的计数器清零。这就意味着任何复位都可以将预分频器计数器清零。从一个捕捉预分频器切换到另一个捕捉预分频器可能产生中断。而且,预分频器计数器不会被清零,因此第一次捕捉可能是来自一个非零的预分频器。


复制代码
  1 /*CCP1输出比较*/
  2 #include "pic.h"
  3
  4 void initPORTB(void);
  5 void initCCP1(void);
  6 void interrupt CCP1INT(void);
  7
  8 void main()
  9 {
10 initPORTB();
11 initCCP1();
12 while(1)
13 {
14 }
15 }
16
17 void initCCP1()
18 {
19 TRISC=0x00;
20 T1CON=0x00;
21 CCPR1H=0x61;
22 CCPR1L=0xa8;
23 CCP1CON=0x0a;
24 CCP1IE=1;
25 PEIE=1;
26 GIE=1;
27 TMR1ON=1;
28 }
29
30 void interrupt CCP1INT(void)
31 {CCP1IF=0;
32 TMR1ON=0;
33 TMR1H=0x00;
34 TMR1L=0x00;
35 T1CON=1;
36 RB0=!RB0;
37 }
38
39 void initPORTB()
40 {
41 TRISB=0xfe;
42 PORTB=0x00;
43 }
44
45
46  
47 PIC项目之CCP捕捉模块
48
49 /*Used pic16C77, CCP捕捉*/
50 #include "pic.h"
51 #define uint unsigned int
52
53 void initPORTB(void);
54 void initCCP1(void);
55 void interrupt CCP1INT(void);
56 void display(void);
57
58 __CONFIG(WDTDIS&XT&UNPROTECT);
59 uint counter=0;
60
61 void main()
62 {
63 initPORTB();
64 initCCP1();
65 while(1)
66 {display();}
67 }
68
69 void initPORTB()
70 {
71 TRISB=0x00;
72 PORTB=0x00;
73 }
74
75 void initCCP1()
76 {
77 TRISC=0x04;
78 GIE=0;
79 PEIE=0;
80 CCP1IE=0;
81 CCP1IF=0;
82 CCP1IE=1;
83 CCP1IF=1;
84 PEIE=1;
85 GIE=1;
86 CCP1CON=0x04;
87
88 }
89
90 void interrupt CCP1INT(void)
91 {
92 GIE=0;
93 CCP1IE=0;
94 CCP1IF=0;
95 counter++;
96 if(counter>9) counter=0;
97 CCP1IE=1;
98 GIE=1;
99 }
100
101 void display()
102 {
103 PORTB=counter;
104 }
复制代码

复制代码
1 #include<pic.h>
2 __CONFIG(0x3f3a);
3
4 #define    CPPDUTY      RA2      //占空比加按键
5 #define    CPPDUTY_PULSE   RA3     //占空比减按键
6
7 void CCP1INIT(void);
8 void INI(void);
9 void tmint(void);
10 void interrupt clkint(void)
11
12 unsigned char QC,CCP1_DUTY=0,DUTY_PULSE;
13
14 //主程序
15
16 main()
17 {
18      INI();
19      
20      tmint();
21      while(1)
22      {
23             CCP1INIT();//CCPR1L与DC1B1与DC1B0共同组成占空比的可调范围,以当前程序为例,则占空比为DC1B<9:0)*Tosc*TMR2预分频
24         CCPR1L=CCP1_DUTY;
25             if((CPPDUTY==0)&&(QC==0))
26            {
27                    CCP1_DUTY++;
28                    CCP1_DUTY=CCP1_DUTY>=254254:CCP1_DUTY;
29            }      
30            if((CPPDUTY_PULSE==0)&&(QC==0))
31           {
32                  CCP1_DUTY--;
33                  CCP1_DUTY=CCP1_DUTY<=1?1:CCP1_DUTY;
34           }
35           if(QC>255) QC=0;
36      }
37 }
38
39 void CCP1INIT()              //CCP1模块的PWM工作方式初始化子程序*/
40 {//CCPR1L与DC1B1与DC1B0共同组成占空比的可调范围,以当前程序为例,则占空比为DC1B<9:0)*Tosc*TMR2预分频
41    CCP1CON=0X3C;        //设置CCP1模块为PWM工作方式,且其占它比的低两位DC1B1与DC1B0为11
42     PR2=255;     //设置PWM的工作周期,也即PWM的工作频率  其中PWM周期=(PR2+1)*4*Tosc*TMR2预分频比,Tosc为MCU的振荡周,以当前程序为例,则PWM的输出频为  1/{(156+1)*4*0.25us(4M晶体)*1}=6.3694267515923566878980891719745
43      T2CON=4;             //打开TMR2,且使其前预分频为1:1,后分频比为1:1,但在这个程序中后分频比用不上
44 }
45
46 void  INI(void)
47  {
48      ADCON1=0B00000111; //A口全作数字IO
49      TRISA=0XFF;        //全输入
50    TRISB=0;
51      GIE=1;
52  }
53
54
55
56 void interrupt clkint(void)   //定时器中断函数
57 {         
58            QC++;              
59            T0IF=0x0;
60 }
61
62
63 void tmint(void)               //定时初始化函数               
64 {
65           T0CS=0;                //T0CS是TMR0的时钟源选择位,当其=1时是用RA4(T0CKI)的外部输入时钟,当其=0时是用内部指令周期时钟(CLKOUT)
66        PSA=0;                 //PSA是预分频器分配位,当其=1预分频器分配给WDT,当其=0时预分频器分配给Timer0 模块
67        PS2=0;                 //PS2:PS1:PS0:预分频比选择位  1 1 1是256分频
68        PS1=0;
69           PS0=0;
70           T0IF=0;                //T0IF是TMR0溢出中断标志位,当其=1时TMR0 寄存器已经溢出(必须用软件清零),当其=0时寄存器尚未发生溢出
71       T0IE=1;                //T0IE是TMR0 溢出中断允许位当其=1时允许TMR0 溢出中断,当其=0时禁止TMR0 溢出中断
72 }
复制代码
    比较模式下,16位CCPR1(CCPR2)寄存器的值随时与TMR1 或TMR3 寄存器对的值相比较。当两者相符时,RC2/CCP1 (RC1/CCP2 )引脚将:
•     变为高电平
•     变为低电平
•     翻转输出(高电平变为低电平或低电平变为高电平)
•     保持不变
    引脚的状态取决于控制位CCP1M3:CCP1M0(CCP2M3:CCP2M0)的值。同时,中断标志位CCP1IF(CCP2IF)置1 。

  用户必须通过将相应的TRISC位清零,将CCPx 引脚配置为输出引脚。 如果CCP模块使用比较功能,Timer1和/ 或Timer3必须工作在定时器模式或同步计数器模式。在异步计数器模式下,可能无法进行比较操作。

    当选择了产生软件中断时,CCP1 引脚上的电平不受影响。CCP中断使能时,只会产生一个CCP中断。

    在这一模式下,将产生一个内部硬件触发信号,可用来触发一个操作。CCP1 的特殊事件触发器输出使TMR1 寄存器对复位。这将使CCPR1寄存器有效地成为Timer1的16位可编程周期寄存器。CCPx 的特殊事件触发器输出使TMR1 或TMR3 寄存器对复位。另外,如果 A/D 模块使能,则 CCP2 特殊事件触发器将启动A/D 转换。   

     在脉冲宽度调制(Pulse Width Modulation,PWM)模式下,CCP1 引脚可产生分辨率高达10位的PWM 输出。因为 CCP1 引脚与PORTC 数据锁存器复用,所以TRISC<2>位必须清零以使CCP1引脚为输出状态。

     PWM 周期可通过写入PR2 寄存器来指定。可用以下公式计算PWM 周期:
                                          PWM 周期=(PR2)+1]•4•TOSC•(TMR2 预分频值)
     PWM 频率定义为1/[PWM 周期] 。
    当TMR2 等于PR2 时,在下一递增计数周期中将产生下面三个事件:
•     清零TMR2
•     将CCP1 引脚置1 (例外情况:如果PWM 占空比= 0%,CCP1 引脚不被置1 )
•    PWM 占空比从CCPR1L 被锁定为CCPR1H  

      PWM 占空比可通过向 CCPR1L 寄存器和CCP1CON<5:4> 位写入来指定。最高分辨率可达10位。CCPR1L 包含8 位MSb,CCP1CON<5:4>包含2位LSb 。这10位值由CCPR1L:CCP1CON<5:4> 来表征。计算PWM 占空比的公式如下:
                              PWM 占空比= (CCPR1L:CCP1CON<5:4>) •TOSC  • (TMR2 预分频值)
      可以在任何时候写入CCPR1L 和CCP1CON<5:4>,但直到PR2 与TMR2 中的值相符(例如,当周期结束)时,占空比的值才被锁存到CCPR1H。在PWM 模式
下,CCPR1H是只读寄存器。CCPR1H寄存器和一个2 位的内部锁存器用于为PWM占空比提供双重缓冲。对于PWM 的无毛刺操作,  双重缓冲是很必要的。
      当CCPR1H和2 位锁存器的值与附加了内部2 位Q 时钟或2 位TMR2 预分频器的TMR2 相符时,CCP1 引脚被清零。对于给定的PWM频率,其最大分辨率(位)为?

      设置PWM 操作通过以下步骤将CCP模块配置为PWM 操作:
1. 写入 PR2 寄存器以设定 PWM周期。
2. 写入CCPR1L 寄存器和CCP1CON<5:4>位以设置PWM 占空比。
3. 将TRISC<2> 位清零以将CCP1 引脚设为输出。
4. 写入T2CON 以设置TMR2 预分频值并使能Timer2。
5. 将CCP1 模块配置为PWM 模式。

出0入0汤圆

发表于 2014-9-24 23:46:36 | 显示全部楼层
不错!感谢楼主分享!

出0入0汤圆

发表于 2014-9-25 08:31:48 | 显示全部楼层
感谢楼主分享!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-5 18:04

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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