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

 
 
 
Reply to this topicStart new topic
> Некорректно считывается TCNT1, ATmega168
OlegALL
сообщение Jan 16 2014, 11:50
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Привет.
Проблема: неправильно считывается значение счётного регистра (TCNT1, ATmega168)

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

помогите, горит проект! заранее спасибо
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 16 2014, 12:10
Сообщение #2


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



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

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

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


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Jan 16 2014, 12:24
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Цитата(ILYAUL @ Jan 16 2014, 16:10) *
Вот и сведите его к
Код
answer[4] = TCNT1L;
        answer[3] = TCNT1H;
TCNT1H = 0;
        TCNT1L = 0;

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




Не работает. Что и очевидно
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 16 2014, 12:45
Сообщение #4


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



OCR1B = _12ms; запиши 0x2EE0
Не поможет , fuses проверь.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 16 2014, 13:21
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Во-первых, поскольку answer изменяется в прерывании, а обрабатывается, скорее всего, в основном цикле, он должен быть volatile.
Во-вторых, вы не показали что у вас в TIMER1_COMPA_vect. Может там какая-то дикая задержка и TIMER1_COMPB_vect ждет, пока закончится тот обработчик.
В третьих, запрещать прерывания не нужно - они запрещаются автоматически при входе в обработчик прерывания.

Другого криминала пока не видно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
HNK0
сообщение Jan 17 2014, 14:15
Сообщение #6





Группа: Участник
Сообщений: 13
Регистрация: 23-07-09
Пользователь №: 51 509



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.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 17 2014, 14:33
Сообщение #7


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(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.

И в чём подвох?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HNK0
сообщение Jan 17 2014, 18:27
Сообщение #8





Группа: Участник
Сообщений: 13
Регистрация: 23-07-09
Пользователь №: 51 509



Цитата(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.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 17 2014, 18:49
Сообщение #9


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Тут у всех английский родной язык. Вы попробуйте по-русски написать , что Вы хотели этим сказать применительно к коду TC. Или просто поболтать вышли.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
HNK0
сообщение Jan 18 2014, 21:32
Сообщение #10





Группа: Участник
Сообщений: 13
Регистрация: 23-07-09
Пользователь №: 51 509



Цитата(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;
}


Сообщение отредактировал IgorKossak - Jan 19 2014, 15:59
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
OlegALL
сообщение Jan 20 2014, 05:14
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 30-11-10
Пользователь №: 61 275



Спасибо всем ответившим, проблема решена. Перенёс задачу на другой таймер, всё равно надо было так делать.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 14:40
Рейтинг@Mail.ru


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