佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 2535|回复: 15

关于pwm modules

[复制链接]
发表于 28-8-2009 09:50 PM | 显示全部楼层 |阅读模式
在datasheet里有写到pwm的setting operation..
1. Set the PWM period by writing to the PR2 register.
2. Set the PWM duty cycle by writing to the
CCPR1L register and CCP1CON<5:4> bits.
3. Make the CCP1 pin an output by clearing the
TRISC<2> bit.
4. Set the TMR2 prescale value and enable Timer2
by writing to T2CON.
5. Configure the CCP1 module for PWM operation.
我要怎么样settingPR2?
p/s-小弟我用的是pic16f877a, hitech-c, MPLAB
回复

使用道具 举报


ADVERTISEMENT

发表于 29-8-2009 05:32 PM | 显示全部楼层
原帖由 abue 于 28-8-2009 09:50 PM 发表
在datasheet里有写到pwm的setting operation..
1. Set the PWM period by writing to the PR2 register.
2. Set the PWM duty cycle by writing to the
CCPR1L register and CCP1CON bits.
3. Make the CCP1 pin

我要怎么样settingPR2? ...


不太明白你的意思。。因为太简单了,你只需要直接设一个值到 PR2 就行啦!
比如 PR2 = 0x7F;
回复

使用道具 举报

 楼主| 发表于 30-8-2009 01:19 PM | 显示全部楼层
PP2的值代表着什么的值呢?
回复

使用道具 举报

发表于 30-8-2009 05:32 PM | 显示全部楼层
原帖由 abue 于 28-8-2009 09:50 PM 发表
在datasheet里有写到pwm的setting operation..
1. Set the PWM period by writing to the PR2 register.
2. Set the PWM duty cycle by writing to the
CCPR1L register and CCP1CON bits.
3. Make the CCP1 pin ...

你的源码呢?

请问
1. 你的crystal 是多少Mhz?
2. 你要什么频率的PWM?
3. 你要多少% Duty Cycle ?
回复

使用道具 举报

 楼主| 发表于 30-8-2009 11:32 PM | 显示全部楼层
我用的是4mhz的crytal..
我主要是要来控制servo motor...
回复

使用道具 举报

 楼主| 发表于 30-8-2009 11:36 PM | 显示全部楼层
我没玩过servo motor所以这次想用来控制它。。
我买的servo motor它上面有写0.12s/60度
回复

使用道具 举报

Follow Us
发表于 31-8-2009 11:19 AM | 显示全部楼层
原帖由 abue 于 30-8-2009 11:36 PM 发表
我没玩过servo motor所以这次想用来控制它。。
我买的servo motor它上面有写0.12s/60度


搜索: PWM
http://cforum3.cari.com.my/search.php?searchid=1208355&orderby=lastpost&ascdesc=desc&searchsubmit=yes

用心爬一下, 然后再回来问。
回复

使用道具 举报

 楼主| 发表于 31-8-2009 03:59 PM | 显示全部楼层
差不多爬完大大给我的贴。。
以下是我所了解的。。
1。servo motor的动作范围是0.9~2.1/20ms,所以duty cycle=0.9/20ms=4.5%
                                                                                             =2.1/20ms=10.5%
2。看了pic斑竹以前做DMX灯光控制时而做的ccs程序后,感觉和hitech的写法有一点不同(小弟我是用hitech,c18的话在fritzlizt大大的教学学了一点点罢了)
3。自己上网找了些资料,凭感觉来写了pwm的初始化程序。。
根据datasheet....
void CCP1INIT()
{
     PR2 = [(PR2) + 1] &#8226; 4 &#8226; TOSC &#8226;(TMR2 Prescale Value);
     CCPR1L = Duty Cycle;
     CCP1CON = 0x3C;(设置CCP1模块为PWM工作方式)
     TRISC=0XFB;(设置CCP1引脚为输出方式)
     T2CON = TMR2 prescale value;
}
TOSC代表着什么意思?TMR2 prescale value又是什么意思?
看来我的路还很长。。。
回复

使用道具 举报


ADVERTISEMENT

发表于 2-9-2009 09:19 AM | 显示全部楼层
原帖由 abue 于 31-8-2009 03:59 PM 发表
差不多爬完大大给我的贴。。
以下是我所了解的。。
1。servo motor的动作范围是0.9~2.1/20ms,所以duty cycle=0.9/20ms=4.5%...

