pwm.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * =====================================================================================
  3. *
  4. * ________ .__ __ ________ ____ ________
  5. * \_____ \ __ __|__| ____ | | __\______ \ _______ _/_ |/ _____/
  6. * / / \ \| | \ |/ ___\| |/ / | | \_/ __ \ \/ /| / __ \
  7. * / \_/. \ | / \ \___| < | ` \ ___/\ / | \ |__\ \
  8. * \_____\ \_/____/|__|\___ >__|_ \/_______ /\___ >\_/ |___|\_____ /
  9. * \__> \/ \/ \/ \/ \/
  10. *
  11. * www.optixx.org
  12. *
  13. *
  14. * Version: 1.0
  15. * Created: 07/21/2009 03:32:16 PM
  16. * Author: david@optixx.org
  17. *
  18. * =====================================================================================
  19. */
  20. #include <stdint.h>
  21. #include <string.h>
  22. #include <avr/io.h>
  23. #include <avr/interrupt.h>
  24. #include "pwm.h"
  25. #include "debug.h"
  26. #include "info.h"
  27. #include "sram.h"
  28. #define PWM_SINE_MAX 64
  29. #define PWM_OVERFLOW_MAX 1024
  30. uint8_t pwm_sine_table[] = {
  31. 0x7f, 0x8b, 0x97, 0xa4, 0xaf, 0xbb, 0xc5, 0xcf, 0xd9, 0xe1, 0xe8, 0xef,
  32. 0xf4, 0xf8, 0xfb, 0xfd,
  33. 0xfd, 0xfd, 0xfb, 0xf8, 0xf3, 0xee, 0xe7, 0xe0, 0xd7, 0xce, 0xc4, 0xb9,
  34. 0xae, 0xa2, 0x96, 0x89,
  35. 0x7e, 0x71, 0x65, 0x59, 0x4d, 0x42, 0x37, 0x2d, 0x24, 0x1c, 0x15, 0x0f,
  36. 0x09, 0x05, 0x03, 0x01,
  37. 0x01, 0x01, 0x03, 0x07, 0x0b, 0x11, 0x17, 0x1f, 0x28, 0x31, 0x3b, 0x46,
  38. 0x52, 0x5e, 0x6a, 0x76
  39. };
  40. volatile uint8_t pwm_setting;
  41. volatile uint16_t pwm_overflow;
  42. volatile uint8_t pwm_idx;
  43. volatile uint16_t pwm_overflow_max;
  44. ISR(TIMER2_COMPA_vect)
  45. {
  46. static uint8_t pwm_cnt = 0;
  47. OCR2A += (uint16_t) T_PWM;
  48. if (pwm_setting > pwm_cnt)
  49. led_pwm_on();
  50. else
  51. led_pwm_off();
  52. if (pwm_cnt == (uint8_t) (PWM_STEPS - 1))
  53. pwm_cnt = 0;
  54. else
  55. pwm_cnt++;
  56. if (pwm_overflow_max == pwm_overflow++) {
  57. pwm_setting = pwm_sine_table[pwm_idx++];
  58. pwm_overflow = 0;
  59. if (PWM_SINE_MAX == pwm_idx)
  60. pwm_idx = 0;
  61. }
  62. }
  63. void pwm_speed(uint16_t val)
  64. {
  65. pwm_overflow_max = val;
  66. }
  67. void pwm_speed_slow(uint16_t val)
  68. {
  69. pwm_overflow_max = PWM_OVERFLOW_MAX * 2;
  70. }
  71. void pwm_speed_fast(uint16_t val)
  72. {
  73. pwm_overflow_max = PWM_OVERFLOW_MAX / 2;
  74. }
  75. void pwm_speed_normal(uint16_t val)
  76. {
  77. pwm_overflow_max = PWM_OVERFLOW_MAX;
  78. }
  79. void pwm_set(uint8_t val)
  80. {
  81. pwm_setting = val;
  82. }
  83. void pwm_stop(void)
  84. {
  85. while (pwm_setting != 0xfd);
  86. TIMSK2 = 0;
  87. }
  88. void pwm_init(void)
  89. {
  90. pwm_overflow_max = PWM_OVERFLOW_MAX;
  91. pwm_setting = 0x7f;
  92. pwm_overflow = 0;
  93. // cli();
  94. TCCR2B = 1;
  95. TIMSK2 |= (1 << OCIE2A);
  96. sei();
  97. }