Перейти к содержанию
    

[решено] Attiny2313 , не менятеся предделитель таймера 0.

привет All. Подскажите в чем проблема. Контроллер Attiny 2313 используется для генерации сигнала на ножке PD6 ~ несколько сотен Гц.

Таймер 0 используется в режиме сброса при совпадении и генерирует нужный сигнал , таймер 1 в нормальном режиме и используется для опроса кнопок.

По нажатию на кнопку на пине PD3 происходит смена предделителя таймера 0. Однако, при выполнении программы , делитель меняется только один раз с 256 до 1024 , больше смена почему то не происходит. проверял в протеусе и на контролере, все абсолютно одинаково - "по нажатию" на PD3 один раз устанавливается больший предделитель и больше чип на кнопку не реагирует, частота сигнала понижается. Контроллер работает от внешнего кварца на 16 МГц.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

volatile uint8_t flags;
#define  KeysF 2
#define StopS 3


void init_timers(void){
cli();

// TCCR0A : com0A1 com0A0 com0B1 com0B0 - - WGM01 WGM00
// TCCR0B : FOC0A FOC0B - - WGM02 CS02 CS01 CS00

// TCCR1A : COM1A1 COM1A0 COM1B1 COM1B0 – – WGM11 WGM10
// TCCR1B : ICNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10
// TCCR1C : FOC1A FOC1B – – – – – –

// TIMSK  : TOIE1 OCIE1A OCIE1B - ICIE1 OCIE0B TOIE0 OCIE0A
// TIFR   : TOV1 OCF1A OCF1B – ICF1 OCF0B TOV0 OCF0A

TCCR0A = (1<<WGM01);
TCCR0B = (1<<CS02);

OCR0A = 254;	

TCCR1A = 0;
TCCR1B = (1<<CS12);	

TIMSK = (1<<OCIE0A) | (1<<TOIE1) ;

sei();
}


/*
Table 41. Clock Select Bit Description
CS02	  CS01	 CS00	        Description
0		0		0		No clock source (Timer/Counter stopped)
0		0		1		clkI/O/(No prescaling)
0		1		0		clkI/O/8 (From prescaler)
0		1		1		clkI/O/64 (From prescaler)
1		0		0		clkI/O/256 (From prescaler)
1		0		1		clkI/O/1024 (From prescaler)
1		1		0		External clock source on T0 pin. Clock on falling edge.
1		1		1		External clock source on T0 pin. Clock on rising edge.
*/



ISR(TIMER0_COMPA_vect){
flags |= 1;
}

ISR(TIMER1_OVF_vect){
flags |= (1<<KeysF);
TCNT1 = 65536 - 31250;
}


int main(void){
DDRB =  0;
PORTB = 0;

DDRD = 1<<PD6;
PORTD = (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3)  ;

init_timers();
sleep_enable();

while(1){
	sleep_cpu();
	if ((flags & 1) && !(flags & (1<<StopS))) {
		PORTD |= 1<<PD6 ;
		asm("nop");
		asm("nop");
		PORTD &= ~(1<<PD6) ;
		flags &= ~1 ;
	}
	if (flags & (1<<KeysF)) {				// 2 раза в секунду опрашиваем кнопки
		flags &= ~(1<<KeysF) ;

			// увеличиваем частоту таймер 0
		if (bit_is_clear(PIND,PD0) && OCR0A > 2) 		
				OCR0A --;	

			// уменьшаем частоту таймер 0
		if (bit_is_clear(PIND,PD1) && OCR0A < 255) 		
				OCR0A ++;	

		if (bit_is_clear(PIND,PD2)){
			if ( flags & (1<<StopS) )
				flags &= ~(1<<StopS) ;
			else
				flags |= (1<<StopS) ;			
		}

		if (bit_is_clear(PIND,PD3)){  
			cli();
			if (TCCR0B & (1<CS00))
				TCCR0B = (1<<CS02);
			else
				TCCR0B = (1<<CS02) | (1<<CS00);
			sei();
		}
	}
}
}

Изменено пользователем San_75

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if (TCCR0B & (1<CS00))

Вы сравниваете адрес TCCR0B с 0x01. Значение адреса TCCR0B равно 0x2E(0b00101110). Результат всегда 0. Отладка же есть, там сразу должно быть видно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хмм, почему тогда

volatile uint8_t c = TCCR0B; вставленная перед началом цикла в отладке с == 4 ?

И вообще у меня что-то шаблон порвался, как же мне добраться до содержимого TCCR0B ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может я и не прав в посте выше. я не проверял. Попробуйте в симуляторе прогнать или отладкой.

Можно попробовать

if (*TCCR0B & (1<CS00))

или

if (*(char*)TCCR0B & (1<CS00))

или

if (*(uint8_t*)TCCR0B & (1<CS00))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для чистоты эксперимента уберите засыпание. Из кода не видно в какой режим SLEEP входит тинька.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Den64, вы хотите сказать, что

if (TCCR0B & (1<CS00))

не работает, а

TCCR0B = (1<<CS02);

работает именно потому, что TCCR0B - это адрес? Ну-ну.

gerber прав, банальная опечатка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Черт , так опростоволоситься - не напечатать одну < и не заметить глядя в упор.

Всем спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...