PCA的PWM

网友投稿 1531 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

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

PCA的PWM

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】
相关文章