OCR1A = OCR1B = sine_wave[n++];
убрать инкремент
OCR1A = OCR1B = sine_wave[n];
Ну хз, я в прерывании всегда тороплюсь
Проверил: на RETI с вашей правкой 66 тактов, без правки 156 тактов и код с правкой меньше на 32 байта…
Деление = ЗЛО !
ISR (TIMER1_OVF_vect) {
static uint8_t n (0);
OCR1AL = OCR1BL = sine_wave[n++];
if (n >= 125) n = 0;
}
Вот так выходит 55 тактов и код ещё меньше…
а говорили - отнимать и делить )))
Вариант с расчетом значений таблицы прямо в скетче:
uint8_t sine_wave[125];
void setup() {
for (uint8_t i=0; i<125;i++) sine_wave[i]=128 + 127.5 * sin(radians(720.0/125*i));
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TIMSK1 = 1 << TOIE1;
OCR1A = OCR1B = sine_wave[124];
TCNT1 = 0;
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM10);
TCCR1B = (1 << WGM12) | (1 << CS10); //Mode5 Fast PWM, 8-bit TOP 0xFF ; DIV 1
}
ISR (TIMER1_OVF_vect) {
static uint8_t n(0);
OCR1AL = OCR1BL = sine_wave[n++];
if (n >= 125) n = 0;
}
void loop() {
}
Ну и лаконичный вариант с расчетом значений при компиляции и без инициализации другой периферии (нет влияния от прерываний таймера, используемого для millis):
constexpr uint8_t s(uint8_t i) {
return 128 + 127.5 * sin(4 * PI / 125 * i);
}
const uint8_t PROGMEM sine_wave[125] = {
s(0), s(1), s(2), s(3), s(4), s(5), s(6), s(7), s(8), s(9),
s(10), s(11), s(12), s(13), s(14), s(15), s(16), s(17), s(18), s(19),
s(20), s(21), s(22), s(23), s(24), s(25), s(26), s(27), s(28), s(29),
s(30), s(31), s(32), s(33), s(34), s(35), s(36), s(37), s(38), s(39),
s(40), s(41), s(42), s(43), s(44), s(45), s(46), s(47), s(48), s(49),
s(50), s(51), s(52), s(53), s(54), s(55), s(56), s(57), s(58), s(59),
s(60), s(61), s(62), s(63), s(64), s(65), s(66), s(67), s(68), s(69),
s(70), s(71), s(72), s(73), s(74), s(75), s(76), s(77), s(78), s(79),
s(80), s(81), s(82), s(83), s(84), s(85), s(86), s(87), s(88), s(89),
s(90), s(91), s(92), s(93), s(94), s(95), s(96), s(97), s(98), s(99),
s(100), s(101), s(102), s(103), s(104), s(105), s(106), s(107), s(108), s(109),
s(110), s(111), s(112), s(113), s(114), s(115), s(116), s(117), s(118), s(119),
s(120), s(121), s(122), s(123), s(124)
};
int main() {
DDRB = 0B00000110;
TIMSK1 = 1 << TOIE1;
OCR1A = OCR1B = pgm_read_byte(sine_wave + 124);
TCNT1 = 0;
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM10);
TCCR1B = (1 << WGM12) | (1 << CS10); //Mode5 Fast PWM, 8-bit TOP 0xFF ; DIV 1
sei();
for (;;);
}
ISR (TIMER1_OVF_vect) {
static uint8_t n(0);
OCR1AL = OCR1BL = pgm_read_byte(sine_wave + n++);
if (n >= 125) n = 0;
}
ЕвгенийП А есть ли возможность заполнитьconst PROGMEM массив на этапе компиляции
более красивым способом ?
Я, конечно, не Евгений, но Ваш способ достаточно красив. Можно заполнить массив, вычисляя синусы. Чего можно от этого выиграть - большой вопрос. Да, и const тогда не получится. Увы.
Смотря, что Вы понимаете под “красивым способом”.
Лично я бы сделал, как у Вас.
Но, если бы я захотел потроллить читателя программы, я бы упёрся рогом в то, что 125 вызовов функции в инициализации - типа некрасиво, и сделал бы вместо них препроцессорный цикл. Это был бы говнокод, но троллинг знатный - пусть читатель разбирается
Выглядело бы это вот так:
#include "preprocloop.h"
constexpr uint8_t s(uint8_t i) { return 128 + 127.5 * sin(4 * PI / 125 * i); }
// макрос инициализации i-го элемента массива
#define ELEMENT_INIT(i) s(i)
#define totalSinValues 125
const uint8_t PROGMEM sine_wave[] = { init_array(totalSinValues) };
// ... далее по тексту ...
Попробуйте, если любопытно.
Файл preprocloop.h
#ifndef PREPROCLOOP_H
#define PREPROCLOOP_H
//
// Инициализация массивов циклом (рекурсией) препроцессора (GCC)
// В основном коде Необходимо доопределить макрос макрос инициализации одного элемента ELEMENT_INIT(i),
// который будет использоваться для иницализации i-го элемента массива.
// Например,
// #define ELEMENT_INIT(i) init_routine(i)
//
#define dec1_0 0
#define dec1_1 0
#define dec1_2 1
#define dec1_3 2
#define dec1_4 3
#define dec1_5 4
#define dec1_6 5
#define dec1_7 6
#define dec1_8 7
#define dec1_9 8
#define dec1_10 9
#define dec1_11 10
#define dec1_12 11
#define dec1_13 12
#define dec1_14 13
#define dec1_15 14
#define dec1_16 15
#define dec1_17 16
#define dec1_18 17
#define dec1_19 18
#define dec1_20 19
#define dec1_21 20
#define dec1_22 21
#define dec1_23 22
#define dec1_24 23
#define dec1_25 24
#define dec1_26 25
#define dec1_27 26
#define dec1_28 27
#define dec1_29 28
#define dec1_30 29
#define dec1_31 30
#define dec1_32 31
#define dec1_33 32
#define dec1_34 33
#define dec1_35 34
#define dec1_36 35
#define dec1_37 36
#define dec1_38 37
#define dec1_39 38
#define dec1_40 39
#define dec1_41 40
#define dec1_42 41
#define dec1_43 42
#define dec1_44 43
#define dec1_45 44
#define dec1_46 45
#define dec1_47 46
#define dec1_48 47
#define dec1_49 48
#define dec1_50 49
#define dec1_51 50
#define dec1_52 51
#define dec1_53 52
#define dec1_54 53
#define dec1_55 54
#define dec1_56 55
#define dec1_57 56
#define dec1_58 57
#define dec1_59 58
#define dec1_60 59
#define dec1_61 60
#define dec1_62 61
#define dec1_63 62
#define dec1_64 63
#define dec1_65 64
#define dec1_66 65
#define dec1_67 66
#define dec1_68 67
#define dec1_69 68
#define dec1_70 69
#define dec1_71 70
#define dec1_72 71
#define dec1_73 72
#define dec1_74 73
#define dec1_75 74
#define dec1_76 75
#define dec1_77 76
#define dec1_78 77
#define dec1_79 78
#define dec1_80 79
#define dec1_81 80
#define dec1_82 81
#define dec1_83 82
#define dec1_84 83
#define dec1_85 84
#define dec1_86 85
#define dec1_87 86
#define dec1_88 87
#define dec1_89 88
#define dec1_90 89
#define dec1_91 90
#define dec1_92 91
#define dec1_93 92
#define dec1_94 93
#define dec1_95 94
#define dec1_96 95
#define dec1_97 96
#define dec1_98 97
#define dec1_99 98
#define dec1_100 99
#define dec1_101 100
#define dec1_102 101
#define dec1_103 102
#define dec1_104 103
#define dec1_105 104
#define dec1_106 105
#define dec1_107 106
#define dec1_108 107
#define dec1_109 108
#define dec1_110 109
#define dec1_111 110
#define dec1_112 111
#define dec1_113 112
#define dec1_114 113
#define dec1_115 114
#define dec1_116 115
#define dec1_117 116
#define dec1_118 117
#define dec1_119 118
#define dec1_120 119
#define dec1_121 120
#define dec1_122 121
#define dec1_123 122
#define dec1_124 123
#define dec1_125 124
#define dec1_126 125
#define dec1_127 126
#define dec1_128 127
//
// Если нужно инициализировать большие массивы, то
// предыдущую последовательность надо продлить насколько нужно
///////////////////////////////////////////////////////////////
#define primitive_cat(a, ...) a ## __VA_ARGS__
#define iif(c) primitive_cat(iif_, c)
#define iif_0(t, ...) __VA_ARGS__
#define iif_1(t, ...) t
#define check_n(x, n, ...) n
#define check(...) check_n(__VA_ARGS__, 0,)
#define probe(x) x, 1,
#define empty()
#define defer(id) id empty()
#define obstruct(...) __VA_ARGS__ defer(empty)()
#define expand(...) __VA_ARGS__
#define dec1(x) primitive_cat(dec1_, x)
#define _not_(x) check(primitive_cat(not_, x))
#define not_0 probe(~)
#define _compl(b) primitive_cat(_compl_, b)
#define _compl_0 1
#define _compl_1 0
#define _bool_(x) _compl(_not_(x))
#define _if_(c) iif(_bool_(c))
#define eat(...)
#define expand(...) __VA_ARGS__
#define when(c) _if_(c)(expand, eat)
#define eval(...) eval1(eval1(eval1(__VA_ARGS__)))
#define eval1(...) eval2(eval2(eval2(__VA_ARGS__)))
#define eval2(...) eval3(eval3(eval3(__VA_ARGS__)))
#define eval3(...) eval4(eval4(eval4(__VA_ARGS__)))
#define eval4(...) eval5(eval5(eval5(__VA_ARGS__)))
#define eval5(...) __VA_ARGS__
#define repeat(count, macro, ...) when(count) (obstruct(repeat_indirect) () (dec1(count), macro, __VA_ARGS__) obstruct(macro) (dec1(count), __VA_ARGS__))
#define repeat_indirect() repeat
//
#define element_sub_init(i, _) ELEMENT_INIT(i),
#define init_array(n) eval(repeat(n, element_sub_init, ~))
#endif // PREPROCLOOP_H
Да уж … пошёл за ящиком водки … без неё не раскурить …
Под красивее я предполагал более короткую писанину …
Ну, тогда держите
Если не считать включаемого файла (он универсальный), то писанина сильно сократилась
и далее - это опечатка ?
Нет. Там 0, 0, 1, 2, 3 и т.д. - так и должно быть
Подозреваете, что опечатка, попробуйте исправить.
Кстати, Вы знаете, как смотреть, что там нагородил препроцессор? Без этого тут трудно разбираться.
Есть ключ -E или пара ключей -E -P для вывода кода до момента компиляции.