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

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

按键扫描

原理图分析

首先我们先查看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);
    }
}


总结

位操作

&=~为1,|=为0

如果我们想让某一个引脚为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);
目录
相关文章
|
5月前
stm32f407探索者开发板(十九)——外部中断实验-EXIT
stm32f407探索者开发板(十九)——外部中断实验-EXIT
352 0
|
5月前
stm32f407探索者开发板(十五)——NVIC中断优先级管理
stm32f407探索者开发板(十五)——NVIC中断优先级管理
254 0
|
5月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
428 0
|
7月前
|
Linux 芯片 Ubuntu
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
|
7月前
|
IDE 开发工具 C++
【瑞萨MCU】玩转 RA2E1 之 e2 studio 点灯
【瑞萨MCU】玩转 RA2E1 之 e2 studio 点灯
101 0
|
7月前
|
IDE 物联网 开发工具
【瑞萨MCU】玩转 HMI-Board 之 MDK + RASC 点灯
【瑞萨MCU】玩转 HMI-Board 之 MDK + RASC 点灯
|
网络协议 网络架构
实验:MSP430F249 按键控制四个灯,并消抖
实验:MSP430F249 按键控制四个灯,并消抖
131 0
野火RA6M5开发板 IIC-OLED测试学习
野火RA6M5开发板 IIC-OLED测试学习
103 0
野火RA6M5开发板 IIC-OLED测试学习