Переключение делителя таймера

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

Всем доброго времени суток. Столкнулся со следующей проблемой. При нажатии на кнопку значение переменной i увеличивается на единицу. В операторе switch -case исходя из значения переменной i происходит выборка делителя таймера. Это в идеале, а на деле где то делаю не правильно и естественно ничего не работает. Уважаемые Гуру, пожалуйста помогите новичку.

Код: Выделить всё

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>


//--------------------------------------------
unsigned char i=0;

//--------------------------------------------
void timer_ini(void)
{
	TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
	TIMSK |= (1<<OCIE1A);	//устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
	OCR1AH = 0b01111010; //записываем в регистр число для сравнения
	OCR1AL = 0b00010010;
	
}
//--------------------------------------------
ISR (TIMER1_COMPA_vect)
  {
  
      if (PINC & (1<<PINC0))
	  { 
		PORTC &= ~_BV(PC0);// переключаем светодиод на линии PC1
               }else{
		PORTC |= _BV(PC0);
                        }
          
  }
  
//--------------------------------------------
  
int main(void)
{
	 DDRC = 0xFF;
	 PORTC=0x00;
	 DDRB = 0x00;
	 PORTB=0XFF;
	  
   timer_ini();
   
   sei(); //разрешаем приревания

   while(1)
		{  	
		
			 //Переключение делителя  
		  switch(i){
			   case 1:  TCCR1B |= (1<<CS10);break;            //установим делитель. 
			      case 2:  TCCR1B |= (1<<CS11);break;                //установим делитель. 
				 case 3:  TCCR1B |= (0<<CS11)|(0<<CS10);break; //установим делитель. 
				    case 4:  TCCR1B |= (1<<CS12);break;                    //установим делитель. 
				       case 5:  TCCR1B |= (0<<CS12)|(0<<CS10);break; //установим делитель. 
			   default : TCCR1B |= (0<<CS12)|(0<<CS10); //установим делитель. по умолчанию
				 }	 
				 
       if (bit_is_clear(PINB, 0)){ //Если нажата кнопка РВ0 то увеличиваем значение i на едениу
	  
	 if(i<5){
	    _delay_ms(550);
	     i=i+1;
	     _delay_ms(550);
	  }else { i=5;}
	    

     if (bit_is_clear(PINB, 1)){  //Если нажата кнопка РВ1 то уменщаем значение i на едениу
	  
	 if(i>0){
	    _delay_ms(150);
	     i=i-1;
	     _delay_ms(150);
	    }
	    }
	    }
	    }
	    }
Добавлено after 1 hour 54 minutes 31 second:
подправил код. оператор переключения забыл вставить
Реклама
Модератор
Аватара пользователя
Сообщения: 19055
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Сообщение Starichok51 »

ты везде добавляешь биты по ИЛИ,но нигде не сбрасываешь ранее установленные биты, ставшие ненужными.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

[uquote="Starichok51",url="/forum/viewtopic.php?p=3845102#p3845102"]ты везде добавляешь биты по ИЛИ,но нигде не сбрасываешь ранее установленные биты, ставшие ненужными.[/uquote]

Сделал так, это правильно? Потому что всё равно не работает.

Код: Выделить всё

		 //Переключение делителя  
		  switch(i){
			   case 1:  TCCR1B = (1<<CS10);break;            //установим делитель. 
				 
			      case 2:  TCCR1B = (0<<CS10)|(1<<CS11);break;                //установим делитель. 		 
				  
				 case 3:  TCCR1B = (1<<CS11)|(1<<CS10);break; //установим делитель. 			
				       
				    case 4:  TCCR1B = (0<<CS11)|(0<<CS10)|(1<<CS12);break;                    //установим делитель.				
					   
				         case 5:  TCCR1B = (0<<CS11)|(1<<CS10)|(1<<CS12);;break; //установим делитель. 				
					
				 
			   default : TCCR1B=0; //установим делитель. по умолчанию
			      
				 }	 
Добавлено after 1 hour 38 minutes 37 seconds:
запустил, нужно было удалить default.

Добавлено after 1 hour 35 minutes 43 seconds:
Если не трудно проверьте пожалуйста мой код. Мне нужно добиться на выходе импульсы частотой 1, 10, 50, 100, 200 герц, но не могу понять как сделать.

Код: Выделить всё

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>


