analogWrite() на любом выводе
- Войдите на сайт для отправки комментариев
Втр, 05/02/2013 - 06:37
Не раз уже поднималась тема о генерации ШИМа на любом из выводов или на всех выводах сразу. Написал простенькую библиотеку, которая позволяет Ардуино программно генерить 8-ми битный ШИМ на любом из выводов. Библиотека использует TIMER2, тестировалась только на Atmega48/88/168/328, то есть Uno, Duemilanove, Nano и т.п.
И так. Качаем архив, распаковываем его как обычно в ...\arduino-1.х\libraries\ , запускаем IDE, в примерах должна появиться вкладка PWM и в ней 3 примера.
Описание функций:
Пример:
#include <PWM.h> int brightness = 0; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by void setup() { // declare pin 13 to be an output: analog.Mode(13, OUTPUT); } void loop() { // set the brightness of pin 13: analog.Write(13, brightness); // change the brightness for next time through the loop: brightness = brightness + fadeAmount; // reverse the direction of the fading at the ends of the fade: if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } // wait for 30 milliseconds to see the dimming effect delay(30); }Видео
Понятненько. Интересная библиотечка.
Для леонардо и меги редактируем файл pins.h согласно пин-маппингу.
В итоге все пришло к тому, что как таковая библиотека не нужна.
Создайте в своем проекте новую вкладку с именем PWM:
и копируйте туда это содержимое:
#ifdef ALL #define PIN_0 #define PIN_1 #define PIN_2 #define PIN_3 #define PIN_4 #define PIN_5 #define PIN_6 #define PIN_7 #define PIN_8 #define PIN_9 #define PIN_10 #define PIN_11 #define PIN_12 #define PIN_13 #define PIN_14 #define PIN_15 #define PIN_16 #define PIN_17 #define PIN_18 #define PIN_19 #endif #define SBI(port, pin) asm volatile ("sbi %0, %1" :: "I" (_SFR_IO_ADDR(port)), "I" (pin)) #define CHECK(pwms, port, pin) \ asm volatile ( \ "cpc %0, %1 \n\t" \ "brlo 0f \n\t" \ "cbi %2, %3 \n\t" \ "rjmp 1f \n\t" \ "0: sbi %2, %3 \n\t" \ "1: nop \n\t" \ : "+r" (pwm), "+r" (pwms) \ : "I" (_SFR_IO_ADDR(port)), "I" (pin)\ )\ void Init_PWM() { cli(); TCCR2A = 0; TCCR2B = 3; //CLK OCR2A = 1; TIMSK2 = 2; //разрешаем прерывание по совпадению sei(); #ifdef PIN_0 SBI(DDRD, 0); #endif #ifdef PIN_1 SBI(DDRD, 1); #endif #ifdef PIN_2 SBI(DDRD, 2); #endif #ifdef PIN_3 SBI(DDRD, 3); #endif #ifdef PIN_4 SBI(DDRD, 4); #endif #ifdef PIN_5 SBI(DDRD, 5); #endif #ifdef PIN_6 SBI(DDRD, 6); #endif #ifdef PIN_7 SBI(DDRD, 7); #endif #ifdef PIN_8 SBI(DDRB, 0); #endif #ifdef PIN_9 SBI(DDRB, 1); #endif #ifdef PIN_10 SBI(DDRB, 2); #endif #ifdef PIN_11 SBI(DDRB, 3); #endif #ifdef PIN_12 SBI(DDRB, 4); #endif #ifdef PIN_13 SBI(DDRB, 5); #endif #ifdef PIN_14 SBI(DDRC, 0); #endif #ifdef PIN_15 SBI(DDRC, 1); #endif #ifdef PIN_16 SBI(DDRC, 2); #endif #ifdef PIN_17 SBI(DDRC, 3); #endif #ifdef PIN_18 SBI(DDRC, 4); #endif #ifdef PIN_19 SBI(DDRC, 5); #endif } volatile uint8_t pwm; volatile uint8_t pwms[20]; void analog_Frequence(byte prescaler) { TCCR2B = prescaler; //CLK } void analog_Write(byte pin, byte value) { pwms[pin] = value; } byte analog_State(byte pin) { return pwms[pin]; } ISR(TIMER2_COMPA_vect) { asm volatile ("clr %0" : "+r" (TCNT2)); // TCNT2 = 0; #ifdef PIN_0 CHECK(pwms[0], PORTD, 0); #endif #ifdef PIN_1 CHECK(pwms[1], PORTD, 1); #endif #ifdef PIN_2 CHECK(pwms[2], PORTD, 2); #endif #ifdef PIN_3 CHECK(pwms[3], PORTD, 3); #endif #ifdef PIN_4 CHECK(pwms[4], PORTD, 4); #endif #ifdef PIN_5 CHECK(pwms[5], PORTD, 5); #endif #ifdef PIN_6 CHECK(pwms[6], PORTD, 6); #endif #ifdef PIN_7 CHECK(pwms[7], PORTD, 7); #endif #ifdef PIN_8 CHECK(pwms[8], PORTB, 0); #endif #ifdef PIN_9 CHECK(pwms[9], PORTB, 1); #endif #ifdef PIN_10 CHECK(pwms[10], PORTB, 2); #endif #ifdef PIN_11 CHECK(pwms[11], PORTB, 3); #endif #ifdef PIN_12 CHECK(pwms[12], PORTB, 4); #endif #ifdef PIN_13 CHECK(pwms[13], PORTB, 5); #endif #ifdef PIN_14 CHECK(pwms[14], PORTC, 0); #endif #ifdef PIN_15 CHECK(pwms[15], PORTC, 1); #endif #ifdef PIN_16 CHECK(pwms[16], PORTC, 2); #endif #ifdef PIN_17 CHECK(pwms[17], PORTC, 3); #endif #ifdef PIN_18 CHECK(pwms[18], PORTC, 4); #endif #ifdef PIN_19 CHECK(pwms[19], PORTC, 5); #endif asm volatile ("inc %0" : "+r" (pwm)); //pwm++; }пример кода:
#define PIN_12 #define PIN_13 int brightness = 0; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by void setup() { Init_PWM(); analog_Frequence(2); // предделитель от 1 до 7 } void loop() { analog_Write(12, 255-brightness); analog_Write(13, brightness); brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 255) fadeAmount = -fadeAmount ; delay(50); }P.S. #define ALL задействует все 20 выводов дуины.
У меги и так шимов много. Для меги имеет смысл применять только на выходы больше 20.
С другой стороны, либа позволяет высвободить таймер1 для себя :)
На 8 меге гугаетсо
А так хочется ещё пару ножек с ШИМ"мом :(
Потому что на меге8 отсутстует таймер2.
Можно немного глупый вопрос, а первый можно задействовать?
Конечно можно. По аналогии можете сделать, только лучше делать сразу для конкретных выводов ,тогда работать будет быстрее.
Тоесть все что имеет в тексте TCCR2A, TCCR2B, OCR2A, TIMSK2, TCCR2B, TIMER2_COMPA_vect изменить на 1 или как?
Вот бы как в дуинки уно... тоесть как в меги 328 были все ноги что поддерживают ШИМ имели поддержку у меги 8-й.
Почти, только таймер1 16битный, а следовательно некоторые регистры состоят из младшего и старшего реистров.
Например на OCR1A компилятор ругнтся так как он 16-битный и состоит из OCR1AH и OCR1AL.
Понятно... что ничего непонятно...
Просто сменить 2-ки на 1-ки неполучилось.
Понятно... что ничего непонятно...
Просто сменить 2-ки на 1-ки неполучилось.
atmega88 - не?
Я пользуюсь ATmega8A-PU.
Я пользуюсь ATmega8A-PU.
Можно ведь постепенно переползать на более современные камни - по сравнению с мега8-й разницы не заметите, но присутсвуют плюшки аппаратной и программной совместимости с фирменными дуино.
Можно, но пока будут современные камни плыть из Китая перебиваться буду тем что есть.
Не плохо ! На меге мне удалось максимум задействовать 14 пинов! А реально их все задействовать под "ШИМ" имея в виду 54 пина? Тут в ...\PWM\PINS изменения сделал, надеясь хотя б 32 зажечь
для экперимента, без успешно! (( Или я не там прописал !??
Еще нужно файл PWM.cpp подправить:
#include "PWM.h" PWM::PWM() { cli(); TCCR2A = 0; //при совпадении уровень OC1A меняется на противоположный TCCR2B = 5; //CLK OCR2A = 1; TIMSK2 = 2; //разрешаем прерывание по совпадению sei(); } void PWM::Frequence(byte prescaler) { TCCR2B = prescaler; //CLK } volatile byte pwms[32]; ISR(TIMER2_COMPA_vect) { TCNT2 = 0; static byte pwm; pwms[0] > pwm ? HIGH_0 : LOW_0; pwms[1] > pwm ? HIGH_1 : LOW_1; pwms[2] > pwm ? HIGH_2 : LOW_2; pwms[3] > pwm ? HIGH_3 : LOW_3; pwms[4] > pwm ? HIGH_4 : LOW_4; pwms[5] > pwm ? HIGH_5 : LOW_5; pwms[6] > pwm ? HIGH_6 : LOW_6; pwms[7] > pwm ? HIGH_7 : LOW_7; pwms[8] > pwm ? HIGH_8 : LOW_8; pwms[9] > pwm ? HIGH_9 : LOW_9; pwms[10] > pwm ? HIGH_10 : LOW_10; pwms[11] > pwm ? HIGH_11 : LOW_11; pwms[12] > pwm ? HIGH_12 : LOW_12; pwms[13] > pwm ? HIGH_13 : LOW_13; pwms[14] > pwm ? HIGH_14 : LOW_14; pwms[15] > pwm ? HIGH_15 : LOW_15; pwms[16] > pwm ? HIGH_16 : LOW_16; pwms[17] > pwm ? HIGH_17 : LOW_17; pwms[18] > pwm ? HIGH_18 : LOW_18; pwms[19] > pwm ? HIGH_19 : LOW_19; pwms[20] > pwm ? HIGH_20 : LOW_20; pwms[21] > pwm ? HIGH_21 : LOW_21; pwms[22] > pwm ? HIGH_22 : LOW_22; pwms[23] > pwm ? HIGH_23 : LOW_23; pwms[24] > pwm ? HIGH_24 : LOW_24; pwms[25] > pwm ? HIGH_25 : LOW_25; pwms[26] > pwm ? HIGH_26 : LOW_26; pwms[27] > pwm ? HIGH_27 : LOW_27; pwms[28] > pwm ? HIGH_28 : LOW_28; pwms[29] > pwm ? HIGH_29 : LOW_29; pwms[30] > pwm ? HIGH_30 : LOW_30; pwms[31] > pwm ? HIGH_31 : LOW_31; pwm++; if(pwm == 255) pwm = 0; } void PWM::Mode(byte pin, bool en) { for(byte i = 0; i < 32; i++) { pinMode(i, en); } } void PWM::Write(byte pin, byte value) { pwms[pin] = value; } byte PWM::State(byte pin) { return pwms[pin]; } PWM analog = PWM();Если процессорного времени хватит, то можно и все 54 задействовать, если же нет то нужно разрядность ШИМа понижать.
Большое спасибо за быструю реакцию! Попробывал предварительно : сменил в PWM.cpp начинку на предложенную, дополнив сразу до 54 пинов! и в ...\PWM\PINS не забыл . И все тоже самое работают в ШИМе только PB4-PB7(10-13),PD0-PD3(18-21)! ( И ещё, если делаю в скетче доп.ю инициализацию в
void setup()
{pinMode(0, OUTPUT);pinMode(1, OUTPUT);........pinMode(54, OUTPUT);
analog.Mode(0, OUTPUT);analog.Mode(1, OUTPUT);..........analog.Mode(54, OUTPUT);}
то начинает работать и PC0-PC4,PD7(33-38)! ( Вроде правильно вычислил..) А остальные молчат !(( А хотелось бы научиться,надеюсь это возможно, на всех портах(пинах) МЕГИ... Может что ещё мы не сделали??
Выводы на выход в этом случае можно настраивать целыми портами:
попробуйте снизить частоту:
и уменьшить разрядность:
СПАСИБО Максим!
И так. Качаем архив, распаковываем его как обычно в ...\arduino-1.х\libraries\ , запускаем IDE, в примерах должна появиться вкладка PWM и в ней 3 примера.
Перезалейте пожалуйста архив.
Перезалейте пожалуйста архив, по Вашей сылке битый.
http://webfile.ru/7d24c4665bbe34036aad195a00b72bdc
Тоже хочу использовать составной 2-х монитор, но есть информация о 4-х или 6-х рамочном + контроллерном объединителе.
Какая у вас модель?
Спасибо.
а вот частоту следования шим, можно изменить, повысить до 3кгц?
Нет.
А какая частота программного ШИМа? На глаз мерцание не заметно, понятно что больше 24 герц.
Да фиг его знает какая, измерьте. А насчет не видно... я например и 3 кГц вижу - когда взгляд отводишь в сторону видны шлейфы.
Может чуть позже выложу данную либу с возможностью задавать выводы до компиляции кода (через директивы препроцессора), а управление выводами через asm-вставки будут организованы, что сэкономит "пару" тактов на обработку кажного вывода. В результате можно будет при небольшом количестве выводов значительно увеличить частоту.
Как обещал - новая версия либы. Старую удалить. Как таковая библиотека отсутствует, все находится в файле PWM.ino, который вложен в примеры.
Пример:
#define PIN_12 #define PIN_13 int brightness = 0; // how bright the LED is int fadeAmount = 5; // how many points to fade the LED by void setup() { Init_PWM(); analog_Frequence(2); // предделитель от 1 до 7 } void loop() { analog_Write(12, 255-brightness); analog_Write(13, brightness); brightness = brightness + fadeAmount; if (brightness == 0 || brightness == 255) fadeAmount = -fadeAmount ; delay(50); }PWM.ino:
#ifdef ALL #define PIN_0 #define PIN_1 #define PIN_2 #define PIN_3 #define PIN_4 #define PIN_5 #define PIN_6 #define PIN_7 #define PIN_8 #define PIN_9 #define PIN_10 #define PIN_11 #define PIN_12 #define PIN_13 #define PIN_14 #define PIN_15 #define PIN_16 #define PIN_17 #define PIN_18 #define PIN_19 #endif #define SBI(port, pin) asm volatile ("sbi %0, %1" :: "I" (_SFR_IO_ADDR(port)), "I" (pin)) #define CHECK(pwms, port, pin) \ asm volatile ( \ "cpc %0, %1 \n\t" \ "brlo 0f \n\t" \ "cbi %2, %3 \n\t" \ "rjmp 1f \n\t" \ "0: sbi %2, %3 \n\t" \ "1: nop \n\t" \ : "+r" (pwm), "+r" (pwms) \ : "I" (_SFR_IO_ADDR(port)), "I" (pin)\ )\ void Init_PWM() { cli(); TCCR2A = 0; TCCR2B = 3; //CLK OCR2A = 1; TIMSK2 = 2; //разрешаем прерывание по совпадению sei(); #ifdef PIN_0 SBI(DDRD, 0); #endif #ifdef PIN_1 SBI(DDRD, 1); #endif #ifdef PIN_2 SBI(DDRD, 2); #endif #ifdef PIN_3 SBI(DDRD, 3); #endif #ifdef PIN_4 SBI(DDRD, 4); #endif #ifdef PIN_5 SBI(DDRD, 5); #endif #ifdef PIN_6 SBI(DDRD, 6); #endif #ifdef PIN_7 SBI(DDRD, 7); #endif #ifdef PIN_8 SBI(DDRB, 0); #endif #ifdef PIN_9 SBI(DDRB, 1); #endif #ifdef PIN_10 SBI(DDRB, 2); #endif #ifdef PIN_11 SBI(DDRB, 3); #endif #ifdef PIN_12 SBI(DDRB, 4); #endif #ifdef PIN_13 SBI(DDRB, 5); #endif #ifdef PIN_14 SBI(DDRC, 0); #endif #ifdef PIN_15 SBI(DDRC, 1); #endif #ifdef PIN_16 SBI(DDRC, 2); #endif #ifdef PIN_17 SBI(DDRC, 3); #endif #ifdef PIN_18 SBI(DDRC, 4); #endif #ifdef PIN_19 SBI(DDRC, 5); #endif } volatile uint8_t pwm; volatile uint8_t pwms[20]; void analog_Frequence(byte prescaler) { TCCR2B = prescaler; //CLK } void analog_Write(byte pin, byte value) { pwms[pin] = value; } byte analog_State(byte pin) { return pwms[pin]; } ISR(TIMER2_COMPA_vect) { asm volatile ("clr %0" : "+r" (TCNT2)); // TCNT2 = 0; #ifdef PIN_0 CHECK(pwms[0], PORTD, 0); #endif #ifdef PIN_1 CHECK(pwms[1], PORTD, 1); #endif #ifdef PIN_2 CHECK(pwms[2], PORTD, 2); #endif #ifdef PIN_3 CHECK(pwms[3], PORTD, 3); #endif #ifdef PIN_4 CHECK(pwms[4], PORTD, 4); #endif #ifdef PIN_5 CHECK(pwms[5], PORTD, 5); #endif #ifdef PIN_6 CHECK(pwms[6], PORTD, 6); #endif #ifdef PIN_7 CHECK(pwms[7], PORTD, 7); #endif #ifdef PIN_8 CHECK(pwms[8], PORTB, 0); #endif #ifdef PIN_9 CHECK(pwms[9], PORTB, 1); #endif #ifdef PIN_10 CHECK(pwms[10], PORTB, 2); #endif #ifdef PIN_11 CHECK(pwms[11], PORTB, 3); #endif #ifdef PIN_12 CHECK(pwms[12], PORTB, 4); #endif #ifdef PIN_13 CHECK(pwms[13], PORTB, 5); #endif #ifdef PIN_14 CHECK(pwms[14], PORTC, 0); #endif #ifdef PIN_15 CHECK(pwms[15], PORTC, 1); #endif #ifdef PIN_16 CHECK(pwms[16], PORTC, 2); #endif #ifdef PIN_17 CHECK(pwms[17], PORTC, 3); #endif #ifdef PIN_18 CHECK(pwms[18], PORTC, 4); #endif #ifdef PIN_19 CHECK(pwms[19], PORTC, 5); #endif asm volatile ("inc %0" : "+r" (pwm)); //pwm++; }P.S. #define ALL задействует все 20 выводов дуины.
Спасибо :)
то есть выше 490гц нельзя? синусоиду с частотой 400гц на ноги вывести невозможно?
Почему 490? Как увеличить частоту аппаратного ШИМа читайте тут. Здесвь же программный ШИМ и частота зависит от предделителя и количества задействованых выводов.
4 вывода. один с опорнойй синусоидой а 3 - фазные смещенные относ друг друга на 120. как это грамотно описать?
У меня данная библиотека конфликтует IRRemote на UNO (обе используют TIMER2)
Можно ктото задействовал TIMER1 ?
Или проще IRremote перенастроить ?
Можно сделать как хотите. Как изменить эту любу обсуждалось, а в IRremote есть возможность поменять таймер.
Можно сделать как хотите. Как изменить эту любу обсуждалось, а в IRremote есть возможность поменять таймер.
Спасибо. Таймер поменял в IRremote. Все заработало с пол-пинка
Почему 490? Как увеличить частоту аппаратного ШИМа читайте тут. Здесвь же программный ШИМ и частота зависит от предделителя и количества задействованых выводов.
я о том, можно ли в analogwrite записывать чаще чем 490гц?
суть моей проблемы в том что в analogwrite пишутся значения из массива (256 значений описывающих один период синусоиды). генерируется несущая у которой должна быть частота 400гц на выходе. с частотой шима в 490 я никак не смогу записать 400*256=102400значений в секунду. какие есть варианты?
Не получилось скачать архив. Было интересно посмотреть что там.
Использую эту библиотеку на Arduino Nano. Подключены 1.8 inch TFT color display (HY-1.8 SPI), часы DS1302, датчик температуры и влажности DHT11, энкодер, кнопка и блютуз. На дисплей вывод время/температура, уровень яркости RGB светодиодов. Светодиоды подключены к аналоговым выходам ( analog.Mode(17, OUTPUT); // R и дальше...)
Все это работает, но при опросе датчика температуры (раз в минуту) светодиоды мигают.
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
DHT22 быстрее работать не будет, только точнее. Протокол у него тот же. Можно датчик пореже опрашивать. Но программный PWM все равно будет в это время тормозить. Лучше всего поменять датчик на i2C или аналоговый типа LM335. Тогда опрос будет быстрее.
При стоимости Arduino Pro Micro 3$ может дешевле отдельный контроллер на PWM поставить?
DHT22 быстрее работать не будет, только точнее. Протокол у него тот же. Можно датчик пореже опрашивать. Но программный PWM все равно будет в это время тормозить. Лучше всего поменять датчик на i2C или аналоговый типа LM335. Тогда опрос будет быстрее.
При стоимости Arduino Pro Micro 3$ может дешевле отдельный контроллер на PWM поставить?
Да, скорее всего, буду пробовать отдельный контроллер...
Использую эту библиотеку на Arduino Nano. Подключены 1.8 inch TFT color display (HY-1.8 SPI), часы DS1302, датчик температуры и влажности DHT11, энкодер, кнопка и блютуз. На дисплей вывод время/температура, уровень яркости RGB светодиодов. Светодиоды подключены к аналоговым выходам ( analog.Mode(17, OUTPUT); // R и дальше...)
Все это работает, но при опросе датчика температуры (раз в минуту) светодиоды мигают.
Я проверял, именно в этом месте светодиоды тухнут. Где-то было написано, что опрос происходит медленно, 250мс. Без подключения библиотеки PWM.h такого не происходит. А мне нехватает ШИМ выходов. Пробовал разные библиотеки DHT11, заработала только одна.
Подскажите, пожалуйста, как с этим бороться? Менять датчик на DHT22?
Спасибо, maksim! Я понял источник проблемы. Главное, что вся связка у меня работает. Теперь до ума доводить буду.
Поделитесь библиотекой плиииз с первого поста. а то файла больше нет.
Берите эту #30, той уже нет.
Берите эту #30, той уже нет.
Кстати на Leonardo не компилируется.
Потому что у ATmega32U4 отсутствует второй таймер, а единственный 8-ми битный таймер это TIMER0. В теории если замените двойки на нули должно завестись.
Есть готовый пульт на NANO. Свободны только пины 0 и 1. Можно ли на них генерить шим для управления драйвером шагового двигателя? С помощью библиотеки maksima вроде можно, но не будут ли какие то подводные камни.
Вот так код компилится под мегу 8-ю:
#ifdef ALL #define PIN_0 #define PIN_1 #define PIN_2 #define PIN_3 #define PIN_4 #define PIN_5 #define PIN_6 #define PIN_7 #define PIN_8 #define PIN_9 #define PIN_10 #define PIN_11 #define PIN_12 #define PIN_13 #define PIN_14 #define PIN_15 #define PIN_16 #define PIN_17 #define PIN_18 #define PIN_19 #endif #define SBI(port, pin) asm volatile ("sbi %0, %1 \n\t" :: "I" (_SFR_IO_ADDR(port)), "I" (pin)) #define CHECK(pwms, port, pin) \ asm volatile ( \ "cpc %0, %1 \n\t" \ "brlo 0f \n\t" \ "cbi %2, %3 \n\t" \ "rjmp 1f \n\t" \ "0: sbi %2, %3 \n\t" \ "1: nop \n\t" \ : "+r" (pwm), "+r" (pwms) \ : "I" (_SFR_IO_ADDR(port)), "I" (pin)\ )\ void Init_PWM() { cli(); TCCR1A = 0; TCCR1B = 3; //CLK OCR1A = 1; TIMSK = 2; //разрешаем прерывание по совпадению sei(); #ifdef PIN_0 SBI(DDRD, 0); #endif #ifdef PIN_1 SBI(DDRD, 1); #endif #ifdef PIN_2 SBI(DDRD, 2); #endif #ifdef PIN_3 SBI(DDRD, 3); #endif #ifdef PIN_4 SBI(DDRD, 4); #endif #ifdef PIN_5 SBI(DDRD, 5); #endif #ifdef PIN_6 SBI(DDRD, 6); #endif #ifdef PIN_7 SBI(DDRD, 7); #endif #ifdef PIN_8 SBI(DDRB, 0); #endif #ifdef PIN_9 SBI(DDRB, 1); #endif #ifdef PIN_10 SBI(DDRB, 2); #endif #ifdef PIN_11 SBI(DDRB, 3); #endif #ifdef PIN_12 SBI(DDRB, 4); #endif #ifdef PIN_13 SBI(DDRB, 5); #endif #ifdef PIN_14 SBI(DDRC, 0); #endif #ifdef PIN_15 SBI(DDRC, 1); #endif #ifdef PIN_16 SBI(DDRC, 2); #endif #ifdef PIN_17 SBI(DDRC, 3); #endif #ifdef PIN_18 SBI(DDRC, 4); #endif #ifdef PIN_19 SBI(DDRC, 5); #endif } volatile uint8_t pwm; volatile uint8_t pwms[20]; void analog_Frequence(byte prescaler) { TCCR1B = prescaler; //CLK } void analog_Write(byte pin, byte value) { pwms[pin] = value; } byte analog_State(byte pin) { return pwms[pin]; } ISR(TIMER1_COMPA_vect) { asm volatile ("clr %0" : "+r" (TCNT2)); // TCNT2 = 0; #ifdef PIN_0 CHECK(pwms[0], PORTD, 0); #endif #ifdef PIN_1 CHECK(pwms[1], PORTD, 1); #endif #ifdef PIN_2 CHECK(pwms[2], PORTD, 2); #endif #ifdef PIN_3 CHECK(pwms[3], PORTD, 3); #endif #ifdef PIN_4 CHECK(pwms[4], PORTD, 4); #endif #ifdef PIN_5 CHECK(pwms[5], PORTD, 5); #endif #ifdef PIN_6 CHECK(pwms[6], PORTD, 6); #endif #ifdef PIN_7 CHECK(pwms[7], PORTD, 7); #endif #ifdef PIN_8 CHECK(pwms[8], PORTB, 0); #endif #ifdef PIN_9 CHECK(pwms[9], PORTB, 1); #endif #ifdef PIN_10 CHECK(pwms[10], PORTB, 2); #endif #ifdef PIN_11 CHECK(pwms[11], PORTB, 3); #endif #ifdef PIN_12 CHECK(pwms[12], PORTB, 4); #endif #ifdef PIN_13 CHECK(pwms[13], PORTB, 5); #endif #ifdef PIN_14 CHECK(pwms[14], PORTC, 0); #endif #ifdef PIN_15 CHECK(pwms[15], PORTC, 1); #endif #ifdef PIN_16 CHECK(pwms[16], PORTC, 2); #endif #ifdef PIN_17 CHECK(pwms[17], PORTC, 3); #endif #ifdef PIN_18 CHECK(pwms[18], PORTC, 4); #endif #ifdef PIN_19 CHECK(pwms[19], PORTC, 5); #endif asm volatile ("inc %0 \n\t" : "+r" (pwm)); //pwm++; }Но ничего не происходит :(