快捷搜索:  汽车  科技

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)低速外部时钟信号(L.SE)有以下2种电路连接方式。专用PLL(PLLI2S)用于生成精确时钟,在I2S接口可实现高品质音频性能(参考STM32F4手册)由于在PLL使能后主PLL配置参数便不可更改,因此建议先对PLL进行配置,然后使能(选择IHIS振荡器时钟或HSE振荡器时钟作为PLL时钟源,并配置预分频系数M、N、P和Q)。PLLI2S使用与主PLL相同的输入时钟(PLLM[5:O]和PLLSRC位为两个PLL所共用)。但是,PLLI2S具有专门的使能/禁止和预分频系数(N和R)配置位。在PLLI2S使能后,配置参数便不能更改。在进入停机和待机模式后,两个PLL将由硬件禁止,如将HSE振荡器时钟或PLLCLK(由HSE振荡器提供时钟信号)用作系统时钟,则在HSE振荡器发生故障时,两个PLL也将由硬件禁止。RCC PLL配置寄存器(RCC PLLCFGR)和RCC时钟配置寄存器可分别用于

一、时钟系统结构1--简述

复位和时钟控制器为stm32f429微控制器提供了内核和片上外设需要的工作时钟,RCC具有高度的时钟选择和配置的灵活性。STM32F429单片机内部时钟系统以时钟树的形式存在。(下图可能不太清楚,树可查看STM32F4xx中文参考手册低107页)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(1)


根据上面的图可以知道,用户在运行内核和外设时可选择使用外部晶振、内部振荡器或PLL(锁相环),也可为以太网、USB OTG FS,以及HS、I2S和SDIO等需要特定时钟的外设提供合适的时钟源。
看图这是我说一下,就是跟着箭头走,有节点的说明这两条线是连接的。可以走,大致意思就是这。

1.1 总线时钟

RCC可通过多个预分频器配置AHB、高速APB(APB2)和低速APB(APB1)。
AHB的最大允许频率为108M,APB2为90MHz,APB1为45MHz。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(2)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(3)

2时钟源

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(4)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(5)

3--HSE时钟

HSE有以下两种输入方式:
1、外部晶振/陶瓷谐振器(无源电路)OSC_IN和OSC_OUT引脚上外接的晶振电路和内部谐振电路产生谐振输出信号,作为HSE供系统使用。
如图:

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(6)


谐振器和负载电容必须尽可能地靠近振荡器的引脚,以尽量减小输出失真和起振稳定时间。负载电容值必须根据所选振荡器的不同做适当调整。负载电容一般选择22~33pF。
HSE电路工作需要先被使能,可通过RCC时钟控制寄存器(RCC_CR)中的HSEON位使能或禁止。
2、外部时钟(有源电路)。
在此模式下,可以旁路内部谐振电路,直接将外部时钟信号输入芯片内部作为HSE使用。通过将RCC时钟控制寄存器中的HSEBYP和HSEON位置1选择此模式。必须使用占空比约为50%的外部时钟信号(方波、正弦波或三角波)来驱动OSCIN引脚,同时OSCOUT引脚应保持为高阻态,一般悬空。HSE时钟输入电路图如图所示。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(7)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(8)

4-- PLL配置

STM32F4系列微控制器的器件具有两个PLL,PLL内部结构图如图所示。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(9)

1.主PLL:

主PLL由HSE振荡器或HSI振荡器提供时钟信号,并具有两个不同的
输出时钟,
(1)第一个输出用于生成高速系统时钟(180MHz)。
(2)第二个输出用于生成USBOTG FS时钟(48MHz)、随机数发生器时钟(48MHz)和 SDIO时钟(48MHz)。

2.专用PLL(PLLI2S)

