MSP430F5529学习笔记(4)——按键点灯

MSP430F5529学习笔记(3)——实现LED闪烁和呼吸灯独立按键工作原理

目录

按键扫描

原理图分析

写程序,按下s1点亮LED1

1,首先我们需要告诉单片机,P2.1是输入还是输出

 2,配置IO是否允许上下拉

 3,配置IO是上拉还是下拉

 4,检测当前电平

5,按键消抖

6,实操

 写程序——按下s1点亮LED1,按下s2点亮LED2

&,|,~简单介绍

只操作一个bit让其为高电平

只操作一个bit让其为低电平

实操

总结

位操作

PxDIR,PxIN,PxOUT,PxREN 

输出

初始化

输出电平

输入

初始化

电平检测


按键扫描

原理图分析

首先我们先查看LED的原理图,按ctrl+f查找——>输入LED1,即可找到LED部分的原理图。User LEDs是LED的电路图,User Buttons是按键的电路图。

首先LED之前说过(MSP430F5529学习笔记(2)——点亮LED),LED高电平灯亮,低电平灯灭。 

现在我们来看按键的,我们明显看到,P2.1是连接GND的。表明如果当我按下s1,P2.1会变成低电平。于是我们可以将P2.1设置为上拉输入,空闲状态为高点平。按下P2.1之后,IO为低电平。

写程序,按下s1点亮LED1

现在我们要做的是,按下s1,P2.1为低电平。我们检测P2.1脚,如果P2.1脚为低电平,LED1亮。P2.1为高电平,LED1灭

1,首先我们需要告诉单片机,P2.1是输入还是输出

我们看数据手册,前几张博客也说了。如果P2DIR为高电平表示输入,P2DIR为低电平表示输出。

 2,配置IO是否允许上下拉

我们看数据手册可以知道,他需要配置一个PxREN的寄存器,来确认IO是否可以上下拉。很明显我们需要将IO进行上拉

 3,配置IO是上拉还是下拉

因为此处是输入,所以我们只需要看下面的IO输入部分。我们知道,bit=1为上拉输入。所以我们要将PxOUT的bit设置为1。

 4,检测当前电平

因为我们知道P2.1为低电平表示按键被按下,所以我们需要一个检测电平的寄存器。PxIN就是用于检测高低电平的。需要注意的一点是 ,PxIN只能用于读,不能写入

5,按键消抖

独立按键工作原理

我们都知道按键按下是会有抖动的,而这个抖动时间一般位5~20ms,而且我们人手按下按键一般都是零点几秒,甚至几秒,不可能做到20ms按下再松开。所以我们就可以延时20ms跳过抖动时间重新电平是否为0,如果电平为0,则按键被按下。同时加一个while等待松开按键。

        if((P2IN &(0x01<<1))==0x00) //如果P2.1为低电平
        {
            delay_ms(20);
            P1OUT=0x01<<0;
            while((P2IN &(0x01<<1))==0x00);
        }

6,实操

#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))



/**
 * main.c
 */

void main()
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    /****配置LED****/
    //P1.0为输出
    P1DIR = 0x01<<0;

    /****配置按键****/
    //P2.1为输入
    P2DIR = 0x00;
    //开启P2.1的上下拉
    P2REN = 0x02;
    //P2.1都为上拉输入
    P2OUT = 0x02;
    while(1)
    {
        if((P2IN &(0x01<<1))==0x00) //如果P2.1为低电平
        {
            delay_ms(20);
            P1OUT = 0x01;
            while((P2IN &(0x01<<1))==0x00);
        }
        else
            P1OUT =0x00;

    }
}

 写程序——按下s1点亮LED1,按下s2点亮LED2

让按下s1点亮LED1很简单,因为他们s1是P2.1口,LED1是P1.0口。但是我们看板子上面,s2是P1.1口,与LED1有所冲突,他们都是P1口。写程序肯定麻烦一点。

这个时候我们就要又&|的概念了。

&,|,~简单介绍

