我正在尝试了解当器件从 LPM3.5唤醒时、一切工作原理。 我的设置基本上是从传感器读取数据并在 LCD 上显示这些数据、使用 RTC 每10分钟从传感器获取读数。 在大多数时间内、该单元将处于 LPM3.5模式、而 RTC 和 LCD 可使用 XT1晶振运行。 此外、在此期间、在 LPM3.5模式下、我将所有与 LCD/XT1晶振无关的 GPIO 设置为输出、并以低功耗驱动为低电平。 当我从 LPM3.5唤醒时、我想设置一些 IO 端口和计时器来读取我的传感器、将值写入 LCD 存储器、然后返回 LPM 3.5。
阅读用户指南、当 LOCKLPM5被置位时(通过进入 LPM3.5)、它将锁定引脚状态以及 RTC 和 LCD 的配置。 在用户指南中:"从 LPMx.5唤醒后、I/O 和连接到 RTC LDO 的模块的状态将被锁定并保持不变、直到您清除 PM5CTL0寄存器中的 LOCKLPM5位。" 数据表指示 RTC 和 LCD 处于"LPM3.5域"中。
由于我将 LPM3.5中未使用的所有 GPIO 设置为输出和低电平、如果我想为传感器操作设置一些 IO、我显然需要更改端口映射、从而清除 LOCKLPM5位。 当我清零 LOCKLPM5位时、这强制我必须重新初始化 XT1、RTC 和 LCD 控制器、对吧? 下面的用户指南部分似乎表明我必须重新初始化几乎所有内容、因为唤醒是一个 BOR。 编辑: 在 LPM3.5唤醒后、RTC 和 LCD 设置似乎仍然存在、我不必重新初始化它们。 我找到了一个例子,他们没有重新改造这些东西,它运转良好,所以这有点令人困惑…
用户指南还在"从 LPM3.5唤醒"中提到
1.4.3.3从 LPM3.5唤醒
从 LPM3.5唤醒后执行以下步骤:
1.按照与 RTC LDO 连接的模块的原样初始化它们的寄存器
在器件进入 LPM3.5之前进行了配置、但不启用中断。
2.初始化端口寄存器的方式与器件进入之前配置的方式完全相同
LPM3.5、但不启用端口中断。
3.如果在 LPM3.5中使用了 LF 晶振,则相应的 I/O 必须配置为 LFXIN
和 LFXOUT。 必须在时钟系统中启用 LF 晶振(请参阅时钟系统 CS)
章)。
4.将 PM5CTL0寄存器中的 LOCKLPM5位清零。
5.根据需要启用端口中断。
6.使能模块中断。
启用端口和模块中断后、唤醒中断将被视为正常中断。
在我的情况下、在我进入 LPM3.5之前、我有一些用于传感器读数的端口、这些端口作为低功耗输出/低电平。 但是、当我唤醒以进行测量时、我将需要一些驱动为高电平的电平、以及一对用作输入的电压。 在设置传感器读取所需的端口之前、我是否需要将端口寄存器设置为所有输出/低电平(不用于 XT1和 LCD)?
我一直在研究在 Launchpad 板的 LCD 上显示时间的 RTC 示例。 我想这个示例从 LPM3.5唤醒时从不需要重新初始化任何内容的原因是它从不需要清零 LOCKLPM5位、因为它只使用 RTC 和 LCD:
int main( void ) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer if (SYSRSTIV == SYSRSTIV_LPM5WU) // If LPM3.5 wakeup { Inc_RTC(); // Real clock PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF_L; // and set PMMREGOFF __bis_SR_register(LPM3_bits | GIE); // Re-enter LPM3.5 } else { // Initialize GPIO pins for low power Init_GPIO(); *Seconds = 0; // Set initial time to 12:00:00 *Minutes = 0; *Hours = 12; // Configure XT1 oscillator P4SEL0 |= BIT1 | BIT2; // P4.2~P4.1: crystal pins do { CSCTL7 &= ~(XT1OFFG | DCOFFG); // Clear XT1 and DCO fault flag SFRIFG1 &= ~OFIFG; }while (SFRIFG1 & OFIFG); // Test oscillator fault flag CSCTL6 = (CSCTL6 & ~(XT1DRIVE_3)) | XT1DRIVE_2; // Higher drive strength and current consumption for XT1 oscillator // Disable the GPIO power-on default high-impedance mode // to activate previously configured port settings PM5CTL0 &= ~LOCKLPM5; // Configure RTC RTCCTL |= RTCSS__XT1CLK | RTCIE; // Initialize RTC to use XT1 and enable RTC interrupt RTCMOD = 32768; // Set RTC modulo to 32768 to trigger interrupt each second // Configure LCD pins SYSCFG2 |= LCDPCTL; // R13/R23/R33/LCDCAP0/LCDCAP1 pins selected LCDPCTL0 = 0xFFFF; LCDPCTL1 = 0x07FF; LCDPCTL2 = 0x00F0; // L0~L26 & L36~L39 pins selected LCDCTL0 = LCDSSEL_0 | LCDDIV_7; // flcd ref freq is xtclk // LCD Operation - Mode 3, internal 3.08v, charge pump 256Hz LCDVCTL = LCDCPEN | LCDREFEN | VLCD_6 | (LCDCPFSEL0 | LCDCPFSEL1 | LCDCPFSEL2 | LCDCPFSEL3); LCDMEMCTL |= LCDCLRM; // Clear LCD memory LCDCSSEL0 = 0x000F; // Configure COMs and SEGs LCDCSSEL1 = 0x0000; // L0, L1, L2, L3: COM pins LCDCSSEL2 = 0x0000; LCDM0 = 0x21; // L0 = COM0, L1 = COM1 LCDM1 = 0x84; // L2 = COM2, L3 = COM3 LCDCTL0 |= LCD4MUX | LCDON; // Turn on LCD, 4-mux selected (LCD4MUX also includes LCDSON) // Display time LCDMEM[pos1] = digit[(*Hours) / 10]; LCDMEM[pos2] = digit[(*Hours) % 10]; LCDMEM[pos3] = digit[(*Minutes) / 10]; LCDMEM[pos4] = digit[(*Minutes) % 10]; LCDMEM[pos5] = digit[(*Seconds) / 10]; LCDMEM[pos6] = digit[(*Seconds) % 10]; // Display the 2 colons LCDMEM[7] = 0x04; LCDMEM[11] = 0x04; PMMCTL0_H = PMMPW_H; // Open PMM Registers for write PMMCTL0_L |= PMMREGOFF_L; // and set PMMREGOFF __bis_SR_register(LPM3_bits | GIE); // Enter LPM3.5 __no_operation(); // For debugger } }