//--------------------------------------------
unsigned char i=0;

//--------------------------------------------
void timer_ini(void)
{
	TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению)
	TIMSK |= (1<<OCIE1A);	//устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
	OCR1AH = 0b01111010; //записываем в регистр число для сравнения
	OCR1AL = 0b00010010;
	
}
//--------------------------------------------
ISR (TIMER1_COMPA_vect)
  {
   static uint8_t b=0;
switch(b)
   {
      case 0:
          
		     PORTC =(1<<0)|(0<<1);         // светодиод 1 включить// светодиод  2 выключить
     break;
    
       case 1:
	  
                   
                 PORTC =(1<<0)|(1<<1);   // светодиод 1 включить // светодиод  2 включить
		   
      case 2:
                
		PORTC =(0<<0)|(1<<1);   // светодиод 1 выключить     // светодиод  2 включить
    
 
     break;
       case 3: 
   
              PORTC =(0<<0)|(0<<1);      // светодиод 1 выключить // светодиод  2 выключить
		      

     break;

}
b++;
b%=4;
          
  }
  
//--------------------------------------------
  
int main(void)
{
	 DDRC = 0xFF;
	 PORTC=0x00;
   	 DDRD = 0xFF;
	 PORTD=0x00;
	 DDRB = 0x00;
	 PORTB=0XFF;
	  
   timer_ini();
   
   sei(); //разрешаем приревания

   while(1)
		{  	
		   
		   
		   
		     switch(i){
			   case 1:  PORTD=0b00000001;break;            //установим делитель. 		      
				 
			      case 2:  PORTD=(1<<1);break;                //установим делитель. 		 
				  
				 case 3:  PORTD=(1<<2);break; //установим делитель. 			
				       
				    case 4:  PORTD=(1<<3);break;                    //установим делитель.				      
					   
				         case 5:  PORTD=(1<<4);break; //установим делитель. 		
			      
				 }	
		
			 //Переключение делителя  
		  switch(i){
			   case 1:  TCCR1B = (1<<CS10);break;            //установим делитель. 
				 
			      case 2:  TCCR1B = (0<<CS10)|(1<<CS11);break;                //установим делитель. 		 
				  
				 case 3:  TCCR1B = (1<<CS11)|(1<<CS10);break; //установим делитель. 			
				       
				    case 4:  TCCR1B = (0<<CS11)|(0<<CS10)|(1<<CS12);break;                    //установим делитель.				
					   
				         case 5:  TCCR1B = (0<<CS11)|(1<<CS10)|(1<<CS12);;break; //установим делитель. 				
				 }	
				 
      if (bit_is_clear(PINB, 0)){ //Если нажата кнопка РВ0 то увеличиваем значение i на едениу
	  
	 if(i<5){
	    _delay_ms(1700);
	     i=i+1;
	     _delay_ms(1700);
	  }else { i=0;}
	    

     if (bit_is_clear(PINB, 1)){  //Если нажата кнопка РВ1 то уменщаем значение i на едениу
	  
	 if(i>0){
	    _delay_ms(1700);
	     i=i-1;
	     _delay_ms(1700);
	    }
	    }
	    }
	    }
	    }
Самсусамыч

Сообщение Самсусамыч »

Ничего не понимаю в Си… но вот для тини13 с фьзами на заводских установках (1,2 МГц).
Кнопка плюс на РВ3, кнопка минус на РВ4. Кнопки замыкают выводы на GND. Выход частоты с вывода РВ0 (0 Гц; 1 Гц; 10 Гц; 50 Гц; 100 Гц; 200 Гц).

прошивка:
Test_But.hex
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

СпойлерДля частоты 8МГц

Код: Выделить всё

          //Переключение делителя 
        switch(i){
            case 1:  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10); OCR1A = 31249; break;         // 1 Гц установим делитель.
            
               case 2:  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10); OCR1A = 3124; break;        // 10 Гц установим делитель.       
             
             case 3:  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10); OCR1A = 624;  break; 			// 50 Гц установим делитель.          
                   
                case 4:  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10); OCR1A = 2499;  break;		// 100 Гц установим делитель.            
                  
                     case 5:  TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10); OCR1A = 1249;   break; // 200 Гц установим делитель.             
             }   
Реклама
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

Большое спасибо, всё заработало.
Реклама
Ответить

Вернуться в «AVR»