矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 755|回复: 0

RP2040生成移相PWM

[复制链接]
     
发表于 2024-7-11 15:17:56 | 显示全部楼层 |阅读模式
本帖最后由 JuncoJet 于 2024-7-11 15:19 编辑

The Pico In MicroPython_ PWM.png

  1. The Pico In MicroPython: PWM
  2. Written by Harry Fairhead & Mike James          
  3. Monday, 26 July 2021
  4. Article Index
  5. The Pico In MicroPython: PWM
  6. Changing The Duty Cycle
  7. Duty Cycle Resolution
  8. Page 2 of 3
  9. Although you don’t need to know anything about the PWM hardware, there is one limitation you need to be aware of. Each PWM generator supports two outputs which work at the same frequency and optionally different duty cycles. For example, if you look back to the table of PWM pin assignments you can see that PWM 0 has outputs on GP16 and GP17. This means that these two pins can only work at the same frequency. For example:
  10. from machine import Pin, PWM
  11. pwm16 = PWM(Pin(16))
  12. pwm17 = PWM(Pin(17))
  13. pwm16.freq(250)
  14. pwm16.duty_u16(65535//2)
  15. pwm17.duty_u16(65535//4)
  16. produces a PWM signal on GP16 and GP17 with the same frequency of 250Hz and duty cycles of 50% and 25% respectively. If you change the frequency on either pin, both change frequency.
  17. You can see the result in this logic analyzer display:
  18. pwm2
  19. You can see from the logic analyzer trace that the pulses on each line start their duty cycle at exactly the same time. The PWM hardware can create phase-correct pulses where the pulses are aligned about their center point, but MicroPython doesn’t support this mode. However, it is fairly easy to write a function that sets or unsets phase-correct mode:
  20. def pwm_set_phase(sliceNo,phase):
  21.   Addr = 0x40050000 +0x14*sliceNo
  22.   if phase:
  23.      machine.mem32[Addr]=machine.mem32[Addr] | 0x2
  24.   else:
  25.      machine.mem32[Addr]=machine.mem32[Addr] & 0xFFFFFFFD
  26. Using this we can generate phase-correct pulses:
  27. pwm16 = PWM(Pin(16))
  28. pwm17 = PWM(Pin(17))
  29. pwm16.freq(250)
  30. pwm_set_phase(0,True)
  31. pwm16.duty_u16(65535//2)
  32. pwm17.duty_u16(65535//4)
  33. Now you can see that the pulses don’t start at the same time, but they are centered around the same time:
  34. pwm3
  35. As well as being able to set the level for each channel, you can also set the polarity. However, it is easy to write a function that will invert any channel:
  36. def pwm_set_polarity(sliceNo,channel,invert):
  37.     Addr = 0x40050000 +0x14*sliceNo
  38.     if invert:
  39.        machine.mem32[Addr]=machine.mem32[Addr] |
  40.                                      0x1 << (2+channel)
  41.     else:
  42.        machine.mem32[Addr]=machine.mem32[Addr] &
  43.                                     ~(0x1<<(2+channel))
  44. For example:
  45. pwm16 = PWM(Pin(16))
  46. pwm17 = PWM(Pin(17))
  47. pwm16.freq(250)
  48. pwm_set_polarity(0,1,True)
  49. pwm16.duty_u16(65535//4)
  50. pwm17.duty_u16(65535//4)
  51. pwm4
  52. and you can see that the output of channel B is inverted.
  53. Changing The Duty Cycle
  54. For reasons that will be discussed later, in most cases the whole point is to vary the duty cycle or the period of the pulse train. This means that the next question is, how fast can you change the characteristics of a PWM line? In other words, how fast can you change the duty cycle? There is no easy way to give an exact answer and, in most applications, an exact answer isn't of much value. The reason is that for a PWM signal to convey information it generally has to deliver a number of complete cycles with a given duty cycle. This is because of the way pulses are often averaged in applications.
  55. We also have another problem – synchronization. This is more subtle than it first seems. The hardware won't change the duty cycle until the current pulse is complete. You might think that the following program works to switch between two duty cycles on a per pulse basis:
  56. pwm16 = PWM(Pin(16))
  57. pwm16.freq(50)
  58. pwm16.duty_u16(65535//2)
  59. while True:
  60.     pwm16.duty_u16(65535//2)
  61.     pwm16.duty_u16(65535//4)
  62. but if you try this out the result isn’t what you might expect on a first analysis:
  63. pwm5
  64. You don’t get one 25% followed by one 50% pulse, but a varying number of each in turn. The reason is, of course, that the duty cycle is being set asynchronously.
  65. picoPython360
  66. << Prev - Next >>
  67. Last Updated ( Monday, 26 July 2021 )
复制代码
您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2025-4-26 09:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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