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

 
 
 
Reply to this topicStart new topic
> Xmega RTC.CNT
Nosaer
сообщение Aug 3 2016, 03:15
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 85
Регистрация: 6-02-15
Пользователь №: 84 967



Добрый день)

Возникла проблема с принудительной установкой RTC.CNT
При выполнении данного кода:
Код
RTC.PER = 34200;
CLK.RTCCTRL = CLK_RTCEN_bm + CLK_RTCSRC_RCOSC_gc;
RTC.INTCTRL = RTC_OVFINTLVL0_bm;
RTC.CTRL = RTC_PRESCALER_gm;                    // 1024 = 1s.
            
while( !(RTC_STATUS & RTC_SYNCBUSY_bm) );
RTC.CNTL = 0x11;    
RTC.CNTH = 0x22;
            
TCC0.PER = 10000;                                // Delay ~1s.
TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;
while(TCC0.CTRLA)
{
    asm("NOP");
}

sendCharE0(RTC.CNTH);                            // UART
sendCharE0(RTC.CNTL);

Если запрашиваю значение RTC.CNT через некоторый промежуток времени, то вижу что RTC считает все с 0x0000(0x0001, 0x0002 и.т.д.)


Если приведенный выше код, выполняю два раза:
Код
// 1
RTC.PER = 34200;
CLK.RTCCTRL = CLK_RTCEN_bm + CLK_RTCSRC_RCOSC_gc;
RTC.INTCTRL = RTC_OVFINTLVL0_bm;
RTC.CTRL = RTC_PRESCALER_gm;                    // 1024 = 1s.
            
while( !(RTC_STATUS & RTC_SYNCBUSY_bm) );
RTC.CNTL = 0x11;    
RTC.CNTH = 0x22;
            
TCC0.PER = 10000;                                // Delay ~1s.
TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;
while(TCC0.CTRLA)
{
    asm("NOP");
}

// 2
RTC.PER = 34200;
CLK.RTCCTRL = CLK_RTCEN_bm + CLK_RTCSRC_RCOSC_gc;
RTC.INTCTRL = RTC_OVFINTLVL0_bm;
RTC.CTRL = RTC_PRESCALER_gm;                    // 1024 = 1s.
            
while( !(RTC_STATUS & RTC_SYNCBUSY_bm) );
RTC.CNTL = 0x11;    
RTC.CNTH = 0x22;
            
TCC0.PER = 10000;                                // Delay ~1s.
TCC0.CTRLA = TC_CLKSEL_DIV1024_gc;
while(TCC0.CTRLA)
{
    asm("NOP");
}

sendCharE0(RTC.CNTH);                            // UART
sendCharE0(RTC.CNTL);

То уже все выставляется как я и планировал 0x2211, 0x2212 и.т.д.
Почему так? %)

Сообщение отредактировал Nosaer - Aug 3 2016, 03:15
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 7 2016, 05:41
Сообщение #2


Местный
***

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



Цитата(Nosaer @ Aug 3 2016, 06:15) *
sendCharE0(RTC.CNTH); // UART
sendCharE0(RTC.CNTL);

Почему так? %)

Чтение 16-битных значений является атомарной операцией и производиться в последовательности:
1. Запретить прерывания (если не запрещены)
2. Чтение младшего байта RTC.CNTL, при котором значение реального старшего байта счетчика заносится во временный TEMP-регистр, общий для таких операций.
3. Чтение значения из TEMP-регистр, а не из счетчика RTC старшего байта.
4. Разрешение прерываний, если они были запрещены на первом шаге.

Код
как-то так:
uchar high;
uchar low;
_disable();
low=RTC.CNTL;
high=RTC.CNTH;
_enable();
sendCharE0(high);                            // UART
sendCharE0(low);
Go to the top of the page
 
+Quote Post
zombi
сообщение Aug 7 2016, 21:02
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106



Цитата(aiwa @ Aug 7 2016, 08:41) *
Чтение 16-битных значений является атомарной операцией

Дык, тут проблема не в атомарности, а в лишнем "!" в строке :

while( !(RTC_STATUS & RTC_SYNCBUSY_bm) );

на AVR Freaks уже ответили
Go to the top of the page
 
+Quote Post
aiwa
сообщение Aug 9 2016, 15:30
Сообщение #4


Местный
***

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



Цитата(zombi @ Aug 8 2016, 00:02) *
Дык, тут проблема не в атомарности, а в лишнем "!" в строке :


Замылился "!", не заметил.
Значит имеются две проблемы.
Причем, вторая не столько в атомарности, сколько в порядке чтения регистров.

Go to the top of the page
 
+Quote Post

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

 


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


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