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

 
 
 
Reply to this topicStart new topic
> Проблема с Т3 в ATMEGA128, Прошу помощи
aai_m
сообщение Mar 14 2008, 10:02
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 25
Регистрация: 29-11-05
Из: Донецк
Пользователь №: 11 548



Подобная тема поднималась уважаемым klen 16.11.2007 http://electronix.ru/forum/index.php?showt...%E0%E9%F2%E0%ED . К сожалению, проблема решена не была. Вернее уважаемый klen в частном случае решил, но сослася на потусторонние силы - "ШАЙТАН - БАЙРАМ" .
Суть проблемы - по ходу работы программы необходимо останавливать и вновь запускать таймер Т3 и менять содержимое регистров OCR3A/OCR3B/TCNT3. Первичная инициализация Т3 проходит успешно:
void timer3_init(void)
{
TCCR3B = 0x00; //stop
TCNT3H = 0xC1; //setup
TCNT3L = 0x81;
OCR3AH = 0x07;
OCR3AL = 0xCF;
OCR3BH = 0x07;
OCR3BL = 0xCF;
OCR3CH = 0x07;
OCR3CL = 0xCF;
ICR3H = 0x07;
ICR3L = 0xCF;
TCCR3A = 0x00;
TCCR3B = 0x09; //start Timer
}
Далее открываем фирменное описание на ATMEGA128 на странице 114 и читаем:
"The TCNTn, OCRnA/B/C, and ICRn are 16-bit registers that can be accessed by the AVR CPU via the 8-bit data bus. The 16-bit register must be byte accessed using two read or write operations. Each 16-bit timer has a single 8-bit register for temporary storing of the high byte of the 16-bit access. ".

Спасибо, что предупредили. Более того на странице 116 описания написано:
"The following code examples show how to do an atomic write of the TCNTn Register contents. Writing any of the OCRnA/B/C or ICRn Registers can be done by using the same principle."
И дается пример кода:
TIM16_WriteTCNTn:
; Save global interrupt flag
in r18,SREG
; Disable interrupts
cli
; Set TCNTn to r17:r16
out TCNTnH,r17
out TCNTnL,r16
; Restore global interrupt flag
out SREG,r18
ret
НО ЭТОТ КОД НИКОГДА РАБОТАТЬ НЕ БУДЕТ!
Потому что, на странице 365 того же описания с изумлением читаем:
($89) TCNT3H Timer/Counter3 – Counter Register High Byte
($88) TCNT3L Timer/Counter3 – Counter Register Low Byte
($87) OCR3AH Timer/Counter3 – Output Compare Register A High Byte и т. д.
Т. е. out TCNTnH,r17 в принципе не возможно(как к регистру ввода-вывода, т.к. такой регистр в регистровом файле отсутствует), а должно быть, по крайней мере, sts TCNTnH,R17 (как к адресному пространству памяти данных).
Применяем вот такую функцию :
void WriteOCR3A( unsigned int i )
{
unsigned char sreg;
CLI();
sreg = SREG;
OCR3A = i;
SREG = sreg;
SEI();
}
Но таймер Т3 правильно не настраивается. Причем есть действительно чертовчина. Например:
TCCR3B = 0x00; //stop
WriteTCNT3(Mem_TCNT);
WriteOCR3A(Mem_D_Period);
TCCR3B = 0x09; //start - не работает,

TCCR3B = 0x00; //stop
WriteTCNT3(Mem_TCNT);
WriteOCR3С(Mem_D_Period);
TCCR3B = 0x09; //start - не работает.
В симуляторе AVRStudio(Version 4.14 Beta 2) все работает без проблем.
Прошу помощи советом, ссылками для решения этой проблемы. Заранее благодарен.
Go to the top of the page
 
+Quote Post
hd44780
сообщение Mar 14 2008, 10:49
Сообщение #2


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



out TCNTnH,r17 - обобщенный вид инструкций out TCNT0H,r17, out TCNT1H,r17 и т.д. по числу таймеров. Так что работать должно.


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
aai_m
сообщение Mar 14 2008, 11:52
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 25
Регистрация: 29-11-05
Из: Донецк
Пользователь №: 11 548



Цитата(hd44780 @ Mar 14 2008, 14:49) *
out TCNTnH,r17 - обобщенный вид инструкций out TCNT0H,r17, out TCNT1H,r17 и т.д. по числу таймеров. Так что работать должно.


Позвольте с Вами не согласиться. Дело в том, что команда out P,Rr допустима для операндов P и Rr, где
P - порт(или регистр имеющий адрестр в регистровом файле), а Rr - регистр общего назначения. Так вот
TCNT3H, TCNT3L и т.д. не находятся в регистровом файле, а доступны лишь как память данных. Т.Е. КОМАНДА OUT К НИМ НЕ ДОПУСТИМА.

$2D ($4D) TCNT1H Timer/Counter1 – Counter Register High Byte
$2C ($4C) TCNT1L Timer/Counter1 – Counter Register Low Byte

Для TCNT1H таймера Т1 возможно out $2D, Rr или sts $4D, Rr но для таймера T3

($89) TCNT3H Timer/Counter3 – Counter Register High Byte

доступно долько sts $89, R. См. стр. 361, 362 описания 2467P–AVR–08/07
http://www.atmel.com/dyn/resources/prod_do...nts/doc2467.pdf
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 14 2008, 11:56
Сообщение #4


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(aai_m @ Mar 14 2008, 14:52) *
Для TCNT1H таймера Т1 возможно out $2D, Rr или sts $4D, Rr но для таймера T3

Я для таких случаев написал макрос
Код
//**************************************************************************
// OutPort - generate out or sts instruction
OutPort MACRO Port,reg
    IF (Port)<0x40
        OUT Port, reg
    ELSE
        STS Port, reg
    ENDIF
  ENDM
Go to the top of the page
 
+Quote Post
aai_m
сообщение Mar 14 2008, 12:02
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 25
Регистрация: 29-11-05
Из: Донецк
Пользователь №: 11 548



Цитата(KRS @ Mar 14 2008, 15:56) *
Я для таких случаев написал макрос
Код
//**************************************************************************
// OutPort - generate out or sts instruction
OutPort MACRO Port,reg
    IF (Port)<0x40
        OUT Port, reg
    ELSE
        STS Port, reg
    ENDIF
  ENDM

Уважаемый KRS, спасибо за совет. Возьму на вооружение, но проблема в том, что 16 разрядные регистры таймера Т3 даже при правильном обращении STS ведут себя не адекватно.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 14 2008, 12:13
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(aai_m @ Mar 14 2008, 14:02) *
Спасибо, что предупредили. Более того на странице 116 описания написано:


На самом деле это серьёзный плюс! Впервые такая конструкция была применена в i8054, так как в i8053 было сделано "обычно", в результате чего вы могли получить ошибку превышающую 256 единиц!

Цитата
НО ЭТОТ КОД НИКОГДА РАБОТАТЬ НЕ БУДЕТ!
Потому что, на странице 365 того же описания с изумлением читаем...

Да эта ошибка у них практически в каждом даташите, где появилось обращение к регистрам ч/з LD/ST.

Так как вы применяете, я тоже применяю таймера. Никаких проблем не возникало никогда. AVR Studio отлично эмулирует и достаточно точно. Единственно, что AVR Studio неверно эмулирует это обращения по не верным адресам. Ну например сделали вы стэк в области адресов ввода/вывода (например там даже устройств нет), - а в AVR Studio всё прекрасно работает. А в кристалле - шиш. smile.gif
Go to the top of the page
 
+Quote Post
Дон Амброзио
сообщение Mar 14 2008, 12:17
Сообщение #7


Местный
***

Группа: Участник*
Сообщений: 323
Регистрация: 11-02-08
Пользователь №: 34 947



Цитата(aai_m @ Mar 14 2008, 15:02) *
но проблема в том, что 16 разрядные регистры таймера Т3 даже при правильном обращении STS ведут себя не адекватно.


о "граблях" когда когда долго мучился с "глюком", а в результате "сам дурак" оказался


--------------------
После устранения бага в программе она стала работать....хуже
Go to the top of the page
 
