Использую софтовый юарт, аппаратный юарт с прерываниями по приему, таймер2 и внешнее прерывания для реализации трехканального димера на 220 вольт - и это все прекрасно работает(ну или я не вижу лагов), но как только я добавляю двухканальный шим на таймере1, без предделителя в режиме Fast PWM top=00FFh. Начинаются лаги выраженные в мерцании ламп, причем чем я ставлю ниже частоту шима тем меньше лагов.
в чем может быть приблема????
atmega8, 8мгц
куски кода
Спойлер
int main( void ){PortInit();
ExInterruptInit();
Timer_1_init();
Timer_2_init();
USART_Init();
SUART_Init();
Read_eeprom_all();
sei();
UART_PutStr("AT+NAMEZeSteam"); UART_PutStr("\r\n");
while(1){
...
тут логика основной программы, неспешная бработка кнопок
// OCR1AL = isp_power[fire_level-1];
// OCR1BL = fan_speed[fire_level-1];
и не важно закоментированны эти две строки или нет тупит уже после инициализации таймера
...
// обработка прерывания с с периодом 180мкс
ISR (TIMER2_COMP_vect){
if ((timer_pwm+1)== lamp[0]) {HIGH(LAMP1_OUT_PORT, LAMP1_OUT);}
if ((timer_pwm+1)== lamp[1]) {HIGH(LAMP2_OUT_PORT, LAMP2_OUT);}
if ((timer_pwm+1)== lamp[2]) {HIGH(LAMP3_OUT_PORT, LAMP3_OUT);}
if ((timer_pwm == 90) || (!timer_pwm)) {
LOW(LAMP1_OUT_PORT, LAMP1_OUT);
LOW(LAMP2_OUT_PORT, LAMP2_OUT);
LOW(LAMP3_OUT_PORT, LAMP3_OUT);
}
if (timer_pwm){timer_pwm--;}
}
//обработка внешнего прерывания INT0
ISR( INT0_vect ){
fl_timer_100ms = true;
timer_pwm = 90;
}
void Timer_1_init(void){
TCCR1A=0x21;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
}
void Timer_2_init(void){
ASSR=0x00;
TCCR2=0x0B;
TCNT2=0x00;
OCR2=0x15;
TIMSK=0x80;
}
void ExInterruptInit(void){
GICR|=0x40;
MCUCR=0x03;
GIFR=0x40;
}
void USART_Init(void){
UBRRH = 0;
UBRRL = 51; //скорость обмена 9600 бод
//разр. прерыв при приеме и передачи, разр приема, разр передачи.
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); // |(1<<TXCIE)
//размер слова 8 разрядов
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
ISR(USART_RXC_vect) { // прерывание при получении данных по UART (bluetooth)
comand_bt_str[1] = comand_bt_str[0];
comand_bt_str[0] = UDR;
if ((comand_bt_str[1] == 'i') || (comand_bt_str[1] == 'v') || (comand_bt_str[1] == 'a')){fl_bluetooth_receiv = true;}
}