Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Некорректно считывается TCNT1, ATmega168
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
OlegALL
Привет.
Проблема: неправильно считывается значение счётного регистра (TCNT1, ATmega168)

описание и код здесь: http://caxapa.ru/480467.html

помогите, горит проект! заранее спасибо
ILYAUL
Цитата
ISR(TIMER1_COMPB_vect) // срабатывает по сравнению, через 12 мс после сброса счётного регистра

Вот и сведите его к
Код
answer[4] = TCNT1L;
        answer[3] = TCNT1H;
TCNT1H = 0;
        TCNT1L = 0;

Будет работать? Скорее да. Всё остальное или в main или по функциям
OlegALL
Цитата(ILYAUL @ Jan 16 2014, 16:10) *
Вот и сведите его к
Код
answer[4] = TCNT1L;
        answer[3] = TCNT1H;
TCNT1H = 0;
        TCNT1L = 0;

Будет работать? Скорее да. Всё остальное или в main или по функциям




Не работает. Что и очевидно
ILYAUL
OCR1B = _12ms; запиши 0x2EE0
Не поможет , fuses проверь.
Сергей Борщ
Во-первых, поскольку answer изменяется в прерывании, а обрабатывается, скорее всего, в основном цикле, он должен быть volatile.
Во-вторых, вы не показали что у вас в TIMER1_COMPA_vect. Может там какая-то дикая задержка и TIMER1_COMPB_vect ждет, пока закончится тот обработчик.
В третьих, запрещать прерывания не нужно - они запрещаются автоматически при входе в обработчик прерывания.

Другого криминала пока не видно.
HNK0
To do a 16-bit write, the high byte must be written before the low byte.
For a 16-bit read, the low byte must be read before the high byte.
ILYAUL
Цитата(HNK0 @ Jan 17 2014, 18:15) *
To do a 16-bit write, the high byte must be written before the low byte.
For a 16-bit read, the low byte must be read before the high byte.

И в чём подвох?
HNK0
Цитата(ILYAUL @ Jan 17 2014, 11:33) *
И в чём подвох?


It is important to notice that accessing 16-bit registers are atomic operations. If an interrupt
occurs between the two instructions accessing the 16-bit register, and the interrupt code
updates the temporary register by accessing the same or any other of the 16-bit Timer Registers,
then the result of the access outside the interrupt will be corrupted. Therefore, when both
the main code and the interrupt code update the temporary register, the main code must disable
the interrupts during the 16-bit access.
ILYAUL
Тут у всех английский родной язык. Вы попробуйте по-русски написать , что Вы хотели этим сказать применительно к коду TC. Или просто поболтать вышли.
HNK0
Цитата(ILYAUL @ Jan 17 2014, 15:49) *
Тут у всех английский родной язык. Вы попробуйте по-русски написать , что Вы хотели этим сказать применительно к коду TC. Или просто поболтать вышли.

Я извиняюсь, невнимательно просмотрел код.

В AVR Studio симуляторе этот код правильно работает.

CODE
#include <avr\io.h>
#include <avr\interrupt.h>

#define _200us 182
#define _12ms 10909

#define DIR_1 0
#define DIR_2 1

#define STROB PC2
#define D1 PC3


void initia(void);

unsigned char answer[4];
unsigned short a;
unsigned short main(void)
{
cli();
initia();
sei();

a = 0;

while (1) {
a++;
}
return 0;
}

void initia(void)
{

DDRC |= 1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3 | 1<<DDC4;
PORTC |= 1<<PC3;

PORTC &= ~(1<<STROB);
PORTC |= 1<<D1;

DDRD &= ~(1<<DDD0 | 1<<DDD3);
DDRD |= 1<<DDD1 | 1<<DDD2;

TIMSK1 |= 1<<OCIE1A | 1<<OCIE1B;

OCR1A = _200us;
OCR1B = _12ms;
TCCR1B |= 1<<CS11;

UBRR0 = 7;
UCSR0B |= 1<<RXEN0 | 1<<RXCIE0 | 1<<TXEN0;

}

ISR(TIMER1_COMPB_vect)
{

answer[0] = TCNT1L;
answer[1] = TCNT1H;

PORTC &= ~(1<<STROB);
PORTC |= 1<<D1;

TCNT1H = 0;
TCNT1L = 0;
}
OlegALL
Спасибо всем ответившим, проблема решена. Перенёс задачу на другой таймер, всё равно надо было так делать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.