您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

131 行
3.2 KiB

  1. /*
  2. * softPwm.c:
  3. * Provide 2 channels of software driven PWM.
  4. * Copyright (c) 2012 Gordon Henderson
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://projects.drogon.net/raspberry-pi/wiringpi/
  8. *
  9. * wiringPi is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * wiringPi is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with wiringPi.
  21. * If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************
  23. */
  24. #include <stdio.h>
  25. #include <pthread.h>
  26. #include "wiringPi.h"
  27. #include "softPwm.h"
  28. #define MAX_PINS 1024
  29. // The PWM Frequency is derived from the "pulse time" below. Essentially,
  30. // the frequency is a function of the range and this pulse time.
  31. // The total period will be range * pulse time in uS, so a pulse time
  32. // of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS
  33. // which is a frequency of 100Hz.
  34. //
  35. // It's possible to get a higher frequency by lowering the pulse time,
  36. // however CPU uage will skyrocket as wiringPi uses a hard-loop to time
  37. // periods under 100uS - this is because the Linux timer calls are just
  38. // accurate at all, and have an overhead.
  39. //
  40. // Another way to increase the frequency is to reduce the range - however
  41. // that reduces the overall output accuracy...
  42. #define PULSE_TIME 100
  43. static int marks [MAX_PINS] ;
  44. static int range [MAX_PINS] ;
  45. int newPin = -1 ;
  46. /*
  47. * softPwmThread:
  48. * Thread to do the actual PWM output
  49. *********************************************************************************
  50. */
  51. static PI_THREAD (softPwmThread)
  52. {
  53. int pin, mark, space ;
  54. pin = newPin ;
  55. newPin = -1 ;
  56. piHiPri (50) ;
  57. for (;;)
  58. {
  59. mark = marks [pin] ;
  60. space = range [pin] - mark ;
  61. if (mark != 0)
  62. digitalWrite (pin, HIGH) ;
  63. delayMicroseconds (mark * 100) ;
  64. if (space != 0)
  65. digitalWrite (pin, LOW) ;
  66. delayMicroseconds (space * 100) ;
  67. }
  68. return NULL ;
  69. }
  70. /*
  71. * softPwmWrite:
  72. * Write a PWM value to the given pin
  73. *********************************************************************************
  74. */
  75. void softPwmWrite (int pin, int value)
  76. {
  77. pin &= (MAX_PINS - 1) ;
  78. /**/ if (value < 0)
  79. value = 0 ;
  80. else if (value > range [pin])
  81. value = range [pin] ;
  82. marks [pin] = value ;
  83. }
  84. /*
  85. * softPwmCreate:
  86. * Create a new PWM thread.
  87. *********************************************************************************
  88. */
  89. int softPwmCreate (int pin, int initialValue, int pwmRange)
  90. {
  91. int res ;
  92. pinMode (pin, OUTPUT) ;
  93. digitalWrite (pin, LOW) ;
  94. marks [pin] = initialValue ;
  95. range [pin] = pwmRange ;
  96. newPin = pin ;
  97. res = piThreadCreate (softPwmThread) ;
  98. while (newPin != -1)
  99. delay (1) ;
  100. return res ;
  101. }