怎么你用Hitech -C 好像写ASM 那样?我没有用过, 但是应该有Library吧, 去找找看。。

下面给你参考, 不过是CCS C, 是用CCS C 的PIC Wizard 来create的。
基本上, 我没有理什么   PR2, CCPR1L, CCP1CON ,   T2CON
这些是Compiler 的工, 买compiler 就是要电脑做工。

  1. // 2 Sep 2009
  2. // By Pic @Cari
  3. // Generate PWM 500Hz,
  4. // Compiler : CCS C
  5. #include <16F877A.h>
  6. #FUSES NOWDT, XT, PUT, NOPROTECT, BROWNOUT, NOLVP
  7. #use delay(clock=4000000)

  8. void main()
  9. {
  10.    setup_timer_2(T2_DIV_BY_16,124,1); // PWM Freq :500Hz
  11.    setup_ccp1(CCP_PWM); // Enable PWM

  12.    while(1)
  13.    {
  14.       // Demo with different Duty cycle  1-1023
  15.       // Pls select the PWM duty cycle you want
  16.       set_pwm1_duty(102); // 10%
  17.       delay_ms(1000);
  18.       set_pwm1_duty(256); // 25%
  19.       delay_ms(1000);
  20.       set_pwm1_duty(512); // 50%
  21.       delay_ms(1000);
  22.       set_pwm1_duty(767); // 75%
  23.       delay_ms(1000);
  24.       set_pwm1_duty(1023); // 100%
  25.       delay_ms(1000);
  26.    }
  27. }
复制代码



下面是ASM 的code, 只是看看就好。。。
  1.                ROM used: 116 words (1%)
  2.                          Largest free fragment is 2048
  3.                RAM used: 8 (2%) at main() level
  4.                          9 (2%) worst case
  5.                Stack:    1 locations

  6. *
  7. 0000:  MOVLW  00
  8. 0001:  MOVWF  0A
  9. 0002:  GOTO   019
  10. 0003:  NOP
  11. ....................  
  12. .................... // 2 Sep 2009
  13. .................... // By Pic @Cari
  14. .................... // Generate PWM 500Hz,  
  15. .................... #include <16F877A.h>
  16. .................... //////// Standard Header file for the PIC16F877A device ////////////////
  17. .................... #device PIC16F877A
  18. .................... #list
  19. ....................  
  20. .................... #FUSES NOWDT, RC, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
  21. .................... #use delay(clock=4000000)
  22. *
  23. 0004:  MOVLW  22
  24. 0005:  MOVWF  04
  25. 0006:  BCF    03.7
  26. 0007:  MOVF   00,W
  27. 0008:  BTFSC  03.2
  28. 0009:  GOTO   018
  29. 000A:  MOVLW  01
  30. 000B:  MOVWF  78
  31. 000C:  CLRF   77
  32. 000D:  DECFSZ 77,F
  33. 000E:  GOTO   00D
  34. 000F:  DECFSZ 78,F
  35. 0010:  GOTO   00C
  36. 0011:  MOVLW  4A
  37. 0012:  MOVWF  77
  38. 0013:  DECFSZ 77,F
  39. 0014:  GOTO   013
  40. 0015:  GOTO   016
  41. 0016:  DECFSZ 00,F
  42. 0017:  GOTO   00A
  43. 0018:  RETLW  00
  44. ....................  
  45. .................... void main()
  46. .................... {
  47. 0019:  CLRF   04
  48. 001A:  BCF    03.7
  49. 001B:  MOVLW  1F
  50. 001C:  ANDWF  03,F
  51. 001D:  BSF    03.5
  52. 001E:  BSF    1F.0
  53. 001F:  BSF    1F.1
  54. 0020:  BSF    1F.2
  55. 0021:  BCF    1F.3
  56. 0022:  MOVLW  07
  57. 0023:  MOVWF  1C
  58. ....................   
  59. ....................    setup_timer_2(T2_DIV_BY_16,124,1); // PWM Freq :500Hz
  60. *
  61. 0027:  MOVLW  00
  62. 0028:  MOVWF  78
  63. 0029:  IORLW  06
  64. 002A:  MOVWF  12
  65. 002B:  MOVLW  7C
  66. 002C:  BSF    03.5
  67. 002D:  MOVWF  12
  68. ....................    setup_ccp1(CCP_PWM); // Enable PWM
  69. 002E:  BCF    03.5
  70. 002F:  BCF    20.2
  71. 0030:  MOVF   20,W
  72. 0031:  BSF    03.5
  73. 0032:  MOVWF  07
  74. 0033:  BCF    03.5
  75. 0034:  BCF    07.2
  76. 0035:  MOVLW  0C
  77. 0036:  MOVWF  17
  78. ....................  
  79. ....................    while(1)
  80. ....................    {
  81. ....................     
  82. ....................       // Demo with different Duty cycle  1-1023
  83. ....................       // Pls select the PWM duty cycle you want
  84. ....................       set_pwm1_duty(102); // 10%
  85. 0037:  MOVLW  66
  86. 0038:  MOVWF  15
  87. ....................       delay_ms(1000);
  88. 0039:  MOVLW  04
  89. 003A:  MOVWF  21
  90. 003B:  MOVLW  FA
  91. 003C:  MOVWF  22
  92. 003D:  CALL   004
  93. 003E:  DECFSZ 21,F
  94. 003F:  GOTO   03B
  95. ....................       set_pwm1_duty(256); // 25%
  96. 0040:  MOVLW  40
  97. 0041:  MOVWF  15
  98. 0042:  MOVF   17,W
  99. 0043:  ANDLW  CF
  100. 0044:  MOVWF  17
  101. ....................       delay_ms(1000);
  102. 0045:  MOVLW  04
  103. 0046:  MOVWF  21
  104. 0047:  MOVLW  FA
  105. 0048:  MOVWF  22
  106. 0049:  CALL   004
  107. 004A:  DECFSZ 21,F
  108. 004B:  GOTO   047
  109. ....................       set_pwm1_duty(512); // 50%
  110. 004C:  MOVLW  80
  111. 004D:  MOVWF  15
  112. 004E:  MOVF   17,W
  113. 004F:  ANDLW  CF
  114. 0050:  MOVWF  17
  115. ....................       delay_ms(1000);
  116. 0051:  MOVLW  04
  117. 0052:  MOVWF  21
  118. 0053:  MOVLW  FA
  119. 0054:  MOVWF  22
  120. 0055:  CALL   004
  121. 0056:  DECFSZ 21,F
  122. 0057:  GOTO   053
  123. ....................       set_pwm1_duty(767); // 75%
  124. 0058:  MOVLW  BF
  125. 0059:  MOVWF  15
  126. 005A:  MOVF   17,W
  127. 005B:  ANDLW  CF
  128. 005C:  IORLW  30
  129. 005D:  MOVWF  17
  130. ....................       delay_ms(1000);
  131. 005E:  MOVLW  04
  132. 005F:  MOVWF  21
  133. 0060:  MOVLW  FA
  134. 0061:  MOVWF  22
  135. 0062:  CALL   004
  136. 0063:  DECFSZ 21,F
  137. 0064:  GOTO   060
  138. ....................       set_pwm1_duty(1023); // 100%
  139. 0065:  MOVLW  FF
  140. 0066:  MOVWF  15
  141. 0067:  MOVF   17,W
  142. 0068:  ANDLW  CF
  143. 0069:  IORLW  30
  144. 006A:  MOVWF  17
  145. ....................       delay_ms(1000);
  146. 006B:  MOVLW  04
  147. 006C:  MOVWF  21
  148. 006D:  MOVLW  FA
  149. 006E:  MOVWF  22
  150. 006F:  CALL   004
  151. 0070:  DECFSZ 21,F
  152. 0071:  GOTO   06D
  153. ....................    }
  154. 0072:  GOTO   037
  155. ....................  
  156. .................... }
  157. 0073:  SLEEP

  158. Configuration Fuses:
  159.    Word  1: 3F3B   RC NOWDT NOPUT NODEBUG NOPROTECT NOBROWNOUT NOLVP NOCPD NOWRT
复制代码

[ 本帖最后由 pic 于 2-9-2009 09:30 AM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2-9-2009 12:27 PM | 显示全部楼层
ccs真好,真方便。。
我写hitech很想asm哦-_-''
没学过asm...
不知道hitech会不会有这些function...
总之谢谢pic大大
回复

使用道具 举报

发表于 3-9-2009 11:11 AM | 显示全部楼层
原帖由 pic 于 2-9-2009 09:19 AM 发表

怎么你用Hitech -C 好像写ASM 那样?我没有用过, 但是应该有Library吧, 去找找看。。

下面给你参考, 不过是CCS C, 是用CCS C 的PIC Wizard 来create的。
基本上, 我没有理什么   PR2, CCPR1L, CCP1CON ,  T2CON  ...


这就是 CCS 与 Hitech -C 的差别了,使用 Hitech -C 必须要自己去定义每个寄存器。就如我在 http://cforum4.cari.com.my/viewthread.php?tid=1093025&extra=page%3D1&page=2  第 30 楼说的。

因此选用 CCS 编写是不能将代码直接移植到不同的单片计算机上运行的。因为它没有遵循标准 C 规则。

这里我附上一个 PWM 例子供参考。

/*  该初始化子程序设置CCP1 模块输出分辨率为10 位的PWM 波形,且占空比为50%。*/
#include <pic.h>

void CCP1INIT()
{
    CCPR1L=0X7F;
    CCP1CON=0X3C; /*设置CCP1 模块为PWM 工作方式,且其工作
                                           *循环的低2 位为11,高8 位为01111111=7F*/
    INTCON=0X00; /*禁止总中断和外围中断*/
    PR2=0XFF; /*设置PWM 的工作周期*/
    TRISC=0XFB; /*设置CCP1 引脚为输出方式*/
}

/*主程序*/
main()
{
    CCP1INIT(); /*CCP1模块的PWM 工作方式初始化*/
    T2CON=0X04; /*打开TMR2,且使其前分频为0,
                                    *同时开始输出PWM 波形*/
    do
    {
            ;
    } while(1); /* 系统开始输出PWM 波形。如果系统是
                          * 多任务的,则可以在此执行其它任务,而
                          * 不会影响PWM 波形的产生*/
}
回复

使用道具 举报

 楼主| 发表于 3-9-2009 04:49 PM | 显示全部楼层
rothmans大大和我找到的范例一样
可是我不明白的是:
CCPR1L=0X7F;且其工作循环的低2 位为11,高8 位为01111111=7F
这是什么意思?PR1有10bit,解释说低二位为11,可是0x7f代表的是高8位不是吗? 不明白。。
还有就是T2CON=0X04; /*打开TMR2,且使其前分频为0,
                                    *同时开始输出PWM 波形*/
这是为什么呢?

请各位老师指点迷津。。。。m(-_-)m
回复

使用道具 举报

发表于 10-3-2010 01:00 PM | 显示全部楼层
#include <16F877A.h>

#FUSES NOWDT, XT, PUT, NOPROTECT, BROWNOUT, NOLVP

#use delay(clock=4000000)


void main()

{

setup_timer_2(T2_DIV_BY_16,124,1); // PWM Freq :500Hz
setup_ccp1(CCP_PWM); // Enable PWM

  while(1)

{  
// Demo with different Duty cycle  1-1023

// Pls select the PWM duty cycle you want

      set_pwm1_duty(102); // 10%
      delay_ms(1000);

      set_pwm1_duty(256); // 25%

      delay_ms(1000);

      set_pwm1_duty(512); // 50%

      delay_ms(1000);
      set_pwm1_duty(767); // 75%

      delay_ms(1000);

      set_pwm1_duty(1023); // 100%

      delay_ms(1000);

   }

}

pic版主,我正在学CCS,我想问,如果我这样写:

set_pwm1_duty(512); // 50%
delay_ms(1000);
output_high(PIN_C4);

然后用oscilloscope来量square wave signal。原理上是可以看到signal的,对吗?但为什么我只量到DC-5V。是我的code错了?
回复

使用道具 举报

发表于 10-3-2010 01:34 PM | 显示全部楼层
pic版主,我正在学CCS,我想问,如果我这样写:

set_pwm1_duty(512); // 50%
delay_ms(1000);
output_high(PIN_C4);

然后用oscilloscope来量square wave signal。原理上是可以看到signal的,对吗?但为什么我只量到DC-5V。是我的code错了?
东邪西毒 发表于 10-3-2010 01:00 PM


你量什么pin? 请量Pin17, RC2/CCP1
回复

使用道具 举报

发表于 10-3-2010 01:44 PM | 显示全部楼层
Oh,谢谢。我量RC4。但你如何知道是量RC2/CCP1?不量RC1/CCP2?
回复

使用道具 举报

发表于 10-3-2010 03:12 PM | 显示全部楼层
原来setup_ccp1(CCP_PWM)已经告诉我了,谢谢。
回复

使用道具 举报


ADVERTISEMENT

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 29-3-2024 08:14 AM , Processed in 0.071638 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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