Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Xmega RTC.CNT
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Nosaer
Добрый день)

Возникла проблема с принудительной установкой 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 и.т.д.
Почему так? %)
aiwa
Цитата(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);
zombi
Цитата(aiwa @ Aug 7 2016, 08:41) *
Чтение 16-битных значений является атомарной операцией

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

while( !(RTC_STATUS & RTC_SYNCBUSY_bm) );

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


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

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.