查看: 2636|回复: 15
|
关于pwm modules
[复制链接]
|
|
在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 |
|
|
|
|
|
|
|
发表于 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度 |
|
|
|
|
|
|
|
发表于 31-8-2009 11:19 AM
|
显示全部楼层
|
|
|
|
|
|
|
楼主 |
发表于 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] • 4 • TOSC •(TMR2 Prescale Value);
CCPR1L = Duty Cycle;
CCP1CON = 0x3C;(设置CCP1模块为PWM工作方式)
TRISC=0XFB;(设置CCP1引脚为输出方式)
T2CON = TMR2 prescale value;
}
TOSC代表着什么意思?TMR2 prescale value又是什么意思?
看来我的路还很长。。。 |
|
|
|
|
|
|
|
发表于 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 就是要电脑做工。
- // 2 Sep 2009
- // By Pic @Cari
- // Generate PWM 500Hz,
- // Compiler : CCS C
- #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);
- }
- }
复制代码
下面是ASM 的code, 只是看看就好。。。
- ROM used: 116 words (1%)
- Largest free fragment is 2048
- RAM used: 8 (2%) at main() level
- 9 (2%) worst case
- Stack: 1 locations
- *
- 0000: MOVLW 00
- 0001: MOVWF 0A
- 0002: GOTO 019
- 0003: NOP
- ....................
- .................... // 2 Sep 2009
- .................... // By Pic @Cari
- .................... // Generate PWM 500Hz,
- .................... #include <16F877A.h>
- .................... //////// Standard Header file for the PIC16F877A device ////////////////
- .................... #device PIC16F877A
- .................... #list
- ....................
- .................... #FUSES NOWDT, RC, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
- .................... #use delay(clock=4000000)
- *
- 0004: MOVLW 22
- 0005: MOVWF 04
- 0006: BCF 03.7
- 0007: MOVF 00,W
- 0008: BTFSC 03.2
- 0009: GOTO 018
- 000A: MOVLW 01
- 000B: MOVWF 78
- 000C: CLRF 77
- 000D: DECFSZ 77,F
- 000E: GOTO 00D
- 000F: DECFSZ 78,F
- 0010: GOTO 00C
- 0011: MOVLW 4A
- 0012: MOVWF 77
- 0013: DECFSZ 77,F
- 0014: GOTO 013
- 0015: GOTO 016
- 0016: DECFSZ 00,F
- 0017: GOTO 00A
- 0018: RETLW 00
- ....................
- .................... void main()
- .................... {
- 0019: CLRF 04
- 001A: BCF 03.7
- 001B: MOVLW 1F
- 001C: ANDWF 03,F
- 001D: BSF 03.5
- 001E: BSF 1F.0
- 001F: BSF 1F.1
- 0020: BSF 1F.2
- 0021: BCF 1F.3
- 0022: MOVLW 07
- 0023: MOVWF 1C
- ....................
- .................... setup_timer_2(T2_DIV_BY_16,124,1); // PWM Freq :500Hz
- *
- 0027: MOVLW 00
- 0028: MOVWF 78
- 0029: IORLW 06
- 002A: MOVWF 12
- 002B: MOVLW 7C
- 002C: BSF 03.5
- 002D: MOVWF 12
- .................... setup_ccp1(CCP_PWM); // Enable PWM
- 002E: BCF 03.5
- 002F: BCF 20.2
- 0030: MOVF 20,W
- 0031: BSF 03.5
- 0032: MOVWF 07
- 0033: BCF 03.5
- 0034: BCF 07.2
- 0035: MOVLW 0C
- 0036: MOVWF 17
- ....................
- .................... while(1)
- .................... {
- ....................
- .................... // Demo with different Duty cycle 1-1023
- .................... // Pls select the PWM duty cycle you want
- .................... set_pwm1_duty(102); // 10%
- 0037: MOVLW 66
- 0038: MOVWF 15
- .................... delay_ms(1000);
- 0039: MOVLW 04
- 003A: MOVWF 21
- 003B: MOVLW FA
- 003C: MOVWF 22
- 003D: CALL 004
- 003E: DECFSZ 21,F
- 003F: GOTO 03B
- .................... set_pwm1_duty(256); // 25%
- 0040: MOVLW 40
- 0041: MOVWF 15
- 0042: MOVF 17,W
- 0043: ANDLW CF
- 0044: MOVWF 17
- .................... delay_ms(1000);
- 0045: MOVLW 04
- 0046: MOVWF 21
- 0047: MOVLW FA
- 0048: MOVWF 22
- 0049: CALL 004
- 004A: DECFSZ 21,F
- 004B: GOTO 047
- .................... set_pwm1_duty(512); // 50%
- 004C: MOVLW 80
- 004D: MOVWF 15
- 004E: MOVF 17,W
- 004F: ANDLW CF
- 0050: MOVWF 17
- .................... delay_ms(1000);
- 0051: MOVLW 04
- 0052: MOVWF 21
- 0053: MOVLW FA
- 0054: MOVWF 22
- 0055: CALL 004
- 0056: DECFSZ 21,F
- 0057: GOTO 053
- .................... set_pwm1_duty(767); // 75%
- 0058: MOVLW BF
- 0059: MOVWF 15
- 005A: MOVF 17,W
- 005B: ANDLW CF
- 005C: IORLW 30
- 005D: MOVWF 17
- .................... delay_ms(1000);
- 005E: MOVLW 04
- 005F: MOVWF 21
- 0060: MOVLW FA
- 0061: MOVWF 22
- 0062: CALL 004
- 0063: DECFSZ 21,F
- 0064: GOTO 060
- .................... set_pwm1_duty(1023); // 100%
- 0065: MOVLW FF
- 0066: MOVWF 15
- 0067: MOVF 17,W
- 0068: ANDLW CF
- 0069: IORLW 30
- 006A: MOVWF 17
- .................... delay_ms(1000);
- 006B: MOVLW 04
- 006C: MOVWF 21
- 006D: MOVLW FA
- 006E: MOVWF 22
- 006F: CALL 004
- 0070: DECFSZ 21,F
- 0071: GOTO 06D
- .................... }
- 0072: GOTO 037
- ....................
- .................... }
- 0073: SLEEP
- Configuration Fuses:
- 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)已经告诉我了,谢谢。 |
|
|
|
|
|
|
| |
本周最热论坛帖子
|