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

2023-11-01

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);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MSP430F5529学习笔记(4)——按键点灯 的相关文章

  • 开关电容转换器的合成器研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码实现
  • 139-基于stm32单片机老人居家监护报警系统Proteus仿真+源程序

    资料编号 139 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 MQ4传感器 电位器模拟 MQ2传感器 电位器模拟 蜂鸣器 电机 制作一个基于stm32单片机老人居家监护报警系统Proteus仿真 2 通过MQ2传
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 138-基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真+源程序

    资料编号 138 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 LED灯 蜂鸣器 电位器 制作一个基于stm32单片机汽车多功能仪表盘显示系统Proteus仿真 2 通过DHT1
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • rt-thread studio中新建5.0不能用

    文章目录 一 版本对比 二 文件和文件夹打斜杠 在使用RT Thread studio创建新工程5 0版本的时候 结果发现新建完成之后程序不能正常运行 但是创建4 10版本的时候却能运行 那肯定是新版本出现了BUG 一 版本对比 首先对比了
  • java——网络编程

    1 网络编程 理解 1 网络编程 用Java语言实现计算机间数据的信息传递和资源共享 2 网络编程模型 3 网络编程的三要素 A IP地址 a 点分十进制 b IP地址的组成 c IP地址的分类 d dos命令 e InetAddress
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • 关于DC电源模块有哪些常见的输入和输出参数?

    关于DC电源模块有哪些常见的输入和输出参数 BOSHIDA DC电源模块是一种用于将交流电转换为直流电的设备 广泛应用于电子设备 通信设备 工业控制 仪器仪表等各个领域 在选择和使用DC电源模块时 了解其常见的输入和输出参数是很重要的 输入
  • Java的引用类型有几种?区别是什么?

    nbsp Java的引用类型有几种 区别是什么 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Java的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评论区回复 888 之后私信回复
  • Java语言真的跌落神坛了吗?

    Java语言真的跌落神坛了吗 在开始前我有一些资料 是我根据自己从业十年经验 熬夜搞了几个通宵 精心整理了一份 Java的资料从专业入门到高级教程 工具包 点个关注 全部无偿共享给大家 在评论区回复 888 之后私信回复 888 即可拿走
  • I.MX RT1170双核学习(4):FreeRTOS之消息缓冲区(Message Buffer)双核通信详解

    对于RT1170来说 它有两个内核 那两个内核如何通信呢 我们可以通过 MU消息单元详解 来实现这些功能 但它一次只能传输32位的数据 我们知道CM7和CM4有一些公共的内存可以访问 那我们可不可以借助这些公共的内存来实现数据的交互呢 答案
  • 【雕爷学编程】Arduino智慧农业之养殖水质监测与控制

    Arduino是一个开放源码的电子原型平台 它可以让你用简单的硬件和软件来创建各种互动的项目 Arduino的核心是一个微控制器板 它可以通过一系列的引脚来连接各种传感器 执行器 显示器等外部设备 Arduino的编程是基于C C 语言的
  • 最新51单片机毕业设计项目集合

    文章目录 1前言 2 STM32 毕设课题 3 如何选题 3 1 不要给自己挖坑 3 2 难度把控 3 3 如何命名题目 4 最后 1前言 更新单片机嵌入式选题后 不少学弟学妹催学长更新STM32和C51选题系
  • 基于单片机设计的电子指南针(LSM303DLH模块(三轴磁场 + 三轴加速度)

    一 前言 本项目是基于单片机设计的电子指南针 主要利用STC89C52作为主控芯片和LSM303DLH模块作为指南针模块 通过LCD1602液晶显示屏来展示检测到的指南针信息 在日常生活中 指南针是一种非常实用的工具 可以帮助我们确定方向
  • 串口流控(CTS/RTS)使用详解

    1 流控概念 在两个设备正常通信时 由于处理速度不同 就存在这样一个问题 有的快 有的慢 在某些情况下 就可能导致丢失数据的情况 如台式机与单片机之间的通讯 接收端数据缓冲区已满 则此时继续发送来的数据就会丢失 流控制能解决这个问题 当接收
  • 世微AP9196 DC-DC 升压恒流电源管理芯 电解水驱动电源应用线路

    AP9196 是一系列外围电路简洁的宽调光比升压调光恒流驱动器 适用于 3 40V 输入电压范围的 LED照明领域 AP9196 采用我司专利算法 可以实现高精度的恒流效果 输出电流恒流精度 3 电压工作范围为5 40V 可以轻松满足锂电池
  • 会stm32有机会进大公司吗?

    今日话题 会stm32有机会进大公司吗 我本科期间参与了飞思卡尔和电赛等比赛 使用过多种单片机 但渐渐发现单片机只是其中的一小部分 不要过分迷恋所谓的单片机基础和技巧 更值得深入研究的是C语言 如果你对此感兴趣 我愿意无偿分享一个资源包 其
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前

随机推荐