Simple single-color 8x8x8 LED Cube with AVRs
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * cube.c
  3. *
  4. * Copyright 2011 Thomas Buck <xythobuz@me.com>
  5. * Copyright 2011 Max Nuding <max.nuding@gmail.com>
  6. * Copyright 2011 Felix Bäder <baeder.felix@gmail.com>
  7. *
  8. * This file is part of LED-Cube.
  9. *
  10. * LED-Cube is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * LED-Cube is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with LED-Cube. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. #include <avr/io.h>
  24. #include <avr/interrupt.h>
  25. #include <stdlib.h>
  26. #include "cube.h"
  27. #ifndef F_CPU
  28. #define F_CPU 16000000L
  29. #endif
  30. volatile uint8_t _isrCounter = 0;
  31. volatile uint8_t **imgBuffer = NULL; // imgBuffer[8][8]
  32. volatile uint8_t imgFlag = 0;
  33. // Wir zählen 21 mal bis 3968
  34. ISR(TIMER1_COMPA_vect) {
  35. if (_isrCounter < 20) {
  36. _isrCounter++;
  37. } else {
  38. _isrCounter = 0;
  39. isrCall();
  40. }
  41. }
  42. inline void setFet(uint8_t data) {
  43. data &= ~((1 << 1) | 1);
  44. PORTD = data;
  45. data &= ~(3);
  46. data = data << 3;
  47. PORTB |= data;
  48. }
  49. inline void selectLatch(uint8_t latchNr) {
  50. PORTC = 0;
  51. if (latchNr < 8) {
  52. PORTC = 1 << latchNr;
  53. }
  54. }
  55. inline void setLatch(uint8_t latchNr, uint8_t data) {
  56. setFet(0); // All LEDs off
  57. selectLatch(latchNr); // Activate current latch
  58. PORTA = data; // Put latch data
  59. delay_ns(LATCHDELAY); // Wait for latch
  60. selectLatch(8); // Deactivate all latches
  61. setFet(1 << latchNr); // Activate current plane
  62. }
  63. inline void isrCall(void) {
  64. static uint8_t layer = 0;
  65. uint8_t latchCtr = 0;
  66. for (; latchCtr < 8; latchCtr++) {
  67. setLatch(latchCtr, imgBuffer[layer][latchCtr]); // Put out all the data
  68. }
  69. // Select next layer
  70. if (layer < 7) {
  71. layer++;
  72. } else {
  73. layer = 0;
  74. }
  75. }
  76. inline void delay_ns(uint16_t ns) {
  77. // minimum 63 nanoseconds (= 1 tick)
  78. uint16_t i = ns;
  79. if (ns != 0) {
  80. if (ns < 63) {
  81. ns = 63;
  82. }
  83. for (; i > 0; i -= 63) {
  84. asm volatile("nop"::);
  85. }
  86. }
  87. }