реклама на сайте
подробности

 
 
> [решено] Attiny2313 , не менятеся предделитель таймера 0.
San_75
сообщение Feb 13 2017, 01:11
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 14-03-13
Пользователь №: 76 008



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

#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 - Feb 13 2017, 11:09
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 7)
Den64
сообщение Feb 13 2017, 02:26
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 584
Регистрация: 22-11-07
Из: Курская область
Пользователь №: 32 571



if (TCCR0B & (1<CS00))
Вы сравниваете адрес TCCR0B с 0x01. Значение адреса TCCR0B равно 0x2E(0b00101110). Результат всегда 0. Отладка же есть, там сразу должно быть видно.
Go to the top of the page
 
+Quote Post
San_75
сообщение Feb 13 2017, 03:28
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 14-03-13
Пользователь №: 76 008



Хмм, почему тогда
volatile uint8_t c = TCCR0B; вставленная перед началом цикла в отладке с == 4 ?
И вообще у меня что-то шаблон порвался, как же мне добраться до содержимого TCCR0B ?
Go to the top of the page
 
+Quote Post
Den64
сообщение Feb 13 2017, 04:24
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 584
Регистрация: 22-11-07
Из: Курская область
Пользователь №: 32 571



Может я и не прав в посте выше. я не проверял. Попробуйте в симуляторе прогнать или отладкой.
Можно попробовать
if (*TCCR0B & (1<CS00))
или
if (*(char*)TCCR0B & (1<CS00))
или
if (*(uint8_t*)TCCR0B & (1<CS00))
Go to the top of the page
 
+Quote Post
aiwa
сообщение Feb 13 2017, 07:35
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Для чистоты эксперимента уберите засыпание. Из кода не видно в какой режим SLEEP входит тинька.
Go to the top of the page
 
+Quote Post
gerber
сообщение Feb 13 2017, 07:47
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(San_75 @ Feb 13 2017, 04:11) *
Код
if (TCCR0B & (1<CS00))

Вероятно, тут ошибка, нужно
Код
if (TCCR0B & (1<<CS00))


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Feb 13 2017, 10:49
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Den64, вы хотите сказать, что
Код
if (TCCR0B & (1<CS00))

не работает, а
Код
TCCR0B = (1<<CS02);

работает именно потому, что TCCR0B - это адрес? Ну-ну.
gerber прав, банальная опечатка.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
San_75
сообщение Feb 13 2017, 11:08
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 14-03-13
Пользователь №: 76 008



Черт , так опростоволоситься - не напечатать одну < и не заметить глядя в упор.
Всем спасибо.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.04293 секунд с 7
ELECTRONIX ©2004-2016