专用PLL(PLLI2S)用于生成精确时钟,在I2S接口可实现高品质音频性能(参考STM32F4手册)
由于在PLL使能后主PLL配置参数便不可更改,因此建议先对PLL进行配置,然后使能(选择IHIS振荡器时钟或HSE振荡器时钟作为PLL时钟源,并配置预分频系数M、N、P和Q)。
PLLI2S使用与主PLL相同的输入时钟(PLLM[5:O]和PLLSRC位为两个PLL所共用)。但
是,PLLI2S具有专门的使能/禁止和预分频系数(N和R)配置位。在PLLI2S使能后,配置参数便不能更改。
在进入停机和待机模式后,两个PLL将由硬件禁止,如将HSE振荡器时钟或PLLCLK(由
HSE振荡器提供时钟信号)用作系统时钟,则在HSE振荡器发生故障时,两个PLL也将由硬件禁止。RCC PLL配置寄存器(RCC PLLCFGR)和RCC时钟配置寄存器可分别用于配置主PLL和 PLLI2S.
选择HSE振荡器作为主PLL的输入源,PLLCLR-(HSE/AM)×N/P。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(10)

4---LSE时钟

低速外部时钟信号(L.SE)有以下2种电路连接方式。

1.外部晶振/陶瓷谐振器(无源电路)

LSE晶振是32.768kHz低速外部晶振或陶瓷谐振器,可作为实时时钟外设(RTC)的时钟源来提供时钟/日历或其他定时功能,LSE晶振具有功耗低且精度高的优点。
LSE晶振通过RCC备份域控制寄存器(RCC BDCR)中的LSEON位打开和关闭。通过检测RCC备份域控制寄存器中的LSERDY标志,可以知道L.SE晶振是否稳定。例如,在RCC时钟中断寄存器(RCC_CIR)中使能中断,LSE就可以产生中断请求。

2、外部时钟(有源电路)

此时内部LSE振荡电路被旁路,必须提供外部时钟源,最高频率不超过lMHz。此模式通过将RCC备份域控制寄存器中的LSEBYP和LSEON位置l进行选择。外部时钟必须使用占空比约为50%的外部时钟信号(方波、正弦波或三角波)来驱动OSC32_IN引脚,
同时OSC32_OUT引脚应保持为高阻态。
总结:

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(11)

5--LSI时钟

LSIRC振荡器可作为低功耗时钟源在停机和待机模式下保持运行,供独立看门狗IWDG)
和自动唤醒单元(AWU)使用。LSI时钟频率在32kHz左右。
LSIRC振荡器可通过RCC时钟控制和状态寄存器(RCC_CSR)中的LSION位打开或关闭。
RCC时钟控制和状态寄存器中的LSIRDY标志指示低速内部振荡器是否稳定。在启动时,硬件将此位置1后,LSI时钟才可以使用。若在RCC时钟中断寄存器中使能中断,则LSI就绪后可产生中断。

6--时钟输出功能

RCC共有两个微控制器时钟输出(MCO)引脚,

1.MCO1

用户可通过可配置的预分频器(1~5)向MCO1引脚(PA8)输出4个不同的时钟源:HSI
时钟、LSE时钟、HSE时钟、PLL时钟。用户所需的时钟源通过RCC时钟配置寄存器中的MCO1PRE[2:0]和MCO1[1:0]位选择。

2.MCO2

用户可通过可配置的预分频器(1~5)向MCO2引脚(PC9)输出4个不同的时钟源:HSE
时钟、PLL时钟、系统时钟、PLLI2S时钟。
用户所需的时钟源通过RCC时钟配置寄存器中的MCO2PRE[2:0]和MCO2位选择。对于不同的MCO引脚,必须将相应的GPIO端口在复用功能模式下进行设置。MCO输出时钟频率不得超过100MHz。
总结:

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(12)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(13)

PLL时钟系统配置步骤及常用库函数

在微控制器中的使用过程中,一般使用PLLCLK作为系统时钟,并选择HSE振荡器时钟作为PLL的输入参考时钟。

1--PLL时钟系统配置步骤

以使用HSE振荡器时钟作为PLL时钟源为例,PLL时钟系统的配置步骤如下。
(1)开启HSE振荡器,并等待HSE振荡器稳定。
如果当前微控制器正在使用PLLCLK作为系统时钟,则需要将系统时钟源切换到HSE振荡器时钟(或其他),然后关闭PLL;否则,在PLL运行期间,PLL不能配置成功。
(2)设置AHB、APB2、APB1的预分频系数。
(3)设置PLL的参数。
设置VCO输入时钟预分频系数M。
设置VCO输出时钟倍频系数N。
设置PLLCLK时钟预分频系数P。
设置OTG FS、SDIO、RNG时钟预分频系数Q。
PLLCLK输出频率计算公式:SYSCLK=(HSE×NMD/P。
(4)开启PLL,并等待PLL稳定。
(5)将PLLCLK切换为系统时钟。
(6)读取时钟切换状态位,确保PLLCLK被选为系统时钟。
在此过程涉及的寄存器有:RCC时钟控制寄存器[步骤(1)、(4)]、RCC PLL配置寄存器
[步骤(3)]、RCC时钟配置寄存器[步骤(2)、(5)、(6)]。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(14)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(15)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(16)

2--常用库函数

与RCC相关的函数和宏都被定义在以下两个文件中。
头文件:stm32f4xx_rcc.h。
源文件:stm32f4xx_rcc.c

1.时钟使能配置函数

控制片上外设时钟的使能或禁止,只有工作时钟被使能,片上外设才能工作。对于片上外设来讲,其初始化的第一步是时钟使能。片上外设的时钟信号大都来自AHB1、AHB2、APB1和APB2四条总线的时钟。涉及以下函数:
(1)AHB1总线片上外设时钟使能。

RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph FunctionalState NewState);

参数1:uint32_t RCC_AHB1Periph,时钟使能对象,以宏定义形式定义在stm32f4xx_rcc.h文件中。

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(17)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(18)


参数1:uint32.t RCC_AHB2Periph,时钟使能对象,以宏定义形式定义在 stm32f4xx rc.h文件中。

#define RCC_AHB2Periph_DCMI ((uint32_t)0x00000001) #define RCC_AHB2Periph_CRYP ((uint32_t)0x00000010) #define RCC_AHB2Periph_HASH ((uint32_t0)0x00000020) #define RCC_AHB2Periph_RNG ((uint32_t)0x00000040) #define RCC_AHB2Periph _OTG FS ((uint32_t)0x00000080)

操作的是RCC AHB2外设时钟使能寄存器(RCCAHB2ENR),功能同函数 RCC_AHBIPeriphClockCmd。
参数2:FunctionalState NewState,使能(ENABLE)或禁止(DISABLE)时钟。
例如,通过将RCC AHB2ENR的位6.置位,使能RNG的时钟。

RCC_ AHBIPeriphClockCmd (RCC_ AHB2Periph_RNG ENABLE);

RCC_APB1 PeriphClockCmd(uint32_t RCC_APB1Periph FunctionalState NewState);参数1:uint32 t RCC APB1Periph,时钟使能对象,以宏定义形式定义在stm32f4xx rcc.h文件中。

#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001) #define RCC_APBIPeriph_TIM3 ((uint32_t)0x00000002) #define RCC_APB1Periph_UART8 ((uint32_t)0x80000000)

操作的是RCC APB1外设时钟使能寄存器(RCC_APB1ENR),功能同函数RCC_AHB1PeriphClockCmd。
参数2:FunctionalState NewState,使能(ENABLE)或禁止(DISABLE)时钟。
例如,通过将RCC_APB1ENR的位0置位,使能TIM2的时钟。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 ENABLE);

(4)APB2总线片上外设时钟使能。

RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph FunctionalState NewState);

参数1:uint32_t RCC_ APB2Periph,时钟使能对象,以宏定义形式定义在stm32f4xx rcc.h文件中。

#define RCC_APB2Periph_ TIM1 ((uint32_t)0x00000001) #define RCC_APB2Periph_ TIM8 ((uint32_t)0x00000002) #define RCC_APB2Periph_LTDC ((uint32_t)0x04000000)

操作的是RCCAPB2外设时钟使能寄存器(RCC_APB2ENR),功能同函数
RCC_AHB1PeriphClockCmd。
参数2:FunctionalState NewState,使能(ENABLE)或禁止(DISABLE)时钟。
例如,通过将RCC_APB2ENR的位0置位,使能TIM1的时钟。

RCC_APB2PeriphClockCmd(RCC APB2Periph_ TIM1 ENABLE);2.配置系统时钟源函数

void RCC_SYSCLKConfig(uint32 t RCC_SYSCLKSource)

参数:uint32_t RCC_SYSCLKSource, 时钟源, 定义在 stm32f4xx_rcc.h 文件中。

