В прошлом занятии мы познакомились с системным таймером SysTick и получили возможность управлять интервалами задержек. Мы узнали возможности данного таймера, которые далеко не безграничны.
Но не всё так плохо, так как у контроллеров STM32 очень много других таймеров с различными возможностями. Мы с ними давно уже знакомы из прошлых занятий, мало того, мы знаем, как они организованы в аппаратном исполнении, а также знаем основные их регистры и назначения их битов и битовых полей из урока 147, который, если кто-то не видел, то обязательно рекомендую просмотреть, так как данные регистры и их настройки мы будем сегодня обязательно использовать.
Для чего нужны таймеры, мы тоже прекрасно знаем, поэтому, чтобы не тянуть резину, предлагаю сразу же приступить к практической части.
Проект нашего занятия сделан из проекта прошлого урока с именем CMSIS_SYSTICK, а новое имя проекту присвоено CMSIS_TIM2, так как работать мы будем именно с таймером 2.
Откроем наш проект в Keil, и добавим в файле main.c новую функцию инициализации нашего таймера
1 2 3 4 5 |
//---------------------------------------------------------- static void TIM2_Init(void) { } //---------------------------------------------------------- |
Первым делом в данной функции организуем тактирование нашего таймера
1 2 3 |
static void TIM2_Init(void) { SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN); |
Включим глобальные прерывания таймера, иначе локальные без них работать не будут
1 2 |
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN); NVIC_EnableIRQ(TIM2_IRQn); |
Произведём основные настройки делителя и также регистра с числом, до которого будет наш таймер считать
1 2 3 |
NVIC_EnableIRQ(TIM2_IRQn); WRITE_REG(TIM2->PSC, 3599); WRITE_REG(TIM2->ARR, 2000); |
Теперь счётчик нашего таймера будет отсчитывать интервалы по 100 милисекунд.
Вызовем данную функцию в main()
1 2 |
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN |RCC_APB2ENR_IOPBEN); TIM2_Init(); |
Напишем макрос для разрешения прерывания от таймера по событию обновления счётчика
1 2 3 |
#define SYSCLOCK 72000000U //---------------------------------------------------------- #define TIM_EnableIT_UPDATE(TIMx) SET_BIT(TIMx->DIER, TIM_DIER_UIE) |
Также добавим макрос для запуска таймера, то есть для включения его счётчика
1 2 |
#define TIM_EnableIT_UPDATE(TIMx) SET_BIT(TIMx->DIER, TIM_DIER_UIE) #define TIM_EnableCounter(TIMx) SET_BIT(TIMx->CR1, TIM_CR1_CEN) |
Ну, и также добавим макрос для остановки счётчика таймера
1 2 |
#define TIM_EnableCounter(TIMx) SET_BIT(TIMx->CR1, TIM_CR1_CEN) #define TIM_DisableCounter(TIMx) CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN) |
Почему именно макросы, а не функции? А потому что в данном случае не сгенерируется подпрограмма, а порой включить и выключить таймер требуется быстро. Можно использовать функции inline, но они носят только рекомендательный характер для компилятора, а использование макроса точно обеспечит вставку его кода в тело без всяких подпрограмм.
В функции main() вызовем наши функции, разрешив прерывания от таймера и запустив его
1 2 3 4 |
MODIFY_REG(GPIOB->CRL, GPIO_CRL_CNF1 | GPIO_CRL_CNF0,\ GPIO_CRL_MODE1_0 | GPIO_CRL_MODE0_0); TIM_EnableIT_UPDATE(TIM2); TIM_EnableCounter(TIM2); |
Теперь если мы соберём наш код и запустим его на выполнение, у нас опять зависнет программа и мы уже знаем почему.
Убедившись в этом, удалим весь наш код из бесконечного цикла и добавим обработчик прерывания от таймера в самом низу файла main.c. Как найти имя функции для обработки прерываний, мы уже знаем
1 2 3 4 5 |
//---------------------------------------------------------- void TIM2_IRQHandler(void) { } //---------------------------------------------------------- |
Теперь у нас два обработчика прерываний в нашем коде. У прерываний пока будут одинаковые приоритеты, так как мы не настраивали контроллер NVIC. Но нас пока и так всё устраивает. Во-первых, потому, что мы в данном уроке не будем пользоваться системным таймером, так как у нас не будет задержек, а, во-вторых, потому, что приоритеты и контроллер NVIC — это отдельная тема и очень серьёзная, ею мы займёмся в более поздних уроках.
В обработчике, который мы только что добавили, мы сначала очистим флаг прерывания, убедившись сначала в том, что именно он у нас установлен, тем самым убедившись также и в том, что мы попали в обработчик именно по интересующему нас событию таймера — по событию обновления счётчика
1 2 3 4 5 6 |
void TIM2_IRQHandler(void) { if(READ_BIT(TIM2->SR, TIM_SR_UIF)) { CLEAR_BIT(TIM2->SR, TIM_SR_UIF); } |
Добавим глобальную переменную, в которой мы будем считать данные события, и с помощью неё включать разные светодиоды
1 2 |
__IO uint32_t SysTick_CNT = 0; __IO uint8_t tim2_count = 0; |
Вернёмся в наш обработчик TIM2_IRQHandler и добавим конструкцию switch, в которой, в зависимости от значения нашей переменной, мы будем зажигать определённый светодиод и гасить предыдущий
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
CLEAR_BIT(TIM2->SR, TIM_SR_UIF); switch(tim2_count) { case 0: LED10_OFF(); LED1_ON(); break; case 1: LED1_OFF(); LED2_ON(); break; case 2: LED2_OFF(); LED3_ON(); break; case 3: LED3_OFF(); LED4_ON(); break; case 4: LED4_OFF(); LED5_ON(); break; case 5: LED5_OFF(); LED6_ON(); break; case 6: LED6_OFF(); LED7_ON(); break; case 7: LED7_OFF(); LED8_ON(); break; case 8: LED8_OFF(); LED9_ON(); break; case 9: LED9_OFF(); LED10_ON(); break; } |
Проинкрементируем наш пользовательский счётчик и, если он достигнет 9, то обнулим
1 2 3 4 |
case 9: LED9_OFF(); LED10_ON(); break; } tim2_count++; if(tim2_count>9) tim2_count=0; |
Соберём код, прошьём контроллер и посмотрим, как работает наша светодиодная планка, а, следовательно и наш таймер
У меня тут рядом оказался будильник с громкой секундной стрелкой, который я сейчас поднёс к уху, и вроде он тикает на одном и том же месте бегущего огня на светодиодной планке.
Таким образом, сегодня мы научились работать с таймером, используя библиотеку CMSIS, что помогло нам отсчитать для наших светодиодов строго определённые периоды их зажигания и гашения, а, самое главное, что мы в данном случае уже не используем задержки, в которых наш контроллер висит ничего при этом не делая и не давая возможность выполнять какой-либо код в это время.
Всем спасибо за внимание!
Предыдущий урок Программирование МК STM32 Следующий урок
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Смотреть ВИДЕОУРОК (нажмите на картинку)
часть
Добрый день. У меня к Вам огромная просьба. Не могли бы Вы выпустить урок по управлению с помощью МК AVR и STM симистором. Например спецэффекты для елочных гирлянд на 220v. Плавное включение ламп, плавное затухание, моргание не затушенных полностью ламп итд. Очень интересная тема. Для Нас, новичков в этом деле.
Вам нужно доработать обе программы и создать схему.Доработать программно и аппаратно.На СТМ я пробывал на cmsis в течение некоторого времени.
извините что вмешиваюсь я наверное вам могу помочь.Информативно даже могу дать часть кода по AVR.Спецэффекты делаются на таймере.Только я немного по другому.Одновременно переключение и плавная работа гирлянды невозможно одним таймером.нужно Например 4 канальная гирлянда.Управление переключением таймером одним.А шим 4 канала другим порты разные аппаратная развязка .Управление переключением эффектов кнопкой желательно в обработчике прерывания по таймеру.Три таймера.я Просчитался./*
* tesst-button.c
*
* Created: 24.07.2016 5:36:48
* Author : User
*/
#define F_CPU 1000000UL
#include
#include
#include
#define BUTON_1 (PIND&1<<2)
#define BUTON_2 (PIND&1<1)
{
//Flag1=0;
pauza=0;
r++;
}
}
if (!(BUTON_2))
{
Flag2=1;
//pauza=0;
pauza=0;
_delay_ms(20);
}
if ((Flag2==1)&&(BUTON_2))
{
//_delay_ms(20);
if(pauza_b>1)
{
//_delay_ms(20);
pauza=0;
Flag2=0;
S=S-50;
}
}
//_delay_ms(20);
}
ISR(TIMER1_COMPB_vect)
{
TCNT1H=0;
TCNT1L=0;
pauza_b++;
//_delay_ms(20);
}
ISR(TIMER2_COMP_vect)
{
TCNT2=0;
pauza++;
}
void program_14(void)
{
if (pauza>0)
{
PORTC|=(1<<0);
}
if (pauza==10)
{
PORTC&=~(1<<0);
}
if (pauza==11)
{
PORTC|=(1<<1);
}
if (pauza==21)
{
PORTC&=~(1<<1);
}
if (pauza==22)
{
PORTC|=(1<<2);
}
if (pauza==32)
{
PORTC&=~(1<<2);
}
if (pauza==33)
{
PORTC|=(1<<3);
}
if (pauza==43)
{
PORTC&=~(1<<3);
}
if (pauza==44)
{
PORTC|=(1<<2);
}
if (pauza==54)
{
PORTC&=~(1<<2);
}
if (pauza==55)
{
PORTC|=(1<<1);
}
if (pauza==65)
{
PORTC&=~(1<<1);
}
if (pauza==66)
{
PORTC|=(1<<0);
}
if (pauza==76)
{
PORTC|=(1<<1);
}
if (pauza==87)
{
PORTC|=(1<<2);
}
if (pauza==97)
{
PORTC|=(1<<3);
}
if (pauza==107)
{
PORTC&=~(1<<0);
}
if (pauza==117)
{
PORTC&=~(1<<1);
}
if (pauza==127)
{
PORTC&=~(1<<2);
}
if (pauza==137)
{
PORTC&=~(1<<3);
}
if (pauza==147)
{
PORTC|=(1<<0);
PORTC|=(1<<2);
}
if (pauza==157)
{
PORTC&=~(1<<0);
PORTC&=~(1<<2);
}
if (pauza==167)
{
PORTC|=(1<<1);
PORTC|=(1<<3);
}
if (pauza==177)
{
PORTC&=~(1<<1);
PORTC&=~(1<<3);
pauza=0;
}
}
void program_13(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
}
if (pauza==10)
{
PORTC|=(1<<1);
}
if (pauza==20)
{
PORTC|=(1<<2);
}
if (pauza==30)
{
PORTC|=(1<<3);
}
if (pauza==40)
{
PORTC&=~(1<<0);
}
if (pauza==50)
{
PORTC&=~(1<<1);
}
if (pauza==60)
{
PORTC&=~(1<<2);
}
if (pauza==70)
{
PORTC&=~(1<<3);
pauza=0;
}
}
void program_12(void)
{
if (pauza==2)
{
PORTC|=(1<<3);
}
if (pauza==13)
{
PORTC&=~(1<<3);
}
if (pauza==15)
{
PORTC|=(1<<0);
}
if (pauza==26)
{
PORTC&=~(1<<0);
}
if (pauza==28)
{
PORTC|=(1<<1);
}
if (pauza==39)
{
PORTC&=~(1<<1);
}
if (pauza==41)
{
PORTC|=(1<<2);
}
if (pauza==52)
{
PORTC&=~(1<<2);
}
if (pauza==84)
{
PORTC&=~((1<<0)|(1<<1)|(1<<2)|(1<<3));
pauza=0;
}
}
void program_11(void)
{
if (pauza==1)
{
PORTC|=(1<<3);
}
if (pauza==10)
{
PORTC&=~(1<<3);
}
if (pauza==11)
{
PORTC|=(1<<2);
}
if (pauza==20)
{
PORTC&=~(1<<2);
}
if (pauza==21)
{
PORTC|=(1<<1);
}
if (pauza==30)
{
PORTC&=~(1<<1);
}
if (pauza==31)
{
PORTC|=(1<<0);
}
if (pauza==40)
{
PORTC&=~(1<<0);
pauza=0;
}
}
void program_10(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
}
if (pauza==20)
{
PORTC&=~(1<<0);
}
if (pauza==22)
{
PORTC|=(1<<0);
}
if (pauza==40)
{
PORTC&=~(1<<0);
}
if (pauza==42)
{
PORTC|=(1<<1);
}
if (pauza==60)
{
PORTC&=~(1<<1);
}
if (pauza==62)
{
PORTC|=(1<<1);
}
if (pauza==80)
{
PORTC&=~(1<<1);
}
if (pauza==82)
{
PORTC|=(1<<2);
}
if (pauza==100)
{
PORTC&=~(1<<2);
}
if (pauza==102)
{
PORTC|=(1<<2);
}
if (pauza==120)
{
PORTC&=~(1<<2);
}
if (pauza==122)
{
PORTC|=(1<<3);
}
if (pauza==140)
{
PORTC&=~(1<<3);
}
if (pauza==142)
{
PORTC|=(1<<3);
}
if (pauza==160)
{
PORTC&=~(1<<3);
pauza=0;
}
}
void program_9(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
PORTC|=(1<<3);
}
if (pauza==20)
{
PORTC&=~(1<<0);
PORTC&=~(1<<3);
}
if (pauza==22)
{
PORTC|=(1<<1);
PORTC|=(1<<2);
}
if (pauza==40)
{
PORTC&=~(1<<1);
PORTC&=~(1<<2);
pauza=0;
}
}
void program_8(void)
{
if (pauza==20)
{
PORTC|=(1<<0);
PORTC|=(1<<1);
}
if (pauza==40)
{
PORTC&=~(1<<0);
}
if (pauza==42)
{
PORTC|=(1<<2);
}
if (pauza==62)
{
PORTC&=~(1<<1);
}
if (pauza==64)
{
PORTC|=(1<<3);
}
if (pauza==86)
{
PORTC&=~(1<<2);
}
if (pauza==88)
{
PORTC&=~(1<<3);
pauza=0;
}
}
void program_7(void)
{
if (pauza==20)
{
PORTC|=(1<<0);
PORTC|=(1<<1);
PORTC|=(1<<2);
PORTC|=(1<<3);
}
if (pauza==40)
{
PORTC&=~(1<<0);
PORTC&=~(1<<1);
PORTC&=~(1<<2);
PORTC&=~(1<<3);
pauza=0;
}
}
void program_6(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
PORTC|=(1<<1);
PORTC|=(1<<2);
PORTC|=(1<<3);
}
if (pauza==20)
{
PORTC&=~(1<<0);
}
if (pauza==22)
{
PORTC|=(1<<0);
PORTC&=~(1<<1);
}
if (pauza==42)
{
PORTC|=(1<<1);
PORTC&=~(1<<2);
}
if (pauza==44)
{
PORTC|=(1<<2);
PORTC&=~(1<<3);
}
if (pauza==64)
{
PORTC|=(1<<3);
pauza=0;
}
}
void program_5(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
PORTC|=(1<<2);
}
if (pauza==20)
{
PORTC&=~(1<<0);
PORTC&=~(1<<2);
}
if (pauza==22)
{
PORTC|=(1<<1);
PORTC|=(1<<3);
}
if(pauza==42)
{
PORTC&=~(1<<1);
PORTC&=~(1<<3);
pauza=0;
}
}
void program_4(void)
{
if (pauza==2)
{
PORTC|=(1<<0);
}
if (pauza==4)
{
PORTC&=~(1<<0);
}
if (pauza==22)
{
PORTC|=(1<<1);
}
if (pauza==22)
{
PORTC&=~(1<<1);
}
if (pauza==42)
{
PORTC|=(1<<2);
}
if (pauza==44)
{
PORTC&=~(1<<2);
}
if (pauza==62)
{
PORTC|=(1<<3);
}
if (pauza==64)
{
PORTC&=~(1<<3);
pauza=0;
}
}
void program_3(void)
{
if (pauza==10)
{
PORTC|=(1<<0);
}
if (pauza==20)
{
PORTC|=(1<<1);
}
if (pauza==30)
{
PORTC|=(1<<2);
}
if (pauza==40)
{
PORTC|=(1<<3);
}
if (pauza==50)
{
PORTC&=~(1<<0);
}
if (pauza==60)
{
PORTC&=~(1<<0);
}
if (pauza==70)
{
PORTC&=~(1<<1);
}
if (pauza==80)
{
PORTC&=~(1<<2);
}
if (pauza==90)
{
PORTC&=~(1<<3);
pauza=0;
}
}
void program_2(void)
{
if (pauza==1)
{
PORTC|=(1<<0);
}
if (pauza==10)
{
PORTC&=~(1<<0);
}
if (pauza==11)
{
PORTC|=(1<<1);
}
if (pauza==19)
{
PORTC&=~(1<<1);
}
if (pauza==20)
{
PORTC|=(1<<2);
}
if (pauza==29)
{
PORTC&=~(1<<2);
}
if (pauza==30)
{
PORTC|=(1<<3);
}
if (pauza==39)
{
PORTC&=~(1<<3);
}
if (pauza==40)
{
pauza=0;
}
}
void program_1()
{
if (pauza==1)
{
PORTC|=(1<<0);
}
if (pauza==11)
{
PORTC&=~(1<<0);
PORTC|=(1<<1);
}
if (pauza==21)
{
PORTC&=~(1<<1);
PORTC|=(1<<2);
}
if (pauza==31)
{
PORTC&=~(1<<2);
PORTC|=(1<<3);
}
if (pauza==41)
{
PORTC&=~(1<<3);
PORTC|=(1<<2);
}
if (pauza==51)
{
PORTC&=~(1<<2);
PORTC|=(1<<1);
}
if (pauza==61)
{
PORTC&=~(1<<1);
}
if (pauza==62)
{
pauza=0;
}
}
void nastroyki()
{
DDRB=0xFF;
PORTB=0x00;
DDRC=(0<<6)|(1<<3)|(1<<2)|(1<<1)|(1<<0);
PORTC=(1<<6)|(0<<3)|(0<<2)|(0<<1)|(0<<0);
DDRD=(1<<5)|(1<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0);
PORTD=(0<<5)|(0<<4)|(1<<3)|(1<<2)|(0<<1)|(0<<0);
GICR=(0<<INT1)|(0<<INT0);//регистр подключения INT1.INT0(PORTB3.PORTB2)в режиме прерывания
MCUCR=(1<<ISC11) | (1<<ISC10) | (1<<ISC01) | (1<<ISC00);//регистр срабатывания прерывания по лог 0 INT1.INT0
GIFR=(1<<INTF1) | (1<<INTF0);//флаги об оканчания прерывания (регистр)выставлен в лог 1
TCNT1L=0;
TCNT1H=0;
TCNT0=0;
TCCR0|=(1<<CS02)|(0<<CS01)|(1<<CS00);
//TCCR1B|=(1<<WGM12)|(1<<WGM13);
TCCR1A=0;
TCCR1B|=(1<<CS12)|(0<<CS11)|(1<<CS10);
OCR1B=250;
OCR2=250;
TCNT2=0;//счетный регистр
TIMSK|=(1<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (1<<OCIE1B) | (0<<TOIE1) | (1<<TOIE0);//регистр маски прерываний он уст 1 прерывание по сравнению
ASSR=0<<AS2;
TCCR2|=(0<<WGM21)|(1<<CS22) | (0<<CS21) | (1<<CS20);//регистр управления 0 и2 биты установлены в лог 1 f/1023 частота работы таймера f-частота работы AVR
TIFR|=(1<<OCF2)|(1<<TOV0);//флаг прерывания таймера по сравнению
TIFR|=(1<<OCF1B)|(0<<TOV1);
//главный в моём случае регистр управления и счётный регистр хотя эту задержку можно написать в прерывании в сравнении
}
int main(void)
{
nastroyki();
asm("sei");
while (1)
{
if(r==1)
{
//asm("cli");
program_1();
// asm("sei");
}
while (r==2)
{
// asm("cli");
program_2();
// asm("sei");
}
while (r==3)
{
// asm("cli");
program_3();
}
if (r==4)
{
// asm("cli");
program_4();
}
while (r==5)
{
program_5();
}
while(r==6)
{
program_6();
}
while(r==7)
{
program_7();
}
while(r==8)
{
program_8();
}
while (r==9)
{
program_9();
}
while (r==10)
{
program_10();
}
while (r==11)
{
program_11();
}
while (r==12)
{
program_12();
}
while(r==13)
{
program_13();
}
while (r==14)
{
program_14();
}
if (r==15)
{
r=1;
}
}
}
и Шим
/*
* pwm mega128.c
*
* Created: 17.12.2017 19:46:39
* Author : User
*/
#define F_CPU 8000000UL
#include
#include
#include
#define FIRST_ADC_INPUT 0//деректива ввода первого вывода АЦП
#define LAST_ADC_INPUT 4//последнего вывода АЦП
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0< (LAST_ADC_INPUT-FIRST_ADC_INPUT))
input_index=0;
ADMUX=(FIRST_ADC_INPUT | ADC_VREF_TYPE)+input_index;
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
}
ISR(TIMER2_COMP_vect)
{
//PORTE|=(1<<6);
PORTE&=~(1<<6);
}
ISR(TIMER2_OVF_vect)
{
// PORTE&=~(1<<6);
PORTE|=(1<<6);
}
// unsigned int ADC_result(unsigned char adc_input)
//{
// ADMUX=adc_input | (ADMUX & 0xF0);
//задержка для стабилизации входного напряжения
// _delay_us(10);
//начинаем преобразование (ADSC = 1)
// ADCSRA=ADCSRA|(1<<ADSC);
// while(ADCSRA & (1<<ADSC));//ждем, пока АЦП закончит преобразование (ADIF = 0)
// return ADC;//ADC — содержит ADCH и ADCL
//}
void init_ports()
{
DDRE|=(1<<3)|(1<<4)|(1<<5)|(1<<6);
PORTE|=(0<<3)|(0<<4)|(0<<5)|(0<<6);
DDRC|=0xFF;
DDRF|=0x00;
DDRB|=(0<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7);
PORTB|=(0<<3)|(0<<4)|(0<<5)|(0<<6)|(0<<7);
}
void init_timers()
{
TCCR0|=(0<<FOC0)|(1<<WGM00)|(1<<COM01)|(0<<COM00)|(1<<WGM01)|(1<<CS02)|(0<<CS01)|(0<<CS00);
TIMSK|=(1<<OCIE2)|(1<<TOIE2)|(0<<TICIE1)|(0<<OCIE1A)|(0<<OCIE1B)|(0<<TOIE1)|(0<<OCIE0)|(0<<TOIE0);
TIFR|=(0<<OCF2)|(0<<TOV2)|(0<<ICF1)|(0<<OCF1A)|(0<<OCF1B)|(0<<TOV1)|(0<<OCF0)|(0<<TOV0);
EIMSK|=(0<<TICIE3)|(0<<OCIE3A)|(0<<OCIE3B)|(0<<TOIE3)|(0<<OCIE3C)|(0<<OCIE1C);
ETIFR|=(0<<ICF3)|(0<<OCF3A)|(0<<OCF3B)|(0<<TOV3)|(0<<OCF3C)|(0<<OCF1C);
TCCR2|=(0<<FOC2)|(1<<WGM20)|(0<<COM21)|(0<<COM20)|(1<<WGM21)|(0<<CS22)|(0<<CS21)|(1<<CS20);
TCCR1B|=(0<<ICNC1)|(0<<ICES1)|(0<<WGM13)|(1<<WGM12)|(0<<CS12)|(0<<CS11)|(1<<CS10);
TCCR1A|=(1<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)|(1<<COM1C1)|(0<<COM1C0)|(0<<WGM11)|(1<<WGM10);
TCCR1C|=(0<<FOC1A)|(0<<FOC1B)|(0<<FOC1C);
TCCR3A|=(1<<COM3A1)|(0<<COM3A0)|(1<<COM3B1)|(0<<COM3B0)|(1<<COM3C1)|(0<<COM3C0)|(0<<WGM31)|(1<<WGM30);
TCCR3B|= (0<<ICNC3)|(0<<ICES3)|(0<<WGM33)|(1<<WGM32)|(0<<CS32)|(0<<CS31)|(1<<CS30);
TCCR3C|=(0<<FOC3A)|(0<<FOC3B)|(0<<FOC3C);
TCNT0=0;
TCNT1H=0;
TCNT1L=0;
TCNT2=0;
TCNT3H=255;
TCNT3L=255;
OCR1A=0;
OCR1B=0;
OCR1C=0;
OCR0=0;
OCR2=2;
OCR3A=0;
OCR3B=0;
OCR3C=254;
}
void init_ADC()
{
ADCSRA|=(1<<ADEN);
ADCSRA|=(1<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
ADMUX |=(0<<REFS1)|(1<<REFS0);
ADCSRA |=(1<<ADSC);
}
int main(void)
{
init_ports();
init_timers();
init_ADC();
asm("sei");
while (1)
{
// asm("cli");
if(OCR1A<254)
{
//if (pauza==1)
OCR1A=OCR1A+1;
_delay_ms(1);
}
// asm("cli");
if(OCR1B<254)
{
OCR1B=OCR1B+1;
_delay_ms(1);
}
if(OCR1C<254)
{
OCR1C=OCR1C+1;
_delay_ms(1);
}
if(OCR0<254)
{
OCR0=OCR0+1;
_delay_ms(1);
}
if(OCR3A<254)
{
OCR3A=OCR3A+1;
_delay_ms(1);
}
if(OCR3B1)
{
OCR3C=OCR3C-1;
_delay_ms(1);
}
if(OCR20)
// {
// OCR2=OCR2-1;
// _delay_ms(1);
// }
// if(OCR3C>0)
// {
// OCR3C=OCR3C-1;
// _delay_ms(1);
//}
// if(OCR3B>0)
// {
// OCR3B=OCR3B-1;
// _delay_ms(1);
//}
// if(OCR3A>0)
// {
// OCR3A=OCR3A-1;
// _delay_ms(1);
//}
//if(OCR2>0)
// {
// OCR2=OCR2-1;
// _delay_ms(1);
//}
// if(OCR1C>0)
//{
// OCR1C=OCR1C-1;
// _delay_ms(1);
//}
//if(OCR1B>0)
//{
// OCR1B=OCR1B-1;
// _delay_ms(1);
//}
//if(OCR1A>0)
//{
// OCR1A=OCR1A-1;
// _delay_ms(1);
//}
//if(OCR0>0)
//{
// OCR0=OCR0-1;
// _delay_ms(1);
//}
}
}