Nosaer 0 3 августа, 2016 Опубликовано 3 августа, 2016 (изменено) · Жалоба Добрый день) Возникла проблема с принудительной установкой 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 и.т.д. Почему так? %) Изменено 3 августа, 2016 пользователем Nosaer Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 7 августа, 2016 Опубликовано 7 августа, 2016 · Жалоба 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 0 7 августа, 2016 Опубликовано 7 августа, 2016 · Жалоба Чтение 16-битных значений является атомарной операцией Дык, тут проблема не в атомарности, а в лишнем "!" в строке : while( !(RTC_STATUS & RTC_SYNCBUSY_bm) ); на AVR Freaks уже ответили Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aiwa 0 9 августа, 2016 Опубликовано 9 августа, 2016 · Жалоба Дык, тут проблема не в атомарности, а в лишнем "!" в строке : Замылился "!", не заметил. Значит имеются две проблемы. Причем, вторая не столько в атомарности, сколько в порядке чтения регистров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться