Лампу как законченный обьект я конечно не сделал (пока по крайней мере)
Но тесты с цветом проводил, так что при желании можно было бы собрать все в кучу и подарить кому-нибудь; а так на макетке собрана такая схема:
Программа проста, как 5 копеек, но памяти забрала аж 3/4 (от 2-х килобайт тини2313); аппаратные шим-ы не используются, яркость управляется программно с помощью таймера, после включения на секунду включаются поочередно каждый цвет, а потом цвет меняется по кругу по известному правилу “Каждый охотник желает знать..”
Плавно вывести все цвета с использованием модели RGB так же непросто, как легко это сделать с помощью модели HSV, которая описывает цвет именно как цвет (в википедии написано больше); бОльшую часть прошивки у меня занимает таблица пред-рассчитанных значений для всего цветового круга, прошивка собственно выглядит так:
1: #include <avr/io.h>
2: #include <avr/interrupt.h>
3: #include <avr/pgmspace.h>
4: // в след. h-файле содержаться описания типов, типа u08 = uint_8
5: #include "avrlibtypes.h"
6: // в hardware.h описывается, что такое led_red_SHIFT – собственно
7: // в этом случае можно было бы не выпендриваться и вписать 3 цифры..
8: #include "hardware.h"
9: // готовый модуль из примеров в протеусе для задержек; в общем-то вообще неважно, как делать паузы..
10: #include "delay.h"
11:
12: // модуль delay.h старый и ищет F_OSC для расчета задержек
13: #define F_OSC F_CPU
14:
15: // собственно значения компонент цвета
16: volatile u08 r, g, b, counter;
17:
18: // init чуть менее чем полностью автогенеренный программкой AVR IO designer
19: void init(void)
20: {
21: //{{AVR_IO_DESIGNER_INIT
22: // Project Options - ambi-lamp
23: //
24: // Device Name = ATtiny2313
25: // CPU Frequency (F_CPU) = 3,68 MHz
26: // IC Package = DIP
27: // Sort Pins by = Pin Number
28: // Output Code File = ..\main.c
29: // Output Header File = ..\hardware.h
30: // Assume Default State = True
31: // Write Unmodified Bits = True
32: // Set Unused PORT Pins = Input
33:
34: //
35: // PORTD variable initializations
36: //
37: // PORTD3 for 1: led_red as Output -
38: // PORTD4 for 1: led_green as Output -
39: // PORTD5 for 1: led_blue as Output -
40: DDRD = 0x38;
41:
42: //
43: // TIMER_COUNTER_0 - -
44: //
45: // Clock Select = clk (No prescaling)
46: // Timer Overflow Interrupt Enable = Enabled
47: // Counter Frequency = 14,375 kHz
48: // Counter Period = 69,565 usec
49: // Seconds per Count = 271,739 nsec
50: // Counts per Second = 3,68 MHz
51: TIMSK = 0x02; // (1<<TOIE0)
52: TCCR0B = 0x01; // (0<<CS02)|(0<<CS01)|(1<<CS00)
53: //}}AVR_IO_DESIGNER_INIT
54:
55: sei();
56: }
57:
58: // собственно вот здесь яркость и управляется..
59: ISR(TIMER0_OVF_vect)
60: {
61: PORTD = ((r >; counter) << led_red_SHIFT) | ((g > counter) << led_green_SHIFT) | ((b > counter) << led_blue_SHIFT);
62: counter++;
63: }
64:
65: // значение hue (цветовой тон) меняется в пределах от 0 до 360, от красного соотв. до фиолетового
66: // в этом массиве – посчитанные в программке на делфи значения rgb для каждого значения hue
67: u08 pre_colors [3 * 360] PROGMEM = {
68: 255, 0, 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 17, 0,
69: 255, 21, 0, 255, 25, 0, 255, 29, 0, 255, 34, 0,
70: 255, 38, 0, 255, 42, 0, 255, 46, 0, 255, 51, 0, 255, 55, 0,
71: 255, 59, 0, 255, 63, 0, 255, 68, 0, 255, 72, 0,
72: 255, 76, 0, 255, 80, 0, 255, 85, 0, 255, 89, 0, 255, 93, 0,
73: 255, 97, 0, 255, 102, 0, 255, 106, 0, 255, 110, 0,
74: 255, 114, 0, 255, 119, 0, 255, 123, 0, 255, 127, 0,
75: 255, 131, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0,
76: 255, 148, 0, 255, 153, 0, 255, 157, 0, 255, 161, 0,
77: 255, 165, 0, 255, 170, 0, 255, 174, 0, 255, 178, 0,
78: 255, 182, 0, 255, 187, 0, 255, 191, 0, 255, 195, 0,
79: 255, 199, 0, 255, 204, 0, 255, 208, 0, 255, 212, 0,
80: 255, 216, 0, 255, 221, 0, 255, 225, 0, 255, 229, 0,
81: 255, 233, 0, 255, 238, 0, 255, 242, 0, 255, 246, 0,
82: 255, 250, 0, 255, 255, 0, 250, 255, 0, 246, 255, 0,
83: 242, 255, 0, 238, 255, 0, 233, 255, 0, 229, 255, 0,
84: 225, 255, 0, 221, 255, 0, 216, 255, 0, 212, 255, 0,
85: 208, 255, 0, 204, 255, 0, 199, 255, 0, 195, 255, 0, 191,
86: 255, 0, 187, 255, 0, 182, 255, 0, 178, 255, 0, 174,
87: 255, 0, 170, 255, 0, 165, 255, 0, 161, 255, 0, 157,
88: 255, 0, 153, 255, 0, 148, 255, 0, 144, 255, 0, 140,
89: 255, 0, 136, 255, 0, 131, 255, 0, 127, 255, 0, 123,
90: 255, 0, 119, 255, 0, 114, 255, 0, 110, 255, 0, 106,
91: 255, 0, 102, 255, 0, 97, 255, 0, 93, 255, 0, 89, 255, 0, 85,
92: 255, 0, 80, 255, 0, 76, 255, 0, 72, 255, 0, 68, 255,
93: 0, 63, 255, 0, 59, 255, 0, 55, 255, 0, 51, 255, 0, 46,
94: 255, 0, 42, 255, 0, 38, 255, 0, 34, 255, 0, 29, 255,
95: 0, 25, 255, 0, 21, 255, 0, 17, 255, 0, 12, 255, 0, 8,
96: 255, 0, 4, 255, 0, 0, 255, 0, 0, 255, 4, 0, 255, 8,
97: 0, 255, 12, 0, 255, 17, 0, 255, 21, 0, 255, 25, 0,
98: 255, 29, 0, 255, 34, 0, 255, 38, 0, 255, 42, 0, 255,
99: 46, 0, 255, 51, 0, 255, 55, 0, 255, 59, 0, 255, 63, 0,
100: 255, 68, 0, 255, 72, 0, 255, 76, 0, 255, 80, 0, 255,
101: 85, 0, 255, 89, 0, 255, 93, 0, 255, 97, 0, 255, 102, 0,
102: 255, 106, 0, 255, 110, 0, 255, 114, 0, 255, 119, 0,
103: 255, 123, 0, 255, 127, 0, 255, 131, 0, 255, 136, 0,
104: 255, 140, 0, 255, 144, 0, 255, 148, 0, 255, 153, 0,
105: 255, 157, 0, 255, 161, 0, 255, 165, 0, 255, 170, 0,
106: 255, 174, 0, 255, 178, 0, 255, 182, 0, 255, 187, 0,
107: 255, 191, 0, 255, 195, 0, 255, 199, 0, 255, 204, 0,
108: 255, 208, 0, 255, 212, 0, 255, 216, 0, 255, 221, 0,
109: 255, 225, 0, 255, 229, 0, 255, 233, 0, 255, 238, 0,
110: 255, 242, 0, 255, 246, 0, 255, 250, 0, 255, 255, 0,
111: 250, 255, 0, 246, 255, 0, 242, 255, 0, 238, 255, 0, 233,
112: 255, 0, 229, 255, 0, 225, 255, 0, 221, 255, 0, 216,
113: 255, 0, 212, 255, 0, 208, 255, 0, 204, 255, 0, 199,
114: 255, 0, 195, 255, 0, 191, 255, 0, 187, 255, 0, 182,
115: 255, 0, 178, 255, 0, 174, 255, 0, 170, 255, 0, 165,
116: 255, 0, 161, 255, 0, 157, 255, 0, 153, 255, 0, 148,
117: 255, 0, 144, 255, 0, 140, 255, 0, 136, 255, 0, 131,
118: 255, 0, 127, 255, 0, 123, 255, 0, 119, 255, 0, 114,
119: 255, 0, 110, 255, 0, 106, 255, 0, 102, 255, 0, 97,
120: 255, 0, 93, 255, 0, 89, 255, 0, 85, 255, 0, 80, 255,
121: 0, 76, 255, 0, 72, 255, 0, 68, 255, 0, 63, 255, 0, 59,
122: 255, 0, 55, 255, 0, 51, 255, 0, 46, 255, 0, 42, 255,
123: 0, 38, 255, 0, 34, 255, 0, 29, 255, 0, 25, 255, 0, 21,
124: 255, 0, 17, 255, 0, 12, 255, 0, 8, 255, 0, 4, 255, 0,
125: 0, 255, 4, 0, 255, 8, 0, 255, 12, 0, 255, 17, 0,
126: 255, 21, 0, 255, 25, 0, 255, 29, 0, 255, 34, 0, 255,
127: 38, 0, 255, 42, 0, 255, 46, 0, 255, 51, 0, 255, 55, 0,
128: 255, 59, 0, 255, 63, 0, 255, 68, 0, 255, 72, 0, 255,
129: 76, 0, 255, 80, 0, 255, 85, 0, 255, 89, 0, 255, 93, 0,
130: 255, 97, 0, 255, 102, 0, 255, 106, 0, 255, 110, 0,
131: 255, 114, 0, 255, 119, 0, 255, 123, 0, 255, 127, 0,
132: 255, 131, 0, 255, 136, 0, 255, 140, 0, 255, 144, 0,
133: 255, 148, 0, 255, 153, 0, 255, 157, 0, 255, 161, 0,
134: 255, 165, 0, 255, 170, 0, 255, 174, 0, 255, 178, 0,
135: 255, 182, 0, 255, 187, 0, 255, 191, 0, 255, 195, 0,
136: 255, 199, 0, 255, 204, 0, 255, 208, 0, 255, 212, 0,
137: 255, 216, 0, 255, 221, 0, 255, 225, 0, 255, 229, 0,
138: 255, 233, 0, 255, 238, 0, 255, 242, 0, 255, 246, 0,
139: 255, 250, 0, 255, 255, 0, 255, 255, 0, 250, 255, 0, 246,
140: 255, 0, 242, 255, 0, 238, 255, 0, 233, 255, 0, 229,
141: 255, 0, 225, 255, 0, 221, 255, 0, 216, 255, 0, 212,
142: 255, 0, 208, 255, 0, 204, 255, 0, 199, 255, 0, 195,
143: 255, 0, 191, 255, 0, 187, 255, 0, 182, 255, 0, 178,
144: 255, 0, 174, 255, 0, 170, 255, 0, 165, 255, 0, 161,
145: 255, 0, 157, 255, 0, 153, 255, 0, 148, 255, 0, 144,
146: 255, 0, 140, 255, 0, 136, 255, 0, 131, 255, 0, 127,
147: 255, 0, 123, 255, 0, 119, 255, 0, 114, 255, 0, 110,
148: 255, 0, 106, 255, 0, 102, 255, 0, 97, 255, 0, 93, 255,
149: 0, 89, 255, 0, 85, 255, 0, 80, 255, 0, 76, 255, 0, 72,
150: 255, 0, 68, 255, 0, 63, 255, 0, 59, 255, 0, 55, 255,
151: 0, 51, 255, 0, 46, 255, 0, 42, 255, 0, 38, 255, 0, 34,
152: 255, 0, 29, 255, 0, 25, 255, 0, 21, 255, 0, 17, 255,
153: 0, 12, 255, 0, 8, 255, 0, 4
154: };
155:
156: // ну и собственно “программа” – на секунду показываю чистые цвета, а потом
157: // бесконечно меняю цвет..
158: int main(void)
159: {
160: init();
161:
162: r = 255; g = b = 0;
163: delay_ms(1000);
164: r = 0; g = 255; b = 0;
165: delay_ms(1000);
166: r = g = 0; b = 255;
167: delay_ms(1000);
168:
169: int h = 0;
170:
171: while(1)
172: {
173: for (h = 0; h < 360; h++)
174: {
175: r = pgm_read_byte(&;pre_colors[h * 3]);
176: g = pgm_read_byte(&;pre_colors[h * 3 + 1]);
177: b = pgm_read_byte(&;pre_colors[h * 3 + 2]);
178:
179: delay_ms(10);
180: }
181: }
182:
183: return 0;
184: }
Почему так через ж***? Процедура, которую я написал для huv –> rgb на паскале, по непонятной пока причине глючит, если я пытаюсь ее написать на Си, поэтому махнул рукой и забил (учитывая, что каждое 3-е предупреждение компилятора мне по прежнему о том, что я путаю “=” и “==”, то неудивительно, что оно не работает.. но не очень то и хотелось просто на самом деле)
Хотя, учитывая, что для конвертации используется умножение/деление и т.д., размер не намного меньше получается – ну половина от всей памяти – можно и так оставить :)
Но зато если считать “на месте” – то яркость опять же легко меняется..
з.ы. естественно не отменяется самый простой способ получить плавный переход по всем цветам
1: int main(void)
2: {
3: init();
4:
5: r = 255; g = b = 0;
6:
7: #define delay_val 10
8:
9: while(1)
10: {
11: for (g = 0; g < 255; g++)
12: delay_ms(delay_val);
13: for (r = 255; r > 0; r--)
14: delay_ms(delay_val);
15: for (b = 0; b < 255; b++)
16: delay_ms(delay_val);
17: for (g = 255; g > 0; g--)
18: delay_ms(delay_val);
19: for (r = 0; r < 255; r++)
20: delay_ms(delay_val);
21: for (b = 255; b > 0; b--)
22: delay_ms(delay_val);
23: }
24:
25: return 0;
26: }
27:
получится те же к –> о –> ж –> з… и займет это всего 600 байт, но тогда сложнее сделать скажем “перейти от зеленого к красному”, если конечно вдруг такое приспичит :)
Комментариев нет:
Отправить комментарий