+Quote Post
KRS
сообщение Mar 14 2008, 12:20
Сообщение #8


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(aai_m @ Mar 14 2008, 13:02) *
Применяем вот такую функцию :
void WriteOCR3A( unsigned int i )
{
unsigned char sreg;
CLI();
sreg = SREG;
OCR3A = i;
SREG = sreg;
SEI();
}

а зачем сохранять sreg?
обычно всетки функция выгдядит так
Код
void WriteOCR3A( unsigned int i )
{
unsigned char sreg;
sreg = SREG;
CLI();
OCR3A = i;
SREG = sreg;
}


или под IAR это делается так
Код
unsigned char oldState;
oldState = __save_interrupt();
__disable_interrupt();
/* Critical section goes here */
__restore_interrupt(oldState);


Кроме того, если вы используете чтение/запись 16 разрядных регистров только в основном коде или только в прерывании можно не запрещать прерывания, потому что между записью/чтением первого байта и второго может пройти неограниченное время ( гглавное что бы не вклинилась другая операция доступа к 16 разрядному регистру этого же таймера)
Go to the top of the page
 
+Quote Post
aai_m
сообщение Mar 14 2008, 12:35
Сообщение #9


Участник
*

Группа: Новичок
Сообщений: 25
Регистрация: 29-11-05
Из: Донецк
Пользователь №: 11 548



Цитата(SasaVitebsk @ Mar 14 2008, 16:13) *
На самом деле это серьёзный плюс! Впервые такая конструкция была применена в i8054, так как в i8053 было сделано "обычно", в результате чего вы могли получить ошибку превышающую 256 единиц!
Да эта ошибка у них практически в каждом даташите, где появилось обращение к регистрам ч/з LD/ST.

Так как вы применяете, я тоже применяю таймера. Никаких проблем не возникало никогда. AVR Studio отлично эмулирует и достаточно точно. Единственно, что AVR Studio неверно эмулирует это обращения по не верным адресам. Ну например сделали вы стэк в области адресов ввода/вывода (например там даже устройств нет), - а в AVR Studio всё прекрасно работает. А в кристалле - шиш. smile.gif


Уважаемый SasaVitebsk, Вы можете, в качестве примера привести код при работе с таймером Т3 для MEGA128. Заранее благодарен.

Цитата(Дон Амброзио @ Mar 14 2008, 16:17) *


Уважаемый Дон Амброзио, есть три опытных образца и все ведут себя одинаково. Правда MEGA128 из одной партии. Может быть. Не охота конечно демонтировать MEGA128.

Уважаемый KRS, поначалу SREG не сохранял, но сохранять советует описание ATMEGA128. Но эффекта нет. Возможно предлагают сохранять SREG по такой причине:
"2. Interrupts may be lost when writing the timer registers in the asynchronous timer If one of the timer registers which is synchronized to the asynchronous timer2 clock is written in the cycle before a overflow interrupt occurs, the interrupt may be lost." (Errata ATmega128 Rev. M) стр. 370.

Сообщение отредактировал aai_m - Mar 14 2008, 13:02
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 14 2008, 14:13
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(aai_m @ Mar 14 2008, 16:35) *
Уважаемый SasaVitebsk, Вы можете, в качестве примера привести код при работе с таймером Т3 для MEGA128. Заранее благодарен.

Я не работал с м128. Но какая разница? Таймеры у них у всех один к одному и давно уже не меняются. Работал с м640/м2560 (вплоть до 5 включительно) и, недавно с at90can128 (применял программный ШИМ).
Ну и как обычно м8/м4/м88/м16/м64.

Что именно у вас не работает? Опишите по подробнее!
Код
c = UDR0;                                                // Прочитать символ
TCNT3 = -(TIMOUT485);                                    // Начать сначала
TIFR3 = TIFR3;
TIMSK3    = 1;                                            // Разрешить прерывания    от Таймера 3 (Расчёт таймаута)


Код
...
#pragma    vector=TIMER3_OVF_vect                            // Тайм-аут    для    485    интерфейса.    Время переключения 5мс
__interrupt    static void    TimeOutFor485(void)
{
...
  TIMSK3 = 0;                                            // Запретить прерывания    от таймера
}
...
Go to the top of the page
 
+Quote Post

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

 


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


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