PCA的PWM

网友投稿 1428 2022-05-30

#include "STC15W4K.H" // 包含STC15W4K寄存器定义文件 void main() { //占空比 = (1-CCAPnH/256)*100% //CCAPnH = (1 - 占空比)*256 // (1-0.875)*256 = 32 = 20H //对应频率为 = SYSclk/12/256 = 22118400/12/256 =7.2K CCAPM0=0x42; // 设置PCA模块为PWM输出方式。 CR=1; // PCA计数器开始运行 CCAP0H=0x20; // 脉宽控制 87.5% while(1); // 让程序停在这里。 }

1

2

3

4

5

6

7

8

9

10

11

12

13

注意:使用PWM功能,单片机IO口会自动切换到强推挽输出模式,所以我们不需要对IO口进行配置,但是要注意强推挽意味输出电流大,不能短路了!!!

上面例子为配置寄存器为系统脉冲的分频,下面演示利用定时器T0溢出作为输入脉冲,进行PWM输出

#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定义头文件 void initPCA() { // 初始化定时器T0为16位自动重装方式,其溢出脉冲作PCA计数器的时钟源 TMOD=0x00; // 设置T0为16位自动重装方式 TH0=0xff; // 定时时间19.53uS TL0=0xDC; TR0=1; // 启动定时器0 // 初始化PCA模块1为PWM输出方式 CMOD=0x84; // #10000100B ,选择T0为PCA计数器时钟源 CCAPM1=0x42; // 设置PCA模块1为8位PWM输出方式。脉冲在P1.0引脚输出,PWM无需中断支持。 CCAP1H=0x20; // 设置脉冲宽度 EA=1; // 开整个单片机所有中断共享的总中断控制位 CR=1; // 启动PCA计数器(CH,CL)计数 } void main (void) { initPCA(); while(1); // 这里可以编写其它程序 }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

使用T0计算定时器初值的方法总结:

所需PWM频率 = (1/定时时间)/256

定时时间 = 1/(256*所需PWM频率)

eg 所需200hz

1/(256*200) = 19.63125us

16位定时器12T的计算公式为

初值 = 65536 - SYSclk/12*T = 0xFFDC

下面是配置寄存器的渐变PWM输出

#include "STC15W4K.H" // 包含STC15W4K寄存器定义文件 #define pulse_width_MAX 0xfa // PWM脉宽最小值,占空比2.3% #define pulse_width_MIN 0x05 // PWM脉宽最大值,占空比98% #define STEP 0x02; // PWM脉宽变化步长 unsigned char pulse_width; // PWM脉宽变量,即存入CCAP0H中的值 void delay(void) { unsigned char i,j,k; for(i=10;i>0;i--) // 注意后面没分号 for(j=50;j>0;j--) // 注意后面没分号 for(k=255;k>0;k--); // 注意后面有分号 } void port_mode() // 端口模式 { P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00; P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00; } void initPWM() { CMOD=0x80; // #10000000B 空闲模式下停止PCA计数器工作 // 选择PCA时钟源为Fosc/12,禁止PCA计数器溢出时中断 CCON = 0; // 清零PCA计数器溢出中断请求标志位CF // CR = 0, 不允许 PCA 计数器计数,清零PCA 各模块中断请求标志位CCFn CL = 0; // 清零PCA 计数器 CH = 0; CCAPM0=0x42; // 设置PCA模块0为PWM输出方式。 CR=1; // PCA计数器开始运行 } void PWM_OUT() { // 占空比从最小到最大 pulse_width=pulse_width_MIN; while(1) { if (pulse_width>pulse_width_MAX) break; CCAP0H= pulse_width; pulse_width+=STEP; delay(); } // 占空比从最大到最小 pulse_width=pulse_width_MAX; while(1) { if (pulse_width

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

下面是调T0实现可变PWM输出的例子

#include "STC15W4K.H" // 包含 "STC15W4K.H"寄存器定义头文件 #define T0_1 246 // 定时器TO重装值(10个脉冲溢出) #define T0_2 236 // 定时器TO重装值(20个脉冲溢出) #define PWM_PluseWidth 255 // PWM脉冲宽度,数字越大,脉宽越窄,占空比越小 void delay20ms(void) { unsigned char i,j,k; for(i=2;i>0;i--) // 注意后面没分号 for(j=198;j>0;j--) // 注意后面没分号 for(k=150;k>0;k--); // 注意后面有分号 } void port_mode() // 端口模式 { P0M1=0x00; P0M0=0x00;P1M1=0x00; P1M0=0x00;P2M1=0x00; P2M0=0x00;P3M1=0x00; P3M0=0x00; P4M1=0x00; P4M0=0x00;P5M1=0x00; P5M0=0x00;P6M1=0x00; P6M0=0x00;P7M1=0x00; P7M0=0x00; } void initPCA() { // 初始化定时器T0为8位自动重装方式,其溢出脉冲作PCA计数器的时钟源 TMOD=0x02; // 设置T0为8位自动重装方式 TH0=T0_1; // 来256-246=10个脉冲就中断 TL0=T0_1; // 来256-246=10个脉冲就中断 TR0=1; // 启动定时器0 // 初始化PCA模块1为8位PWM输出方式 CMOD=0x84; // #10000100B 空闲模式下停止PCA计数器工作 // PCA时钟源选择T0溢出信号,禁止PCA计数器溢出时中断 CCON=0; // 清零PCA计数器溢出中断请求标志位CF // CR = 0, 不允许 PCA 计数器计数,清零PCA 各模块中断请求标志位CCFn CL=0; // 清零PCA 计数器 CH=0; CCAPM1=0x42; // 设置PCA模块1为8位PWM输出方式。脉冲在P1.0引脚输出,PWM无需中断支持。 PCA_PWM1=0; // 清0 PWM 模式下的第9位 CCAP1H=PWM_PluseWidth; // 设置脉冲宽度 EA=1; // 开整个单片机所有中断共享的总中断控制位 CR=1; // 启动PCA计数器(CH,CL)计数 } void main (void) { port_mode(); // 所有IO口设为准双向弱上拉方式。 initPCA(); while(1) // 等待中断 { // P1.0 输出高频PWM极窄脉冲 TH0=T0_1; // 来256-246=10个脉冲就中断 TL0=T0_1; // 来256-246=10个脉冲就中断 CCAP1H=PWM_PluseWidth; // 设置脉冲宽度 delay20ms(); // P1.0 输出低频PWM极窄脉冲 TH0=T0_2; // 来256-236=20个脉冲就中断 TL0=T0_2; // 来256-236=20个脉冲就中断 delay20ms(); // P1.0 输出高频PWM窄脉冲 TH0=T0_1; // 来256-246=10个脉冲就中断 TL0=T0_1; // 来256-246=10个脉冲就中断 CCAP1H=PWM_PluseWidth>>2; // 设置脉冲宽度 delay20ms(); // P1.0 输出低频PWM窄脉冲 TH0=T0_2; // 来256-236=20个脉冲就中断 TL0=T0_2; // 来256-236=20个脉冲就中断 delay20ms(); //P1.0 输出高频PWM宽脉冲 TH0=T0_1; // 来256-246=10个脉冲就中断 TL0=T0_1; // 来256-246=10个脉冲就中断 CCAP1H=PWM_PluseWidth>>4; delay20ms(); // P1.0 输出低频PWM宽脉冲 TH0=T0_2; // 来256-236=20个脉冲就中断 TL0=T0_2; // 来256-236=20个脉冲就中断 delay20ms(); } }

1

2

3

4

5

6

7

PCA的PWM

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

单片机 嵌入式

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:手撕环形队列系列二:无锁实现高并发
下一篇:使用计算着色器(Compute Shader)模拟粒子效果【OpenGL】【GLSL】
相关文章