#define RCC_SYSCLKSource_HSI ((uint32_t)0x00000000)
#define RCC_SYSCLKSource_HSE ((uint32_t)0x00000001)
#define RCC_SYSCLKSource_PLLCLK ((uint32_t)0x00000002)

后面还有不少,可以去查看数据手册。函数就不一一说明了,上面这部分理解了,剩下的接没啥问题了。
总结:

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(19)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(20)

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(21)

实例

STM32 时钟树(4-玩转STM32之STM32RCC时钟树)(22)

主函数main

int main(void) { u8 flag=0; delay_init(); //初始化延时函数 // LED 端口初始化 LED_Config(); /*初始化按键*/ Key_Config(); while (1) { if( Key_Scan(GPIOA GPIO_Pin_0) == KEY_ON ) { flag=~flag; if(flag) HSE_SetSysClock(25 180 2 9);//系统时钟切换到到90M,最高是216M else HSE_SetSysClock(25 360 2 9);//系统时钟切换到到180M,最高是216M } LED_ON ; // LED等亮 delay_ms(500); LED_OFF; // LED等灭 delay_ms(500); } }RCC_CLCK配置代码

#include "bsp_clkconfig.h" #include "stm32f4xx_rcc.h" void SetSysClock_HSE(uint32_t m uint32_t n uint32_t p uint32_t q) { __IO uint32_t HSEStartUpStatus = 0; /*-------------------第1步--------------------*/ RCC_HSEConfig(RCC_HSE_ON); // 使能HSE,开启外部晶振 HSEStartUpStatus = RCC_WaitForHSEStartUp();// 等待HSE启动稳定 if (HSEStartUpStatus == SUCCESS)//判断HSE是否启动成功,不成功的话,出错处理 { /*在程序运行中更改系统时钟的话需要先将时钟源切换到其他,并关闭PLL,再进行PLL配置*/ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); // 将系统时钟切换到HSE while (RCC_GetSYSCLKSource() != 0x04) // 判断HSE是否被选为系统时钟 { } RCC_PLLCmd(DISABLE);//禁止PLL /*-------------------第2步--------------------*/ RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK / 1 RCC_PCLK2Config(RCC_HCLK_Div2); // PCLK2 = HCLK / 2 RCC_PCLK1Config(RCC_HCLK_Div4); // PCLK1 = HCLK / 4 /*-------------------第3步--------------------*/ RCC_PLLConfig(RCC_PLLSource_HSE m n p q); // 配置PLL /*-------------------第4步--------------------*/ RCC_PLLCmd(ENABLE); // 使能PLL while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) // 等待 PLL稳定 { } /*--------开启 OVER-RIDE模式,以能达到更高频率---------*/ PWR->CR |= PWR_CR_ODEN; while((PWR->CSR & PWR_CSR_ODRDY) == 0) { } PWR->CR |= PWR_CR_ODSWEN; while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) { } /*--------配置FLASH预取指 指令缓存 数据缓存和等待状态---------*/ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; /*-------------------第5步--------------------*/ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //把PLL时钟切换为系统时钟 /*-------------------第6步--------------------*/ while (RCC_GetSYSCLKSource() != 0x08) //判断PLLCLK是否被选为系统时钟 { } } else // HSE启动出错处理 { while (1) { } } } /* * 使用HSI时,设置系统时钟的步骤 * 1、开启HSI ,并等待 HSI 稳定 * 2、设置 AHB、APB2、APB1的预分频因子 * 3、设置PLL的时钟来源 * 设置VCO输入时钟 分频因子 m * 设置VCO输出时钟 倍频因子 n * 设置SYSCLK时钟分频因子 p * 设置OTG FS SDIO RNG时钟分频因子 q * 4、开启PLL,并等待PLL稳定 * 5、把PLLCK切换为系统时钟SYSCLK * 6、读取时钟切换状态位,确保PLLCLK被选为系统时钟 */ /* * m: VCO输入时钟 分频因子,取值2~63 * n: VCO输出时钟 倍频因子,取值192~432 * p: PLLCLK时钟分频因子 ,取值2,4,6,8 * q: OTG FS SDIO RNG时钟分频因子,取值4~15 * 函数调用举例,使用HSI设置时钟 * SYSCLK=HCLK=180M PCLK2=HCLK/2=90M PCLK1=HCLK/4=45M * HSI_SetSysClock(16 360 2 7); * HSE作为时钟来源,经过PLL倍频作为系统时钟,这是通常的做法 * 系统时钟超频到216M爽一下 * HSI_SetSysClock(16 432 2 9); */ void HSI_SetSysClock(uint32_t m uint32_t n uint32_t p uint32_t q) { __IO uint32_t HSIStartUpStatus = 0; // 把RCC外设初始化成复位状态 RCC_DeInit(); //使能HSI HSI=16M RCC_HSICmd(ENABLE); // 等待 HSI 就绪 HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY; // 只有 HSI就绪之后则继续往下执行 if (HSIStartUpStatus == RCC_CR_HSIRDY) { // 调压器电压输出级别配置为1,以便在器件为最大频率 // 工作时使性能和功耗实现平衡 RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; // HCLK = SYSCLK / 1 RCC_HCLKConfig(RCC_SYSCLK_Div1); // PCLK2 = HCLK / 2 RCC_PCLK2Config(RCC_HCLK_Div2); // PCLK1 = HCLK / 4 RCC_PCLK1Config(RCC_HCLK_Div4); // 如果要超频就得在这里下手啦 // 设置PLL来源时钟,设置VCO分频因子m,设置VCO倍频因子n, // 设置系统时钟分频因子p,设置OTG FS SDIO RNG分频因子q RCC_PLLConfig(RCC_PLLSource_HSI m n p q); // 使能PLL RCC_PLLCmd(ENABLE); // 等待 PLL稳定 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } /*-----------------------------------------------------*/ //开启 OVER-RIDE模式,以能达到更高频率 PWR->CR |= PWR_CR_ODEN; while((PWR->CSR & PWR_CSR_ODRDY) == 0) { } PWR->CR |= PWR_CR_ODSWEN; while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) { } // 配置FLASH预取指 指令缓存 数据缓存和等待状态 FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; /*-----------------------------------------------------*/ // 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 读取时钟切换状态位,确保PLLCLK被选为系统时钟 while (RCC_GetSYSCLKSource() != 0x08) { } } else { // HSI启动出错处理 while (1) { } } } // MCO1 PA8 GPIO 初始化 void MCO1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ENABLE); // MCO1 GPIO 配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA &GPIO_InitStructure); } // MCO2 PC9 GPIO 初始化 void MCO2_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC ENABLE); // MCO2 GPIO 配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC &GPIO_InitStructure); }按键

#include "bsp_key.h" #include "delay.h" /** * @brief 配置按键用到的I/O口 * @param 无 * @retval 无 */ void Key_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /*开启按键GPIO口的时钟*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ENABLE); /*选择按键的引脚*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; /*设置引脚为输入模式*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; /*设置引脚不上拉也不下拉*/ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /*使用上面的结构体初始化按键*/ GPIO_Init(GPIOA &GPIO_InitStructure); } /** * @brief 检测是否有按键按下 * @param1 GPIO_TypeDef* GPIOx: 具体的端口 x可以是(A...K) * @param2 uint16_t GPIO_Pin : 具体的端口位, 可以是GPIO_PIN_x(x可以是0...15) * @param3 uint8_t Key_Lvl : 按键的有效电平,‘0’表示低电平有效,‘1’表示高电平有效 * @retval 按键的状态 * @arg KEY_ON:按键按下 * @arg KEY_OFF:按键没按下 */ uint8_t Key_Scan(GPIO_TypeDef* GPIOx uint16_t GPIO_Pin uint8_t Key_Lvl) { /*检测是否有按键按下 */ if(GPIO_ReadInputDataBit(GPIOx GPIO_Pin) == Key_Lvl ) //第一次检测有效电平 { delay_ms(10);//去抖动 if(GPIO_ReadInputDataBit(GPIOx GPIO_Pin) == Key_Lvl) //第二次检测有效电平 return KEY_ON;//确认有效按键动作返回 else return KEY_OFF;//无有效按键动作返回 } else return KEY_OFF; //无有效按键动作返回 } /*********************************************END OF FILE**********************/

猜您喜欢: