Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.55 KB | None | 0 0
  1. #ifndef __pwm_h__
  2. #define __pwm_h__
  3.  
  4. #include <avr/io.h>
  5. #include <avr/interrupt.h>
  6.  
  7. /*
  8. TCCRnA:
  9. 7-6 : Set comparison with OCnA
  10. 5-4 : Set comparison with OCnB
  11. 1-0:
  12.  
  13. PB7 - OC3B
  14. PB6 - OCR3A TCCR3B TCNT3 TCCR3A COM3A0 WGM32 CS31 CS30
  15.  
  16. PB4 - OC0B
  17. PB3 - OC0A
  18.  
  19. PD7 - OC2A
  20. PD6 - OC2B
  21.  
  22. PD5 - OC1A
  23. PD4 - OC1B
  24. */
  25.  
  26.  
  27. // 0.954 hz is lowest frequency possible with this function,
  28. // based on settings in PWM_on()
  29. // Passing in 0 as the frequency will stop the speaker from generating sound
  30. void set_PWM(unsigned char channel, double frequency) {
  31. static double current_frequency_0; // Keeps track of the currently set frequency
  32. static double current_frequency_1; // Keeps track of the currently set frequency
  33. static double current_frequency_2; // Keeps track of the currently set frequency
  34. static double current_frequency_3; // Keeps track of the currently set frequency
  35.  
  36. switch(channel)
  37. {
  38. case 0:
  39. if (frequency != current_frequency_0) // Only update registers when frequency changes
  40. {
  41. if (!frequency) { TCCR0B &= 0x08; } //stops timer/counter
  42. else { TCCR0B |= 0x03; } // resumes/continues timer/counter
  43.  
  44. // prevents OCR0A from overflowing, using prescaler 64
  45. // 0.954 is smallest frequency that will not result in overflow
  46. if (frequency < 0.954) { OCR0A = 0xFFFF; }
  47.  
  48. // prevents OCR0A from underflowing, using prescaler 64
  49. // 31250 is largest frequency that will not result in underflow
  50. else if (frequency > 31250) { OCR0A = 0x0000; }
  51.  
  52. // set OCR0A based on desired frequency
  53. else { OCR0A = (short)(8000000 / (128 * frequency)) - 1; }
  54.  
  55. TCNT0 = 0; // resets counter
  56. current_frequency_0 = frequency; // Updates the current frequency
  57. }
  58. break;
  59. case 1:
  60. if (frequency != current_frequency_1) // Only update registers when frequency changes
  61. {
  62. if (!frequency) { TCCR1B &= 0x08; } //stops timer/counter
  63. else { TCCR1B |= 0x03; } // resumes/continues timer/counter
  64.  
  65. // prevents OCR1A from overflowing, using prescaler 64
  66. // 0.954 is smallest frequency that will not result in overflow
  67. if (frequency < 0.954) { OCR1A = 0xFFFF; }
  68.  
  69. // prevents OCR1A from underflowing, using prescaler 64
  70. // 31250 is largest frequency that will not result in underflow
  71. else if (frequency > 31250) { OCR1A = 0x0000; }
  72.  
  73. // set OCR1A based on desired frequency
  74. else { OCR1A = (short)(8000000 / (128 * frequency)) - 1; }
  75.  
  76. TCNT1 = 0; // resets counter
  77. current_frequency_1 = frequency; // Updates the current frequency
  78. }
  79. break;
  80. case 2:
  81. if (frequency != current_frequency_2) // Only update registers when frequency changes
  82. {
  83. if (!frequency) { TCCR2B &= 0x08; } //stops timer/counter
  84. else { TCCR2B |= 0x03; } // resumes/continues timer/counter
  85.  
  86. // prevents OCR2A from overflowing, using prescaler 64
  87. // 0.954 is smallest frequency that will not result in overflow
  88. if (frequency < 0.954) { OCR2A = 0xFFFF; }
  89.  
  90. // prevents OCR2A from underflowing, using prescaler 64
  91. // 31250 is largest frequency that will not result in underflow
  92. else if (frequency > 31250) { OCR2A = 0x0000; }
  93.  
  94. // set OCR2A based on desired frequency
  95. else { OCR2A = (short)(8000000 / (128 * frequency)) - 1; }
  96.  
  97. TCNT2 = 0; // resets counter
  98. current_frequency_2 = frequency; // Updates the current frequency
  99. }
  100. break;
  101. case 3:
  102. if (frequency != current_frequency_3) // Only update registers when frequency changes
  103. {
  104. if (!frequency) { TCCR3B &= 0x08; } //stops timer/counter
  105. else { TCCR3B |= 0x03; } // resumes/continues timer/counter
  106.  
  107. // prevents OCR3A from overflowing, using prescaler 64
  108. // 0.954 is smallest frequency that will not result in overflow
  109. if (frequency < 0.954) { OCR3A = 0xFFFF; }
  110.  
  111. // prevents OCR3A from underflowing, using prescaler 64
  112. // 31250 is largest frequency that will not result in underflow
  113. else if (frequency > 31250) { OCR3A = 0x0000; }
  114.  
  115. // set OCR3A based on desired frequency
  116. else { OCR3A = (short)(8000000 / (128 * frequency)) - 1; }
  117.  
  118. TCNT3 = 0; // resets counter
  119. current_frequency_3 = frequency; // Updates the current frequency
  120. }
  121. break;
  122. default:
  123. break;
  124. }
  125. }
  126.  
  127. void PWM_on(unsigned char channel) {
  128. // COMnA0: Toggle channel to compare match between counter and OCRnA
  129. // WGMn2: When counter (TCNTn) matches OCRnA, reset counter
  130. // CSn1 & CSn0: Set a prescaler of 64
  131.  
  132. switch(channel)
  133. {
  134. case 0:
  135. TCCR0A = (1 << COM0A0);
  136. TCCR0B = (1 << WGM02) | (1 << CS01) | (1 << CS00);
  137. set_PWM(0,0);
  138. break;
  139. case 1:
  140. TCCR1A = (1 << COM1A0);
  141. TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10);
  142. set_PWM(1,0);
  143. break;
  144. case 2:
  145. TCCR2A = (1 << COM2A0);
  146. TCCR2B = (1 << WGM22) | (1 << CS21) | (1 << CS20);
  147. set_PWM(2,0);
  148. break;
  149. case 3:
  150. TCCR3A = (1 << COM3A0);
  151. TCCR3B = (1 << WGM32) | (1 << CS31) | (1 << CS30);
  152. set_PWM(3,0);
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158.  
  159. void PWM_off(unsigned char channel) {
  160. switch(channel)
  161. {
  162. case 0:
  163. TCCR0A = 0x00;
  164. TCCR0B = 0x00;
  165. break;
  166. case 1:
  167. TCCR1A = 0x00;
  168. TCCR1B = 0x00;
  169. break;
  170. case 2:
  171. TCCR2A = 0x00;
  172. TCCR2B = 0x00;
  173. break;
  174. case 3:
  175. TCCR3A = 0x00;
  176. TCCR3B = 0x00;
  177. break;
  178. default:
  179. break;
  180. }
  181. }
  182.  
  183. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement