Контакты

Восстановление конфигурации Fuse-битов микроконтроллеров Tiny AVR (HVSP). Схема приставки для восстановления FUSE-битов в AVR микроконтроллерах Подключение выводов микроконтроллеров в режиме высоковольтного последовательного программирования

Иногда случается что исправный, правильно подключенный микроконтроллер перестает определяться программой для прошивки. Это может происходить в следствии нескольких причин:

  1. Программирование через SPI запрещено
  2. Ножка RESET стала обычным пином порта
  3. Неправильно выбран источник тактирования

Если в первом и втором случае без параллельного программатора не обойтись, то при неправильном выбранном источнике тактирования, можно попробовать методы описанные в этом небольшом руководстве. Для этого нам потребуются:

  • Кварц ~4 МГц
  • Конденсаторы от 12 пФ до 22 пФ (2 шт)
  • Резистор 10 кОм
  • Микросхема 74HC00
  • Прямые руки:-)

Предположим, что мы не знаем какой источник тактирования у нас выбран. Существуют следующие источники тактирования:

  • Кварцевый резонатор
  • Внешняя RC цепочка
  • Внешней генератор

Есть еще внутренний RC генератор но по понятным причинам он нам не интересен. Для воскрешения контроллера нужно последовательно перебирать возможные варианты.

Кварцевый резонатор

Кварцевый резонатор подключается к ногам XTAL2 и XTAL1. Каждая нога кварца подсоединена к конденсатору который в свою очередь подключен на землю. Конденсаторы любые от 12 до 22 пф.

Если подключение кварца не помогло то пойдем дальше

Внешняя RC-цепочка

Использовать ее для тактирования я бы не стал, ибо частота будет плавать как сами знаете что в проруби. Подключается она к контроллеру вот таким образом:

ВАЖНО: Вывод XTAL2 должен болтаться в воздухе! Подключать его никуда не надо. Если и это не помогает то остается последний вариант

Внешний генератор

Этот генератор можно сделать практически из любой логики или например из таймера 555. Под рукой оказалась микросхема 74HC00. Вместо нее можно использовать нашу к155ла3. Схема предельно проста и не требует наладки:

Генератор работает на частоте около 1.3 МГц. Естественно ее можно подстроить меняя номиналы резистора и конденсатора, но вряд-ли в этом будет необходимость. Плату я для него не делал т.к. смысла не было. Ногу XTAL2 нужно оставить болтаться в воздухе. Если и после этого контроллер не завелся, то это значит что контроллер умер или программирование по SPI запрещено или отключен RESET. Помочь тут может только параллельный программатор.

Вопросы, предложения, уточнения кидаем в комментарии.

ШИМ (PWM) — широтно-импульсная модуляция. Не нужно пугаться данного термина. Это всего навсего способ регулирования напряжения. Допустим подсветка монитора горит слишком ярко, вы меняете яркость. А что же происходит в этот момент на самом деле?

Представим себе, что подсветка монитора это несколько светодиодов. Питается все это дело от постоянного напряжения. Но вот нам понадобилось уменьшить яркость монитора. Логично ответить, что это можно сделать переменным резистором. На маленьких токах — возможно. Но на больших, резистор будет сильно греться. Сильно возрастут габариты, потери, энергопотребление.

Поэтому люди придумали схему на транзисторах, которая делает из постоянного напряжения пульсирующее. Оказывается, пульсирующее напряжение, в зависимости от заполнения периода будет эквивалентно постоянному напряжению. Т.е. если в течение периода напряжение 50% времени было включено, 50% выключено, то эквивалент постоянного напряжения будет равен 50% от номинального.

В цифрах это просто — было 5В постоянного напряжения прогнали через ШИМ — получили 2,5В. Если заполнение импульса равно 75%, то эквивалентное постоянное напряжение будет 3,75В. Думаю идея понятна.

Теперь приступим к практической реализации. Будем при помощи микроконтроллера изменять заполнение от 0 до 100%, потом от 100% до нуля. Конечный результат должен выглядеть так:

Чтобы было более наглядно, подключим светодиод. В результате у нас будет плавно включаться и отключаться светодиод.

Запускаем наш любимый CodeVision. Создаем проект при помощи мастера. В разделе таймеров (Timers), выбираем Timer 2 и выставляем настройки как на рисунке.

Если попробовать сгенерировать проект, то прога может ругнуться. Соглашаемся, ведь у нас нога 3 порта В должна быть настроена как выход.

Приводим код к следующему виду:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include void main(void ) { PORTB= 0x00 ; DDRB= 0x08 ; // Timer/Counter 2 initialization ASSR= 0x00 ; TCCR2= 0x6C ; TCNT2= 0x00 ; OCR2= 0x00 ; TIMSK= 0x00 ; while (1 ) { } ; }

#include void main(void) { PORTB=0x00; DDRB=0x08; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) { }; }

Уделим внимание строке OCR2=0x00; Эта переменная как раз и отвечает за величину заполнения импульса. Изменяется данная величина от 0 до 255(0хFF), т.е. 255 соответствует 100% -му заполнению (постоянный ток). Следовательно, если нужно 30% заполнение (255/100)*30=77. Далее 77 переводим в шестнадцатеричную систему OCR2=0x4D;

TCCR2=0x6C; Изменяя данную величину мы можем регулировать частоту ШИМ. Величина частоты работы ШИМ кратна частоте, на которой работает микроконтроллер. В проекте использована частота микроконтроллера 8 МГц, частоту ШИМ использовали 125кГц, следовательно делитель равен 8/125=64
0x6C в двоичной системе счисления 1101100, открываем даташит на Atmega8 и видим описание регистра TCCR2, так вот 1101100 последние цифры 100 и отвечают за выбор частоты работы ШИМ

Приступим непосредственно к программе:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include #include void main(void ) { PORTB= 0x00 ; DDRB= 0x08 ; ASSR= 0x00 ; TCCR2= 0x6C ; TCNT2= 0x00 ; OCR2= 0x00 ; TIMSK= 0x00 ; while (1 ) { while (OCR2< 0xff ) { OCR2= OCR2+ 0x01 ; delay_ms(5 ) ; } while (OCR2> 0x00 ) { OCR2= OCR2- 0x01 ; delay_ms(5 ) ; } } ; }

#include #include void main(void) { PORTB=0x00; DDRB=0x08; ASSR=0x00; TCCR2=0x6C; TCNT2=0x00; OCR2=0x00; TIMSK=0x00; while (1) { while(OCR2<0xff) { OCR2=OCR2+0x01; delay_ms(5); } while(OCR2>0x00) { OCR2=OCR2-0x01; delay_ms(5); } }; }

Код прост до безобразия: сначала в цикле увеличиваем заполнение от 0 до 255(ff), потом уменьшаем от 255 до 0.
И напоследок видосик, как это все должно работать. Успехов в изучении)

Достаточно часто появляется необходимость использовать управление какого-либо устройства (будь то лампочка накаливания, двигатель, ТЭН или простой светодиод) посредством ШИМ.

Наверно объяснять что это такое и в чем прелесть управления ШИМом не нужно, информации в интернете накопилось уже достаточно много, да и врядли мне получиться разжевать эту тему лучше. Поэтому сразу перейдем к делу, а именно запустим ШИМ на Attiny2313 средствами Bascom-AVR.

Шим в микроконтроллерах AVR работает на таймерах-счетчиках, в мк Tiny2313 таких таймеров всего 2: 8-и битный Timer0 считающий до 255 и 16-и битный Timer1 способный считать до 65535. Каждый таймер управляет двумя ШИМ-каналами, таким образом всего аппаратно можно реализовать целых 4 канала ШИМ.

Информацию о количестве каналов ШИМ и разрядность каждого канала можно глянуть на страницах даташита на микроконтроллер.

Так, на борту Attiny2313 имеются два 8-и битных канала ШИМ работающих от Timer0 и еще два канала под управлением таймера Timer1 имеют программируемую разрядность от 8 до 10 бит. В даташите эти ноги подписываются следующим образом:

Для того чтобы сконфигурировать таймер Timer1 на генерацию ШИМ в Bascom достаточно записать следующую строку:

Config Timer1 = Pwm, Pwm = 8 , Compare A Pwm = Clear Up, Compare B Pwm = Clear Down, Prescale = 64

Pwm = 8 выбирается разрядность ШИМ, для Timer1 как писалось выше может быть также Pwm = 9 или Pwm = 10.

Compare A/B Pwm = Clear Up/Clear Down здесь конфигурируем активное состояние для каждого канала ШИМ (А и В).

Prescale = 64 - уже знакомая строка конфигурации таймера, отвечающая за предварительное деление частоты переполнения таймера, в данном случае делитель будет задавать частоту ШИМ. Можем менять на свое усмотрение Prescale= 1|8|64|256|1024


Скважность генерируемого сигнала определяется значением, которые мы записываем в регистры сравнения OCR1A и OCR1B (каналов ШИМ же у нас два на одном таймере, вот по одному регистру на канал А и В). Со значениями, которые лежат в этих регистрах постоянно сравнивается значение счетного регистра (туда оно копируется с таймера), при их совпадении происходит переключение ноги мк в активное состояние, а счетный регистр продолжает считать до своего максимального значения. Досчитав до максимума, таймер начинает считать в обратном направлении, и дойдя до момента когда значения счетного регистра и регистра сравнения снова совпадут, произойдет обратное переключение на ноге микроконтроллера (см. рисунок ниже)



Для нас регистры сравнения OCR1A и OCR1B всего-навсего переменные, в которые мы можем положить какое-нибудь значение. Например, так:


OCR1A = 100
OCR1B = 150


В баскоме для удобства предусмотрено и другое название этих регистров: PWM1A и PWM1B, так предыдущие строки будут равнозначны следующим:


PWM1A = 100
PWM1B = 150

Теперь разберемся, как влияет конфигурация активного состояния Clear Up/Clear Down на то, что происходит на выходе ШИМ в зависимости от значения регистра сравнения.

Когда выход сконфигурирован как Compare A Pwm = Clear Down активным состоянием выхода является высокий уровень и при увеличении значения регистра OCR (PWM) пропорциональное напряжение на этой ноге будет расти. С точностью до наоборот все будет происходить, если выход сконфигурирован как Compare A Pwm = Clear Up. Все это хорошо проиллюстрировано на картинке ниже



Значения, которые могут принимать эти регистры сравнения зависят от того, какую разрядность канала ШИМ мы выбрали. При PWM = 8 (8-и битный шим) возможно значение от 0 до 255; при PWM = 9 от 0 до 511; при PWM = 10 от 0 до 1023. Тут я думаю, все понятно.


Теперь небольшой пример: подключим к микроконтроллеру светодиоды как показано на схеме (питание мк на схеме не указано)


И напишем небольшую программку:


$crystal = 4000000

Config Timer1 = Pwm, Pwm = 9 , Compare A Pwm = Clear Down, Compare B Pwm = Clear Up, Prescale = 8
Config PORTB.3 = Output
Config PORTB.4 = Output

Incr Pwm1a "плавно увеличиваем значение регистра сравнения OCR1A
Incr Pwm1b "плавно увеличиваем значение регистра сравнения OCR1B

Waitms 20 "добавим задержку

Loop

End

После того как откомпилировали и прошили программу в контроллер один из светодиодов (D1) будет плавно набирать яркость, а другой (D2) плавно гаснуть


Если сейчас ткнуть осциллографом на выходы ШИМ, то можем увидеть такую вот картину с изменяющейся скважностью импульсов (синий сигнал на ОС1А, красный на ОС1В):


Конфигурация таймера Timer0 для генерации ШИМ практически такая же, за исключением того, что timer0 это 8-и битный таймер, и поэтому ШИМ генерируемый этим таймером будет всегда иметь разрядность 8. Поэтому конфигурируя этот таймер, разрядность ШИМ не указывается:

Config Timer0 = Pwm, Compare A Pwm = Clear Up, Compare B Pwm = Clear Down, Prescale = 64



Теперь аналогичный пример со светодиодами, но теперь шим сгенерируем при помощи Timer0:


$regfile = "attiny2313.dat"
$crystal = 4000000

Config Timer0 = Pwm, Compare A Pwm = Clear Down, Compare B Pwm = Clear Up, Prescale = 8
Config PORTB.2 = Output
Config PORTD.5 = Output

Incr Pwm0a " плавно увеличиваем значение регистра OCR0A
Incr Pwm0b " плавно увеличиваем значение регистра OCR0B

Waitms 20 "добавим задержку

Loop

End

Подключим светодиоды к выходу ШИМ Timer0, как показано на схеме:

Тут все аналогично: первый светодиод (D1) будет плавно набирать яркость, а второй (D2) будет плавно гаснуть.


Подсчет частоты генерации ШИМ

Если требуется узнать частоту генерации ШИМ, то сделать это не сложно. Смотри на формулу ниже:

Частота ШИМ = (частота кварца/предделитель) / (размер счетного регистра *2)

Для примера подсчитаем несколько значений:

1. Частота кварца = 4000000 Гц, предделитель = 64, разрядность ШИМ 10 бит => размер счетного регистра = 1024

Частота ШИМ = (4000000/64)/(1024*2) = 122 Гц

2. Частота кварца = 8000000 Гц, предделитель = 8, разрядность ШИМ 9 бит => размер счетного регистра = 512

Частота ШИМ = (8000000/8)/(512*2) = 976,56 Гц

3. Частота кварца 16000000 Гц, предделитель = 1, разрядность ШИМ 8 бит => размер счетного регистра = 256

Частота ШИМ = (16000000/1)/(256*2) = 31250 Гц


Широтно-Импульсная Модуляция (ШИМ, PWM). Урок AVR 8

Наверное, вы не раз задавались вопросом, как можно регулировать мощность потребителя, например управлять яркостью светодиода или регулировать обороты двигателя. Самый простой способ - последовательно нагрузке, например светодиоду, включить резистор, но ведь он будет греться и забирать драгоценную энергию, и чем мощней светодиод, тем сильней будет греться наш резистор, такой вариант не для нас. А что если светодиод очень быстро включать и выключать, при этом меняя длительность включений при константной частоте? Например, включать светодиод на 0,2 милисекунди каждую милисекунду, то светодиод засветится, но не на полную яркость. Аналогично с двигателем - включать движок на 30 секунд каждую минуту - тогда двигатель раскрутится, но не на полную скорость - относительно большой вес ротора сгладит рывки от включающегося двигателя, а сопротивление от трения будет его притормаживать. Таким образом, двигатель будет крутится на половину своей мощности.

Широтно-импульсная модуляция

- приближение желаемого сигнала (многоуровневого или непрерывного) к действительным бинарным сигналам (с двумя уровнями - вкл / выкл), так, что, в среднем, за некоторый отрезок времени, их значения равны.

Основной причиной внедрения ШИМ является сложность обеспечения произвольным напряжением. Есть какое-то базовое постоянное напряжение питания (сети, от аккумуляторов и пр.). И на его основе нужно получить более низкую и уже им питать электродвигатели или иное оборудование. Самый простой вариант - делитель напряжения, но он имеет пониженное КПД, повышенное выделением тепла и расходом энергии. Другой вариант - транзисторная схема. Она позволяет регулировать напряжение без использования механики. Основное преимущество ШИП - высокий КПД его усилителей мощности, который достигается за счет использования исключительно в ключевом режиме. Это значительно уменьшает выделение мощности на силовом преобразователе (СП).

ШИМ является импульсный сигнал постоянной частоты и переменной скважности, то есть отношения периода следования импульса к его длительности. С помощью задания скважности (длительности импульсов) можно менять среднее напряжение на выходе ШИМ . У цифровой технике, выходы которой могут принимать только одно из двух значений, приближение желаемого среднего уровня выхода с помощью ШИМ является совершенно естественным. Давайте на практике попробуем изменять яркость светодиода. Схема очень проста как в первом уроке:

Самое главное находится в прошивке:

void main(void)
{ PORTB=0x00; //Выставляем все выходы порта B на 0 DDRB=0xFF; //Делаем порт B как выход, чтобы мы могли менять лог уровень на ножках (устанавливать или 0 или 1) while (1) //Организовываем бесконечный цикл { PORTB.1=1; //Включаем светодиод на 1 выходе порта B delay_us(5); //разрешаем светодиоду посветится 5 микросекунд PORTB.1=0; //Выключаем светодиод на 1 выходе порта B delay_us(5); //Делаем задержку на 5 микросекунд }; }

Компилим и закидываем в мк, светодиод должен светится на половину яркости. Но вы, наверное, уже успели заметить, что наша программа только то и делает, что устанавливает лог-уровни на выводе мк. Чтобы освободить главный цикл от этой рутинной работы, мы воспользуемся таймером.

Апаратный ШИМ
Таймер может генерировать ШИМ в нескольких режимах:

Итак, для наших нужд (регулировка яркости светодиода) подходит режим Fast PWM . Запускаем CodeWizard AVR, переходим на вкладку timers->timer1, выставляем все, как показано на скриншоте

  • Clock Source - выбор источника тактирования таймера, выбираем System Clock - таймер тактируeтся частотой, на которой работает микроконтроллер
  • Clock Value - выбор частоты работы таймера, здесь мы установили 1000000 hz, это значит, что переменная TCNT1 будет переполнятся с частотой 1000000/255 = 3921 hz, частота ШИМ будет 3921 khz
  • out A (вывод А) определяет состояния ножки OC1A при совпадении счетного регистра и регистра сравнения
  • Comp. A значение регистра сравнения
Кликаем File->Generate and save.

#include void main(void) { // Port B initialization PORTB=0x00; DDRB=0x02; // Timer/Counter 1 initialization TCCR1A=0x81; TCCR1B=0x09; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x64;// число 100 в шестнадцатеричном виде OCR1BH=0x00; OCR1BL=0x00; while (1) { }; }

Компилим и закидаем в мк, теперь наш светодиод должен светиться примерно на половину яркости.

Давайте теперь попробуем что-нибудь пропищать с помощью таймера:
Схема подключения динамика к мк:

Таймер мы установим в режим Fast PWM и будем плавно менять частоту от 0 - 4 khz.
Код такой программы выглядит следующим образом:

#include #include void main(void) { // Port B initialization PORTB=0x00; DDRB=0x02; // Timer/Counter 1 initialization TCCR1A=0x40; TCCR1B=0x09; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x64; OCR1BH=0x00; OCR1BL=0x00; while (1) { OCR1AL++; // увеличиваем регистр сравнения на 1, чтобы изменилась частота delay_ms(100); }; }


Перейдем к изучению встроенных таймеров.
Изучение прерываний и особенно таймеров в микроконтроллерах представляет определенную сложность из за их многофункциональности. Сегодня постараемся разобраться в терминах и названиях.

В микроконтроллерах AVR могут быть от одного до 4-х таймеров, восьмиразрядные или шестнадцатиразрядные.
Упрощенно таймеры обозначаются буквой T, и номером от нуля до трех. Обычно четные Т0 и Т2 являются восьмиразрядными, а нечетные Т1 и Т3 шестнадцатиразрядными. При программировании упрощенный вариант используется только в комментариях, а в программах прописывается полное название таймера – регистр TCNT. Ниже показаны обозначения таймеров:

Таймеры

T0, T2 – (TCNT0, TCNT2) восьмиразрядные счетчики (четные)
TCNTn - счетный регистр 8 разрядного счетчика
где; n-номер счетчика

T1, T3 – (TCNT1Н и TCNT1L, TCNT3H и TCNT3L) шестнадцатиразрядные счетчики (нечетные)
TCNTny - счетный регистр 16 разрядного счетчика
где; n-номер счетчика
y-старший (H) или младший (L) разряд

Т1 состоит из двух восьмиразрядных регистров TCNT1Н и TCNT1L , а
Т3 из двух регистров TCNT3H и TCNT3L . Буквой H обозначается старший разряд, а L младший.

Так как таймеры являются регистрами, то к ним можно обращаться в любой момент времени, считывать, записывать, обнулять и менять значение.
Приняты определенные правила записи и чтения в таймеры TCNT1Н и TCNT1L.

1. Программы записи и чтения данных таймера должны быть атомарными, т.е. перед чтением или записью мы запрещаем прерывания, а по окончании процесса вновь разрешаем.
2. При записи сначала записывается старший байт H а затем младший L.
3. При чтении сначала считывается младший байт L затем старший H.
Например:
Запись данных в счетный регистр.
CLI ; Запрещаем прерывания OUT TCNT1H,R16 ; Запись старшего байта OUT TCNT1L,R17 ; Запись младшего байта SEI ; Разрешаем прерывания

Чтение данных из счетного регистра
CLI ; Запрещаем прерывания IN TCNT1L,R16 ; Считывание младшего байта IN TCNT1H,R17 ; Считывание старшего байта SEI ; Разрешаем прерывания

Почему такие правила? А все для того, чтобы не исказились данные за то время, которое уйдет на процесс считывания из каждого регистра.
Если использовать прямое чтение 8-битных регистров TCNT1H и TCNT1L, то нельзя быть уверенным, что эти регистры прочитались одновременно. Может произойти следующая ситуация: Счетчик содержал значение $01FF, Вы считали TCNT1H (содержащий значение 01 в какую-то переменную). За это время пришел счетный импульс, и содержимое TCNT1L стало равно $00, а в TCNT1H записалось значение $02.

Теперь Вы читаете значение TCNT1L в другую переменную, получаете в этой переменной значение $00 (ведь таймер/счетчик уже произвел счет). 16-битное значение этих переменных получилось $0100, но на момент считывания старшего байта содержимое счетчика было $01FF, и младший байт у Вас должен был прочитаться как FF. Для предотвращения такой ситуации служит временный регистр, содержащийся в блоке таймера/счетчика. Этот регистр прозрачный, т.е. действует автоматически. При считывании значения регистра TCNT1L в переменную, содержимое TCNT1H попадает в этот регистр. Затем при чтении старшего байта в переменную, считывается значение временного регистра. Временный регистр абсолютно прозрачен для пользователя, но для его корректной работы необходимо соблюдать указанную выше последовательность действий. Обращение к регистрам через дополнительный (буферный) регистр называется двойной буферизацией

Таймеры связаны с счетными импульсами , которые могут быть внешними и поступать на специальный вход микросхемы или формироваться собственным генератором. В свою очередь частота собственного генератора может синхронизироваться внешним кварцевым резонатором, а может определяться внутренней RC – схемой. После этого, внешняя частота или частота собственного генератора, проходят предделитель, управляемый регистром CLKPR .Частоту генератора после предделителя (прескалера) CLKPR нередко называют тактовым сигналом (тактовой частотой) процессора (CPU) .
Частота, подаваемая на вход таймера обозначается как CLKTn Эта частота соответствует тактовому сигналу процессора.
Один счетный импульс увеличивает значение таймера на единицу, поэтому регистры TCNT являются счетными, и называются таймером/счетчиком (ТС) .
Для правильной работы таймера/счетчика по внешнему тактовому сигналу минимальное время между двумя переключениями внешнего тактового сигнала должно быть не менее одного периода тактового сигнала CPU. Синхронизируется внешний тактовый сигнал нарастающим фронтом внутреннего тактового сигнала CPU. (Это нужно помнить при построении частотомеров).
Управляющим регистром для таймера/счетчика TCNT является регистр TCCR .
Маской прерывания для таймера/счетчика TCNT служит регистр TIMSK (регистр управления прерываниями таймера).
Регистром флагов маски прерывания TIMSK - является регистр TIFR . Запомните, что эти 3 регистра (TCCR, TIMSK, TIFR) при работе таймера/счетчика TCNT используются почти всегда.

Прерывания могут вызываться по переполнению регистра TCNT, сравнению значения регистра TCNT со значением специальных регистров сравнения OCR, захвату – по значениям специальных регистров захвата ICR и определяются режимом работы таймера/счетчика . Кроме этого запрос прерывания может происходить по срабатыванию сторожевого таймера (Watchdog Timer) WDT.

Таймеры/счетчики могут работать в разных режимах и соответственно выполнять разные функции.
Режим работы, то есть, поведение таймера/счетчика и выхода сигнала совпадения, определяется как режимом работы генератора сигналов, управляемого регистрами WGM02; WGM01; WGM00 (сокращенная запись WGM02:0 ), так и режимом вывода сигнала совпадения, управляемых регистрами СОМ0х1; СОМ0х0 (сокращенная запись СОМ0х1:0 ). Состояние битов, от которых зависит режим вывода сигнала совпадения, не влияет на последовательность подсчета, которая определяется только состоянием битов конфигурации генератора сигналов.

Биты СОМ0х1:0 определяют, должен ли выходной сигнал ШИМ быть инвертирован или нет (инвертированный или не инвертированный ШИМ).
(ШИМ) Широтно-импульсная модуляция или Pulse-width modulation (PWM).
Для не-ШИМ-режимов содержимое битов СОМ0х1:0 определяет, должен ли сигнал на выходе быть установлен в единицу, сброшен в ноль либо переключен в противоположное состояние в момент совпадения

--
Спасибо за внимание!
Игорь Котов, главный редактор журнала «Датагор»

Можно сделать шаг равный единице, тогда изменения будут выглядеть следующим образом:
plus: rcall delay ; Переход в подпрограмму задержки inc temp2 ; Переходим на один шаг и проверяем, не равен ли результат нулю breq plus_1 ; Если равен, то переходим на метку plus_1 rjmp Correct ; Возват на опрос кнопок plus_1: dec temp2 ; вычитаем единицу rjmp Correct ; Возврат на опрос кнопок minus: rcall delay ; Переход в подпрограмму задержки dec temp2 ; Переходим на один шаг и проверяем, не равен ли результат нулю breq minus_1 ; Если равен, то переходим на метку minus_1 rjmp Correct ; Возврат на опрос кнопок minus_1: inc temp2 ; прибавить единицу rjmp Correct ; Возврат на опрос кнопок

В связи с неактуальностью AVRStudio 5, и микроконтроллера ATtiny2313 серия статей будет переписана под AtmelStudio6, и микроконтроллеры ATmega8 и ATmega16. Заранее приношу извинения за неудобства.

Понравилась статья? Поделитесь ей