Пт май 04, 2018 22:17:33
CLK_PCKENR2 = 0b00000101; // ADC + RTC
while (CLK_CRTCR & CLK_CRTCR_RTCSWBSY); // Wait for RTCSWBSY flag to clear
led(LED_3);
CLK_CRTCR = 0xB0; // RTC clock: source LSE, RTCDIV = 32
while (!(CLK_ECKCR & CLK_ECKCR_LSERDY)); // Wait for LSE stabilization
led(LED_2);
RTC_WPR = 0xCA;
RTC_WPR = 0x53;
RTC_ISR1 |= RTC_ISR1_INIT; // Enter initialization mode
while (!(RTC_ISR1 & RTC_ISR1_INITF)); // <--- тут зависаем
led(LED_1);
RTC_APRER = 0x08;
RTC_SPRERH = 0x00;
RTC_SPRERL = 0x80;
RTC_WUTRH = 0xFF; // Wakeup timer = 0xFFFF
RTC_WUTRL = 0xFF;
RTC_DR1 = 0x16;
RTC_DR2 = 0x04;
RTC_DR3 = 0x18;
RTC_TR3 = 0x21;
RTC_TR2 = 0x37;
RTC_TR1 = 0x54;
RTC_ISR1 &= ~RTC_ISR1_INIT; // Exit initialization mode
RTC_WPR = 0xFF;
#define RTC_ISR1_INIT ((uint8_t)0x80)
#define RTC_ISR1_INITF ((uint8_t)0x40)
#define CLK_CRTCR_RTCSWBSY ((uint8_t)0x01) /*!< RTC clock switch busy */
#define CLK_ECKCR_LSERDY ((uint8_t)0x08) /*!< Low speed external crystal oscillator ready */
#define RTC_ISR1 *(unsigned char*)0x514C // RTC Initialization and status register 1 0x01
#define RTC_WPR *(unsigned char*)0x5159 // RTC Write protection register 0x00
Сб май 05, 2018 13:37:49
Bits 7:5 WDU[2:0]: Week day units
000: forbidden.
001: Monday
...
111: Sunday
void init_periph(void) {
CLK_CKDIVR_CKM = 0x3; // HSintCLK / 8
CLK_CCOR_CCOSEL = 0; // disable clock output
CLK_ECKR_LSEON = 1; // enable LSE 32768
while (!CLK_ECKR_LSERDY) ; // wait while LSE ready
CLK_CRTCR_RTCSEL3 = 1;
CLK_PCKENR2_PCKEN23 = 1; // LCD
CLK_PCKENR2_PCKEN22 = 1; // RTC
// LCD stuff skipped
// Port stuff skipped
RTC_WPR = 0xCA;
RTC_WPR = 0x53;
RTC_ISR1_INIT = 1;
while (RTC_ISR1_INITF == 0) continue;
RTC_APRER_PREDIV_A = 127;
RTC_SPRERH = 0;
RTC_SPRERL = 255;
RTC_TR1 = 0x00;
RTC_TR2 = 0x32;
RTC_TR3 = 0x14;
RTC_DR1 = 0x05;
RTC_DR2 = 0x05 | (6 << 5);
RTC_DR3 = 0x18;
RTC_CR1 = 0;
RTC_ISR1_INIT = 0;
}
Сб май 05, 2018 19:54:05
; main.c: 223: CLK_PCKENR2 = 0b00000101; // ADC + RTC
ldw x, #0x50c4
ld a, #0x05
ld (x), a
; main.c: 224: CLK_CRTCR = 0b00010000; // RTC clock: source LSE
ldw x, #0x50c1
ld a, #0x10
ld (x), a
; main.c: 225: while (!(CLK_ECKCR & CLK_ECKCR_LSERDY)); // Wait for LSE stabilization
00104$:
ldw x, #0x50c6
ld a, (x)
bcp a, #0x08
jreq 00104$
; main.c: 227: RTC_WPR = 0xCA;
ldw x, #0x5159
ld a, #0xca
ld (x), a
; main.c: 228: RTC_WPR = 0x53;
ldw x, #0x5159
ld a, #0x53
ld (x), a
; main.c: 229: RTC_ISR1 |= RTC_ISR1_INIT; // Enter initialization mode
bset 0x514c, #7
; main.c: 231: while (!(RTC_ISR1 & RTC_ISR1_INITF));
00107$:
ldw x, #0x514c
ld a, (x)
bcp a, #0x40
jreq 00107$
; main.c: 236: RTC_APRER = 0x7F;
ldw x, #0x5152
ld a, #0x7f
ld (x), a
; main.c: 237: RTC_SPRERH = 0x00;
ldw x, #0x5150
clr (x)
; main.c: 238: RTC_SPRERL = 0xFF;
ldw x, #0x5151
ld a, #0xff
ld (x), a
; main.c: 240: RTC_DR1 = 0x16;
ldw x, #0x5144
ld a, #0x16
ld (x), a
; main.c: 241: RTC_DR2 = 0x04;
ldw x, #0x5145
ld a, #0x04
ld (x), a
; main.c: 242: RTC_DR3 = 0x18;
ldw x, #0x5146
ld a, #0x18
ld (x), a
; main.c: 244: RTC_TR3 = 0x21;
ldw x, #0x5142
ld a, #0x21
ld (x), a
; main.c: 245: RTC_TR2 = 0x37;
ldw x, #0x5141
ld a, #0x37
ld (x), a
; main.c: 246: RTC_TR1 = 0x54;
ldw x, #0x5140
ld a, #0x54
ld (x), a
; main.c: 248: RTC_ISR1 &= ~RTC_ISR1_INIT; // Exit initialization mode
bres 0x514c, #7
; main.c: 249: RTC_WPR = 0xFF;
ldw x, #0x5159main.c: 40:
ld a, #0xff
ld (x), a
ret
RTC_ISR1 &= ~(RTC_ISR1_INIT | RTC_ISR1_RSF);
Вс май 06, 2018 05:46:08
Ну дык, для того этот флаг (INITF) и есть. Тем более в даташите явно сказано, что переход в режим инициализации требует 2 такта RTCCLK, который вы еще и затормозили в 32 раза! У моего кристалла всё нормально работает: и RSF взводится, и часы тикают.a_winner писал(а):что если после установки флага INIT немного подождать, то потом флаг INITF нормально читается
Не нужно. По входу в режим инициализации оно и так сбрасывается. Надо просто читать все регистры TR и DR. Так как в даташите написано, что обновление теневых регистров блокируется после чтения TR1 или SSRL и разблокируется после чтения DR3.a_winner писал(а):Так, чтобы часы пошли нужно флаг RSF сбрасывать руками, например так:
Вс май 06, 2018 12:35:59
// Enter initialization mode
void RTC_InitModeEnter() {
RTC_ISR1 |= RTC_ISR1_INIT;
while (!(RTC_ISR1 & RTC_ISR1_INITF)) {
_delay_ms(10);
}
}
// Exit initialization mode
inline void RTC_InitModeExit() {
RTC_ISR1 &= ~(RTC_ISR1_INIT | RTC_ISR1_RSF);
}
// Unlock write protection of the RTC registers
inline void RTC_Unlock() {
RTC_WPR = 0xCA;
RTC_WPR = 0x53;
}
// Lock write protection of the RTC registers
inline void RTC_Lock() {
RTC_WPR = 0xFF;
}
// Init the RTC module
void initRTC() {
while (CLK_CRTCR & CLK_CRTCR_RTCSWBSY); // Wait for RTCSWBSY flag to clear
CLK_CRTCR = 0b00010000; // RTC clock: source LSE
while (!(CLK_ECKCR & CLK_ECKCR_LSERDY)); // Wait for LSE stabilization
RTC_Unlock();
RTC_InitModeEnter();
RTC_APRER = 0x7F;
RTC_SPRERH = 0x00;
RTC_SPRERL = 0xFF;
if (!(RTC_ISR1 & RTC_ISR1_INITS)) {
RTC_DR1 = 0x07;
RTC_DR2 = 0x05 | 0x20;
RTC_DR3 = 0x18;
RTC_TR3 = 0x21;
RTC_TR2 = 0x04;
RTC_TR1 = 0x54;
}
RTC_InitModeExit();
RTC_Lock();
}