Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 

188 rader
5.7 KiB

  1. // WiringPi test program: PWM test
  2. // Compile: gcc -Wall wiringpi_test8_pwm.c -o wiringpi_test8_pwm -lwiringPi
  3. #include "wpi_test.h"
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <unistd.h>
  7. #include <sys/time.h>
  8. #include <time.h>
  9. #include <stdint.h>
  10. int PWM_OUT[4] = { 18, 12, 13, 19 };
  11. int PWM_IN[4] = { 17, 13, 12, 26 };
  12. volatile int gCounter = 0;
  13. //Interrupt Service Routine for FREQIN
  14. void ISR_FREQIN(void) {
  15. gCounter++;
  16. }
  17. double MeasureAndCheckFreqTolerance(const char* msg, double expect_freq, int tolerance) {
  18. double fFrequency;
  19. clock_t CPUClockBegin, CPUClockEnd;
  20. int CountBegin, CountEnd;
  21. double CPUClockInterval, CountInterval;
  22. double elapsed_time, CPULoad;
  23. uint64_t tbegin, tend;
  24. int SleepMs = 1200;
  25. CPUClockBegin = clock();
  26. tbegin = piMicros64();
  27. CountBegin = gCounter;
  28. delay(SleepMs);
  29. CountEnd = gCounter;
  30. CPUClockEnd = clock();
  31. tend = piMicros64();
  32. elapsed_time = (double)(tend-tbegin)/1.0e6;
  33. CountInterval = CountEnd - CountBegin;
  34. CPUClockInterval = CPUClockEnd - CPUClockBegin;
  35. CPULoad = CPUClockInterval*100.0 / CLOCKS_PER_SEC / elapsed_time;
  36. fFrequency = CountInterval / elapsed_time / 1000;
  37. printf("\nInterval: time: %.6f sec (CPU: %3.1f %%), count: %g -> frequency: %.3f kHz\n",
  38. elapsed_time, CPULoad, CountInterval, fFrequency);
  39. CheckSameDouble("Wait for freq. meas.", elapsed_time, SleepMs/1000.0, 0.1); //100ms tolerance. maybe problematic on high freq/cpu load
  40. CheckSameDouble(msg, fFrequency, expect_freq, (expect_freq!=0.0) ? expect_freq*tolerance/100 : 0.1); //x% tolerance
  41. return fFrequency;
  42. }
  43. double MeasureAndCheckFreq(const char* msg, double expect_freq) {
  44. return MeasureAndCheckFreqTolerance(msg, expect_freq, 2);
  45. }
  46. int main (void) {
  47. int major, minor;
  48. int PWM, FREQIN;
  49. wiringPiVersion(&major, &minor);
  50. printf("WiringPi PWM GPIO test program 8\n");
  51. printf("PWM/ISR test (WiringPi %d.%d)\n", major, minor);
  52. wiringPiSetupGpio() ;
  53. int rev, mem, maker, overVolted, RaspberryPiModel;
  54. piBoardId(&RaspberryPiModel, &rev, &mem, &maker, &overVolted);
  55. CheckNotSame("Model: ", RaspberryPiModel, -1);
  56. PWM = 18;
  57. FREQIN = 17;
  58. printf("Register ISR@%d\n", PWM);
  59. // INT_EDGE_BOTH, INT_EDGE_FALLING, INT_EDGE_RISING only one ISR per input
  60. int result = wiringPiISR(FREQIN, INT_EDGE_RISING, &ISR_FREQIN);
  61. CheckSame("Register ISR", result, 0);
  62. if (result < 0) {
  63. printf("Unable to setup ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
  64. return UnitTestState();
  65. }
  66. printf("\n==> Set pwm 0%% and enable PWM output with PWM_OUTPUT (default mode)\n");
  67. pwmWrite(PWM, 0); // <-- Allways start with 0 Hz
  68. pinMode(PWM, PWM_OUTPUT); //Mode BAL, pwmr=1024, pwmc=32
  69. delay(250);
  70. double duty_fact = 0.0;
  71. double freq = 0.0;
  72. MeasureAndCheckFreq("PMW Pi0-4:BAL/Pi5:MS without change", freq);
  73. printf("Keep pwm 0%% and set mode MS\n");
  74. pwmSetMode(PWM_MODE_MS);
  75. delay(250);
  76. MeasureAndCheckFreq("PWM MS without change", freq);
  77. int pwmc;
  78. int pwmr;
  79. int pwm;
  80. if (RaspberryPiModel!=PI_MODEL_5) {
  81. pwmSetMode(PWM_MODE_BAL);
  82. pwmc = 1000;
  83. pwmr = 1024;
  84. pwm = 512;
  85. duty_fact = (double)pwm/(double)pwmr;
  86. printf("\n==> set mode BAL, pwmc=%d, pwmr=%d, pwm=%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
  87. pwmSetClock(pwmc);
  88. pwmSetRange(pwmr);
  89. pwmWrite(PWM, pwm);
  90. delay(250);
  91. freq = 19200.0/pwmc*duty_fact;
  92. MeasureAndCheckFreq("PWM BAL with settings", freq);
  93. }
  94. pwmSetMode(PWM_MODE_MS);
  95. pwmc = 10;
  96. pwmr = 256;
  97. pwm = 171;
  98. duty_fact = (double)pwm/(double)pwmr;
  99. printf("\n==> set mode MS, pwmc=%d, pwmr=%d, pwm=%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
  100. pwmSetClock(pwmc);
  101. pwmSetRange(pwmr);
  102. pwmWrite(PWM, pwm);
  103. delay(250);
  104. freq = 19200.0/(double)pwmc/(double)pwmr;
  105. MeasureAndCheckFreq("PWM BAL with settings", freq);
  106. printf("set PWM@GPIO%d (output) off\n", PWM);
  107. pinMode(PWM, PM_OFF);
  108. delay(1000);
  109. MeasureAndCheckFreq("PMW off", 0.0);
  110. if (RaspberryPiModel!=PI_MODEL_5) {
  111. pwmc = 800;
  112. pwmr = 2048;
  113. pwm = 768;
  114. duty_fact = (double)pwm/(double)pwmr;
  115. printf("\n==> set mode PWM_BAL_OUTPUT, pwmc=%d, pwmr=%d, pwm=%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
  116. pwmSetRange(pwmr);
  117. pwmSetClock(pwmc);
  118. pwmWrite(PWM, pwm);
  119. pinMode(PWM, PWM_BAL_OUTPUT);
  120. delay(250);
  121. freq = 19200.0/pwmc*duty_fact;
  122. MeasureAndCheckFreq("PMW BAL start values", freq);
  123. }
  124. printf("set PWM@GPIO%d (output) off\n", PWM);
  125. pinMode(PWM, PM_OFF);
  126. delay(1000);
  127. MeasureAndCheckFreq("PMW off", 0.0);
  128. printf("Set pwm settings and enable PWM\n");
  129. //pwmc = 5; //Problem with Pi0/1 after setting, PWM stops working, maybe IRQ problem or PWM BAL with that high freq (>2 MHz)
  130. pwmc = 35; //PWM BAL would be >400 kHz
  131. pwmr = 1024;
  132. pwm = 768;
  133. duty_fact = (double)pwm/(double)pwmr;
  134. printf("\n==> set mode PWM_MS_OUTPUT, pwmc=%d, pwmr=%d, pwm=%d, duty=%g%%\n", pwmc, pwmr, pwm, duty_fact*100);
  135. pwmSetRange(pwmr);
  136. pwmSetClock(pwmc);
  137. pwmWrite(PWM, pwm);
  138. pinMode(PWM, PWM_MS_OUTPUT);
  139. delay(250);
  140. freq = 19200.0/(double)pwmc/(double)pwmr;
  141. MeasureAndCheckFreq("PMW MS start values", freq);
  142. printf("set PWM@GPIO%d (output) off\n", PWM);
  143. pinMode(PWM, PM_OFF);
  144. delay(1000);
  145. MeasureAndCheckFreq("PMW off", 0.0);
  146. printf("set PWM0 CLK off @ Pi5\n");
  147. pwmSetClock(0);
  148. result = wiringPiISRStop(FREQIN);
  149. CheckSame("\n\nRelease ISR", result, 0);
  150. if (result < 0) {
  151. printf("Unable to release ISR for GPIO %d (%s)\n\n", FREQIN, strerror(errno));
  152. return UnitTestState();
  153. }
  154. return UnitTestState();
  155. }