轻触按键在单片机中的使用

目录

前言

消抖流程

实现代码

初始化定时器

每1ms扫描一次按键

按键计数触发

短按的拓展

长按

长按的拓展

拓展按键

其他

最终代码

最后


前言

        按键是许多单片机初学者必学的元件,按键的驱动程序中,消抖是很重要的一个部分,网上许多教程的按键消抖思路如图所示:

        根据这个思路,这些教程给出的程序写法大概如下所示:

sbit Button0 = P1^0;

void main()
{
    while(1)
    {
        if(Button == 0)
        {
            delay_ms(50);
            if(Button0 == 0)
            {
                printf("Button pressed!");
            }
        }
    }
}

        其中delay_ms(50)函数起延时消抖作用,咋一看好像没什么问题,但是,问题就出现在这个地方。且看,在程序中,当按键按下的时候,程序就停留在delay_ms函数中,单纯地做加减法运算,最终实现延时50ms的目的,而对于其他的事情呢,在这50ms内单片机一概不管。要知道50ms对于单片机来说是可以执行很多任务的,这样的程序在简单的项目里倒没什么,但是在复杂的项目里,它的缺点就特别明显。

        这么说来读者或许感觉不是特别深刻,我举个例子。对许多初学者来说,数码管也早就有所了解,数码管的使用中有动态数码管这种显示方法,倘若将动态数码管与按键结合使用,以上我所描述的情况即会出现,读者不妨尝试尝试。(仅对初学者而言昂,用其他方法规避这个问题当我没说)。

        不知读者是否已经体会到了?那么今天我就是为解决这个问题而来的。

消抖流程

        首先上面展示的消抖思路是没问题的,只是实现的过程出现了问题,根据上面的思路以及一些例程,我为读者提供了一种实现方法:

        额……读者可能看不明白,但是不要慌,我解读一下。在整个流程里,单片机每1ms检测一次按键是否按下,当连续50次(50ms)检测到按键按下时,触发按键程序,其余时间段的则执行其他程序(除按键以外的程序)。

        同样是实现50ms的延时消抖,但是与之前不同的是,在这50ms里,单片机并没有停留在这个地方,而是在执行其他程序,直到50ms达到,执行按键程序。(读者应该能get到意思吧?不懂的评论区留言)

实现代码

        根据以上的思路,接下来来看代码的实现,我将一步步搭建程序的框架,直接使用的读者可直接跳到后面获取最终程序。需要说明的是,以下的代码是在STC8H8K64U单片机中实现的,不同的单片机代码会有些许差异,但是整体的实现思路是一样的。

初始化定时器

        要达到流程图中的效果,硬核延时是难以实现的,但好在单片机有定时器,我们可以利用定时器来实现每1ms扫描一次按键,只需设置一个1ms的定时器中断即可。

#include<stc8h.h>

extern bit button0ScanBit_ms;    //外部变量声明(来自按键程序)

#define FOSC	24000000UL    //系统时钟频率,24MHz

#define TIMER4_US	1000U    //中断时间(单位:us)

//初始化定时器4
void TIMER4_Init()
{
	T4T3M &= ~(0x01 << 4);
	T4T3M |= (0x01 << 5);
//	T4T3M &= ~(0x01 << 5);
	T4T3M &= ~(0x01 << 6);
	TM4PS = 0;
	
	if((T4T3M >> 5) & 0x01)
	{
		T4H = (65536 - FOSC/1000000UL/(TM4PS + 1) *TIMER4_US) >> 8;
		T4L = (65536 - FOSC/1000000UL/(TM4PS + 1) *TIMER4_US) & 0xff;
	}
	else
	{
		T4H = (65536 - FOSC/1000000UL/(TM4PS + 1) *TIMER4_US/12) >> 8;
		T4L = (65536 - FOSC/1000000UL/(TM4PS + 1) *TIMER4_US/12) & 0xff;
	}

	T4T3M |= (0x01 << 7);
	IE2 |= (0x01 << 6);
	EA = 1;
}

//每TIMER4_US进入一次中断
void TIMER4_Interrupt() interrupt 20
{
	button0ScanBit_ms = 1;
}

        定时器的初始化函数写法来自单片机数据手册,不是本次的重点,不作过多介绍。这里读者只需要注意到定时器每过1ms(1000us)进入中断函数将变量button0ScanBit_ms 置1。

每1ms扫描一次按键

       在搭建出按键的扫描框架之前,我们先来规划一下按键的状态,按键的状态,有未按下、短按、长按、双击等等。在本次的讲解中,我只讲述短按和长按的实现,其余的读者自行发挥。

        下面我用一个枚举类型将这些状态罗列出来:

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

        接下来把扫描的框架搭建出来:

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)
        {

        }
        else
        {

        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {

        }
        else if(buttonResult == ButtonState_Long)
        {

        }
    }
}

按键计数触发

        在扫描到按键按下时,就应该开始计数了,当计数达到预定值就就表示按键真的按下了,而如果检测到按键并未按下,那么就要清空计数器。

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

#define BUTTON_TRIGGER_NUM 50	//扫描到按键按下BUTTON_TRIGGER_NUM次时,触发短按

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {
            printf("Button0 Short Pressed!\r\n");
        }
        else if(buttonResult == ButtonState_Long)
        {

        }
    }
}

短按的拓展

        上面的的程序算是已经实现了我们想要的功能,但先别急,读者在使用的时候应该能感觉出来,按键一按下的时候就疯狂地触发短按,如果遇到那种按一次触发一次的该作何解?下面我为按键添加了一个标志,表示在本次按下按键之后触发过的状态,如果触发过短按,记录一次,直到按键抬起才清除该标志。

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

#define BUTTON_TRIGGER_NUM 50	//扫描到按键按下BUTTON_TRIGGER_NUM次时,触发短按

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static ButtonState xdata button_PastState = ButtonState_No;	//在按键触发后已经返回过的按键状态(主要用于不要重复返回)
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;

                {
                    if(button_PastState == ButtonState_No)	//在本次按键按下之后是否已经返回过短按状态
                    {
                        button_PastState = ButtonState_Short;	//否
                    }
                    else
                    {
                        button_NowState = ButtonState_No;    //是,清除状态,避免重复返回
                    }
                }
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
            button_PastState = ButtonState_No;
        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {
            printf("Button0 Short Pressed!\r\n");
        }
        else if(buttonResult == ButtonState_Long)
        {

        }
    }
}

        这样下来,按键算是实现了。慢着!前面我还说个一个长按的状态,下面将为读者展示。

长按

        按键的长按,可以理解成很多次的短按累计而成的,因此在函数中还需要引入一个变量来记录触发短按的次数,达到一定数量之后触发长按。

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

#define BUTTON_TRIGGER_NUM 50	//扫描到按键按下BUTTON_TRIGGER_NUM次时,触发短按
#define BUTTON_LONG_S 3			//长按时间(单位:s)

const unsigned char xdata BUTTON_LTRIGGER_NUM = TIMER4_US/BUTTON_TRIGGER_NUM *BUTTON_LONG_S;	//扫描到多少次短按之后代表长按

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static ButtonState xdata button_PastState = ButtonState_No;	//在按键触发后已经返回过的按键状态(主要用于不要重复返回)
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;

                {
                    if(button_PastState == ButtonState_No)	//在本次按键按下之后是否已经返回过短按状态
                    {
                        button_PastState = ButtonState_Short;	//否
                    }
                    else
                    {
                        button_NowState = ButtonState_No;    //是,清除状态,避免重复返回
                    }

					if(button_LongCounter < BUTTON_LTRIGGER_NUM)
					{
						button_LongCounter++;	//短按累计次数未达到预定值
					}
					else	//短按累计次数达到预定值
					{
						button_NowState = ButtonState_Long;		//触发长按
					}
                }
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
            button_PastState = ButtonState_No;
			button_LongCounter = 0;
        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {
            printf("Button0 Short Pressed!\r\n");
        }
        else if(buttonResult == ButtonState_Long)
        {
            printf("Button0 Long Pressed!\r\n");
        }
    }
}

长按的拓展

        在长按的程序中,同样面临着疯狂触发的情况,这一点的处理方法跟短按是一样的。

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

#define BUTTON_TRIGGER_NUM 50	//扫描到按键按下BUTTON_TRIGGER_NUM次时,触发短按
#define BUTTON_LONG_S 3			//长按时间(单位:s)

const unsigned char xdata BUTTON_LTRIGGER_NUM = TIMER4_US/BUTTON_TRIGGER_NUM *BUTTON_LONG_S;	//扫描到多少次短按之后代表长按

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static ButtonState xdata button_PastState = ButtonState_No;	//在按键触发后已经返回过的按键状态(主要用于不要重复返回)
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;

                {
                    if(button_PastState == ButtonState_No)	//在本次按键按下之后是否已经返回过短按状态
                    {
                        button_PastState = ButtonState_Short;	//否
                    }
                    else
                    {
                        button_NowState = ButtonState_No;    //是,清除状态,避免重复返回
                    }

					if(button_LongCounter < BUTTON_LTRIGGER_NUM)
					{
						button_LongCounter++;	//短按累计次数未达到预定值
					}
					else	//短按累计次数达到预定值
					{
						button_NowState = ButtonState_Long;		//触发长按

						if(button_PastState != ButtonState_Long)	//在本次按键按下之后是否已经返回过长按状态
						{
							button_PastState = ButtonState_Long;	//否
						}
						else
						{
							button_NowState = ButtonState_No;		//是,(返回过长按必定返回过短按,根据实际情况确定是否要避免重复返回长按状态)
						}
					}
                }
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
            button_PastState = ButtonState_No;
			button_LongCounter = 0;
        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {
            printf("Button0 Short Pressed!\r\n");
        }
        else if(buttonResult == ButtonState_Long)
        {
            printf("Button0 Long Pressed!\r\n");
        }
    }
}

        在程序里,读者可能对常变量BUTTON_LTRIGGER_NUM和宏定义BUTTON_LONG_S有所疑惑,这里其实是将比较的次数转换成了时间,因为我们对长按一般都习惯说长按多少秒。

拓展按键

        在实际的应用中,我们面对的可能并不是一个按键,而是多个按键,这就需要将按键拓展加以应用,而我上面所写的程序对于拓展按键也是十分方便的,假设我现在要拓展按键1,只需要添加一个bit变量,并到定时器中断中加入这个变量,然后将按键0的程序复制粘贴,最后把关于Button0的全改成Button1即可。(是不是很简单?)

//每TIMER4_US进入一次中断
void TIMER4_Interrupt() interrupt 20
{
	button0ScanBit_ms = 1;
	button1ScanBit_ms = 1;
}
bit button1ScanBit_ms = 0;

sbit Button1 = P1^1;

//Button1
ButtonState BUTTON_Button1Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static ButtonState xdata button_PastState = ButtonState_No;	//在按键触发后已经返回过的按键状态(主要用于不要重复返回)
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button1ScanBit_ms == 1)
    {
        button1ScanBit_ms = 0;

        if(Button1 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;

                {
                    if(button_PastState == ButtonState_No)	//在本次按键按下之后是否已经返回过短按状态
                    {
                        button_PastState = ButtonState_Short;	//否
                    }
                    else
                    {
                        button_NowState = ButtonState_No;    //是,清除状态,避免重复返回
                    }

					if(button_LongCounter < BUTTON_LTRIGGER_NUM)
					{
						button_LongCounter++;	//短按累计次数未达到预定值
					}
					else	//短按累计次数达到预定值
					{
						button_NowState = ButtonState_Long;		//触发长按

						if(button_PastState != ButtonState_Long)	//在本次按键按下之后是否已经返回过长按状态
						{
							button_PastState = ButtonState_Long;	//否
						}
						else
						{
							button_NowState = ButtonState_No;		//是,(返回过长按必定返回过短按,根据实际情况确定是否要避免重复返回长按状态)
						}
					}
                }
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
            button_PastState = ButtonState_No;
			button_LongCounter = 0;
        }
    }

    return button_NowState;
}

其他

        在main函数中还有一个函数——BUTTON_Init(),这其实是因为STC8H8K64U单片机配置的原因,在这函数里面我将按键配置为高阻输入并使能上拉电阻,读者使用的单片机根据实际情况配置即可。

最终代码

#include<stc8h.h>

bit button0ScanBit_ms = 0;		//按键扫描标志位,每1ms扫描一次

typedef enum
{
	ButtonState_No,        //无按下
	ButtonState_Short,    //短按
	ButtonState_Long     //长按
}ButtonState;           //按键扫描结果

#define BUTTON_PUSHED 0			//按键按下的电平
#define BUTTON_NOPUSH !BUTTON_PUSHED

#define BUTTON_TRIGGER_NUM 50	//扫描到按键按下BUTTON_TRIGGER_NUM次时,触发短按
#define BUTTON_LONG_S 3			//长按时间(单位:s)

const unsigned char xdata BUTTON_LTRIGGER_NUM = TIMER4_US/BUTTON_TRIGGER_NUM *BUTTON_LONG_S;	//扫描到多少次短按之后代表长按

sbit Button0 = P1^0;

//Button0
ButtonState BUTTON_Button0Scan()
{
    ButtonState xdata button_NowState = ButtonState_No;    //按键当下的状态
    static ButtonState xdata button_PastState = ButtonState_No;	//在按键触发后已经返回过的按键状态(主要用于不要重复返回)
    static unsigned char xdata button_Counter = 0;    //按键扫描次数(次数达到BUTTON_TRIGGER_NUM后,触发短按)

	if(button0ScanBit_ms == 1)
    {
        button0ScanBit_ms = 0;

        if(Button0 == BUTTON_PUSHED)    //按键按下
        {
            button_Counter++;
            if(button_Counter > BUTTON_TRIGGER_NUM)    //计数到达,按键真的按下了
            {
                button_Counter = 0;

                button_NowState = ButtonState_Short;

                {
                    if(button_PastState == ButtonState_No)	//在本次按键按下之后是否已经返回过短按状态
                    {
                        button_PastState = ButtonState_Short;	//否
                    }
                    else
                    {
                        button_NowState = ButtonState_No;    //是,清除状态,避免重复返回
                    }

					if(button_LongCounter < BUTTON_LTRIGGER_NUM)
					{
						button_LongCounter++;	//短按累计次数未达到预定值
					}
					else	//短按累计次数达到预定值
					{
						button_NowState = ButtonState_Long;		//触发长按

						if(button_PastState != ButtonState_Long)	//在本次按键按下之后是否已经返回过长按状态
						{
							button_PastState = ButtonState_Long;	//否
						}
						else
						{
							button_NowState = ButtonState_No;		//是,(返回过长按必定返回过短按,根据实际情况确定是否要避免重复返回长按状态)
						}
					}
                }
            }
        }
        else    //按键未按下
        {
            button_NowState = ButtonState_No;
            button_Counter = 0;
            button_PastState = ButtonState_No;
			button_LongCounter = 0;
        }
    }

    return button_NowState;
}

void main()
{
    ButtonState buttonResult;

    TIMER4_Init();
    BUTTON_Init();

    while(1)
    {
        buttonResult = BUTTON_Button0Scan();
        if(buttonResult == ButtonState_Short)
        {
            printf("Button0 Short Pressed!\r\n");
        }
        else if(buttonResult == ButtonState_Long)
        {
            printf("Button0 Long Pressed!\r\n");
        }
    }
}

最后

        该按键程序是我在实际开发中而来的,或许读者所遇到的情况与我遇到的不一样,所以希望读者能根据实际情况进行应用。由于个人的水平实在有限,如有错误或改进之处,请赐教。如读者在文章中有所疑问,欢迎评论区留言!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
1 1 1 产品简介 1.1 功能特性  产品性能列表 定时器 单片机名称 ROM RAM 堆栈 T0 TC0 TC1 T1 SIO MSP I/O 比较器 PWM 唤醒功能 引脚数目 封装形式 SN8P2522 2K*16 128 8 V V V V V - 16 8-ch 2 9 DIP18/SOP18/ SSOP20 SN8P2523 2K*16 256 8 V - V - V V 22 12-ch 8+1 14 SKDIP24/SOP24 /SSOP28 SN8P25231 2K*16 256 8 V - V - V V 16 8-ch 2+1 12 DIP18/SOP18/ SSOP20  存储器配置  1 个 8位基本定时器 T0 ROM:2K * 16 位。  1 个 8位定时器,具有占空比/周期可编程控制的 PWM 功能 RAM:256 * 8 位。  8 通道 LED PWM驱动  8 层堆栈缓存器  12 通道比较器  6 个断源  SIO 串行输入/输出接口 5 个内部断:T0,TC1,CM0,SIO,MSP。  MSP从动模式接口 1 个外部断:INT0。  内置看门狗定时器,时钟源由内部低速 RC时钟提供 (16KHz @3V, 32KHz @5V)  I/O 引脚配置 双向输入输出端口:P0,P1,P5。 具有唤醒功能的端口:P0,P1 电平变换。  2 种系统时钟 具有上拉电阻的端口:P0,P1,P5。 内部高速时钟:RC,16MHz。 可编程的开漏引脚:P5.0~P5.2。 内部低速时钟:RC,16KHz(3V),32KHz(5V)。 比较器输入引脚:CM0N0~CM0N11。 比较器输出引脚:CM0O。  4 种工作模式 普通模式:高低速时钟正常工作。  Fcpu(指令周期) 低速模式:仅低速时钟工作。 Fcpu = Fpsc/1,Fpsc/2,Fosc/4,Fosc/8,Fosc/16。 睡眠模式:高低速时钟都停止工作。 绿色模式:由定时器周期性的唤醒。  功能强大的指令集 指令的长度为 1个字长。  封装形式 大多数指令只需要一个周期。 SKDIP 24 pin JMP/CALL 指令可寻址整个 ROM区。 SOP 24 pin 查表指令 MOVC 可寻址整个 ROM区。 SSOP 28 pin

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值