&,就是有0出0。比如说,0010&0110,结果为0010。

|,就是有1出1(如果记不住,可以记着|长得像1,所以是有1出1)。比如说,0010|0110,结果为0110。

~,就说有1出0,有0出1。~0101,结果为1010。

只操作一个bit让其为高电平

既然我们知道了&和|的作用之后。我们想让P1.0为输出可以这样写。

这样写我们就只会改变P1.0引脚,其他引脚没有变化
P1DIR |= (0x01<<0);

如果那么无法理解,那我就先假设P1DIR=0x40;  0100 0000,如果我们需要在这里将P1.0为输出。不能写成P1DIR=0x01;那样P1.6会从输出变为输入

0100 0000|(0x01<<0),那么就是0100 0000 | 0000 0001。结果为0100 00001。

只操作一个bit让其为低电平

假如我现在想让P1.0为低电平。还是假设P1DIR=0x40;  0100 0000

P1DIR &= ~(0x01<<0);
0100 0000 & 1111 1110
——>0100 0000

 现在我们就能够将P1.0随意变成输出或者输入,其他引脚也不会受到改变。

很多时候我们都知道这个原理,但是写出来可能就忘了。想要记住也简单,就是&1,|0

实操

我们知道&和|之后,就可以实操了。具体自己看,我懒得啰嗦了。

记住&=~,表示让指定引脚为低电平, |=表示让指定引脚为高电平

#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))



/**
 * main.c
 */

void main()
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    /****配置LED****/
    //P1.0和P4.7为输出
    P1DIR |= (0x01<<0);
    P4DIR |= (0x01<<7);

    /****配置按键****/
    //P2.1和P1.1为输入
    P2DIR &= ~(0x01<<1);
    P1DIR &= ~(0x01<<1);
    //开启P2.1和P1.1的上下拉
    P2REN |= (0x01<<1);
    P1REN |= (0x01<<1);
    //P2.1和P1.1都为上拉输入
    P2OUT |= (0x01<<1);
    P1OUT |= (0x01<<1);
    while(1)
    {
        if((P2IN &(0x01<<1))==0x00) //如果P2.1为低电平
        {
            delay_ms(20);
            P1OUT|=(0x01<<0);
            while((P2IN &(0x01<<1))==0x00);
        }
        else
            P1OUT&=~(0x01<<0);
        if((P1IN &(0x01<<1))==0x00) //如果P1.1为低电平
        {
            delay_ms(20);
            P4OUT|=(0x01<<7);
            while((P1IN &(0x01<<1))==0x00);
        }
        else
            P4OUT&=~(0x01<<7);
    }
}

总结

位操作

&=~为0,|=为1

如果我们想让某一个引脚为1,就使用&=~。如果想让他为0就使用|=

P1OUT|=(0x01<<0);  //P1.0输出高电平
P1OUT&=~(0x01<<0); //P1.0输出低电平

PxDIR,PxIN,PxOUT,PxREN 

输出

初始化

输出的初始化,只需要配置一个PxDIR即可。

 P1DIR |= (0x01<<0);  //P1.0为输出

输出电平

利用 PxOUT输出高电平还是低电平

P1OUT|=(0x01<<0);  //P1.0输出高电平
P1OUT&=~(0x01<<0); //P1.0输出低电平

输入

初始化

输入需要匹配PxDIR,PxREN,PxOUT。

(1)先配置PxDIR

 P2DIR &= ~(0x01<<1);  //P2.1为输入

(2)再配置PxREN

P2REN |= (0x01<<1);  //开启P2.1的上下拉

(3)先配置PxOUT

P2OUT |= (0x01<<1);  //P2.1为上拉输入

电平检测

PxIN,只可读取,不能修改。如果bit为0表示检测到低电平,bit为1,表示检测到高电平。

if((P2IN &(0x01<<1))==0x00) //如果P2.1为低电平
    P1OUT|=(0x01<<0);
else                        //如果P2.1为高电平
    P1OUT&=~(0x01<<0);

  • 16
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风正豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值