历史上的今天
返回首页

历史上的今天

今天是:2025年07月21日(星期一)

正在发生

2018年07月21日 | STM32学习笔记之按键查询方式控制led灯的亮灭

2018-07-21 来源:eefocus

        其实接触STM32已经快半年了,端断续续的也学习了一下的STM32的各个模块的基本功能,刚开始的时候也是看比人的写的代码,看懂了然后再去修改,能够在自己的平台上实现基本的功能,也就是到现在才能真正的按照自己的想法来实现写功能,在本文中我将介绍下比较经典的按键驱动程序的实现方式--查询,当然中断方式的应用也比较广泛,在此先不做介绍了。

     首先我的硬件平台是奋斗版STM32,之所以选择这款开发版是因为板子提供了许多关于ucos和ucgui的例程,想往这方面发展的童鞋可以考虑哦,呵呵,不多说了,开发板带的芯片型号是STM32F103VET6: 64K 片内SRAM,512K 片内FALSH.

     本文所用到的外设:3个led以及4个按键,基本功能就是开发板上电3个led点亮,按下按键1时led灭,按下按键2时led2熄灭,按下按键3时led3熄灭,通过查询方式来获取键值

     接口设置情况:led灯: V6-PB5--LED1
                                            V7-PD6--LED2
                                            V8-PD3--LED3

                                 按键:K1--PC5
                                            K2--PC2
                                            K3--PC3
                                            K4--PE6  

函数部分:首先是主函数:

int main(void)
{
                 TYPEDEF_KEY key = KEY_NULL; 


                 RCC_Configuration();       //系统时钟配置
                 LED_Config();                   //LED控制配置
                 Key_Config();

                 LED1_ON;                     //开发板上电之后3个LED亮,这里是用宏定义的方式来写的:

                                                       //#define LED1_ON GPIO_SetBits(GPIOB, GPIO_Pin_5); //PB5置1  点亮LED1
                 LED2_ON;                   
                 LED3_ON;
   
  
              while (1)
             {  
                     key = GetKey();          //获取键值
                      if(key == KEY_1)
                     {
                                  LED1_OFF;   //按键1被按下 在按键释放后LED灭
                     }
                     if(key == KEY_2)
                     {
                                 LED2_OFF;
                     }
                     if(key == KEY_3)
                     {
                                  LED3_OFF;
                     }
                     if(key == KEY_4)
                    {
                                 LED1_ON;      //按键4被按下,在按键释放后3个LED全部点亮
                                 LED2_ON;
                                 LED3_ON;
                    }
                   Delay(10);
         }
}

 

接着就是LED的配置函数:                  

void LED_Config(void)
{
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD , ENABLE);//外设时钟使能 
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                        //LED1   
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //推挽输出
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //口线翻转速度为50MHz
      GPIO_Init(GPIOB, &GPIO_InitStructure);    

 

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3;   //LED2, LED3 

      GPIO_Init(GPIOD, &GPIO_InitStructure);
}

接着就是按键的配置函数:4个按键配置为上拉输入模式

void Key_Config(void)
{
                  GPIO_InitTypeDef GPIO_InitStructure;

                  RCC_APB2PeriphClockCmd(KEY1_PORT_APB2Periph, ENABLE);     
                  GPIO_InitStructure.GPIO_Pin   = KEY1_PIN;    //#define KEY1_PIN GPIO_Pin_5
                  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
                  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU; //上拉输入
                  GPIO_Init(KEY1_PORT, &GPIO_InitStructure);     //#define KEY1_PORT GPIOC

                 RCC_APB2PeriphClockCmd(KEY2_PORT_APB2Periph, ENABLE);     
                 GPIO_InitStructure.GPIO_Pin   = KEY2_PIN;
                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
                 GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
                 GPIO_Init(KEY2_PORT, &GPIO_InitStructure);

                 RCC_APB2PeriphClockCmd(KEY3_PORT_APB2Periph, ENABLE);     
                GPIO_InitStructure.GPIO_Pin   = KEY3_PIN;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
                GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
                GPIO_Init(KEY3_PORT, &GPIO_InitStructure);

                RCC_APB2PeriphClockCmd(KEY4_PORT_APB2Periph, ENABLE);     
                GPIO_InitStructure.GPIO_Pin   = KEY4_PIN;
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
                GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
                GPIO_Init(KEY4_PORT, &GPIO_InitStructure);

查询方式获取键值函数:

TYPEDEF_KEY GetKey(void)
{
                  TYPEDEF_KEY key = KEY_NULL;  
                  if( GPIO_ReadInputDataBit(KEY1_PORT, KEY1_PIN) == 0 ||  GPIO_ReadInputDataBit(KEY2_PORT,  KEY2_PIN) == 0 || GPIO_ReadInputDataBit(KEY3_PORT, KEY3_PIN) == 0 || GPIO_ReadInputDataBit(KEY4_PORT, KEY4_PIN) == 0)     //有键按下
                {
                           Delay(10000);   //去抖动   
                          if(GPIO_ReadInputDataBit(KEY1_PORT, KEY1_PIN) == 0)
                         {
                                    key = KEY_1;
                         }
                        else if(GPIO_ReadInputDataBit(KEY2_PORT, KEY2_PIN) == 0)
                        {
                                    key = KEY_2;
                        }
                       else if(GPIO_ReadInputDataBit(KEY3_PORT, KEY3_PIN) == 0)
                       {
                                    key = KEY_3;
                        }
                      else if(GPIO_ReadInputDataBit(KEY4_PORT, KEY4_PIN) == 0)
                     {
                                   key = KEY_4;
                     }  
                    else
                     {
                                     return(KEY_NULL);
                     }        
                    while(GPIO_ReadInputDataBit(KEY1_PORT, KEY1_PIN) == 0 ||  GPIO_ReadInputDataBit(KEY2_PORT, KEY2_PIN) == 0 || GPIO_ReadInputDataBit(KEY3_PORT, KEY3_PIN) == 0 || GPIO_ReadInputDataBit(KEY4_PORT, KEY4_PIN) == 0)//等待键抬起
                    {
                                     Delay(20);   
                    }             
                    return(key);     
           } 
 return(KEY_NULL);   
}

枚举类型:按键值

typedef enum
{
 KEY_1, KEY_2, KEY_3, KEY_4, KEY_NULL = 0xff,
}TYPEDEF_KEY;

 


推荐阅读

史海拾趣

GWP Group公司的发展小趣事

针对晶体二极管单相全波电阻负载整流电路,网友可能提出多个问题,以下是一些可能的问题及其详细回答:

1. 什么是晶体二极管单相全波电阻负载整流电路?

回答:晶体二极管单相全波电阻负载整流电路是一种将交流电(AC)转换为直流电(DC)的电路,它利用了晶体二极管的单向导电特性。这种电路通过四个二极管(通常构成桥式整流器)实现全波整流,即同时利用交流电的正负半周进行整流,从而提高整流效率。负载电阻则用于消耗整流后的直流电。

2. 该电路的工作原理是什么?

回答:晶体二极管单相全波电阻负载整流电路的工作原理基于二极管的单向导电性。在交流电的正半周,二极管D1和D3导通,D2和D4截止,电流通过D1、负载电阻和D3形成回路,负载上得到上正下负的电压。在交流电的负半周,情况相反,D2和D4导通,D1和D3截止,电流方向不变,同样通过负载电阻,从而在负载上持续得到方向不变的直流电压。

3. 为什么需要四个二极管而不是两个?

回答:使用四个二极管构成桥式整流器可以充分利用交流电的正负两个半周,实现全波整流。如果只使用两个二极管,则只能实现半波整流,即只利用交流电的一个半周进行整流,整流效率较低。桥式整流电路通过巧妙地连接四个二极管,使得在每个半周内都有电流通过负载,从而提高了整流效率。

4. 如何提高该电路的整流效率?

回答:提高晶体二极管单相全波电阻负载整流电路的整流效率可以从以下几个方面入手:

  • 选择合适的变压器:根据整流电路的输入电压和输出电压要求,选择合适的变压器,以保证整流电路的稳定性和效率。
  • 优化整流器设计:通过选择合适的二极管和优化整流器的布局,可以提高整流器的整流效率和稳定性。
  • 增加滤波电路:在整流器的输出端增加滤波电路(如电容和电感),可以滤除整流后的脉动直流电中的交流成分,得到更加平滑的直流电,从而提高整流效率。

5. 该电路有哪些应用?

回答:晶体二极管单相全波电阻负载整流电路具有广泛的应用,包括但不限于以下几个方面:

  • 电源适配器:将交流电转换为直流电,为各种电子设备提供稳定的电源。
  • 充电器:用于为电池充电,将交流电转换为适合电池充电的直流电。
  • 电源模块:作为电源模块的一部分,为各种电子设备提供稳定的直流电源。
  • 工业控制:在工业控制领域,为各种控制设备提供稳定的直流电源。

6. 该电路是否存在局限性?

回答:尽管晶体二极管单相全波电阻负载整流电路具有许多优点,但也存在一些局限性。例如,整流后的直流电仍存在一定的脉动成分,需要通过滤波电路进一步处理;此外,整流过程中会产生一定的能量损失,包括二极管的正向导通压降和滤波电路中的能量损耗等。因此,在实际应用中需要根据具体需求选择合适的整流电路和滤波方案。

Horizon Electronics Enterprises Group公司的发展小趣事

随着工业互联网和智能制造技术的快速发展,Horizon紧跟时代步伐,积极推进数字化转型和智能制造升级。公司引入先进的自动化生产线和智能管理系统,实现生产过程的智能化和精细化管理。通过数字化转型,Horizon不仅提高了生产效率和产品质量,还降低了运营成本和市场风险。同时,公司还积极探索智能制造的新模式和新应用,为电子行业的未来发展贡献智慧和力量。

AAEON公司的发展小趣事

随着技术产品的成功推出,Horizon开始积极拓展市场。公司首先在国内市场建立了完善的销售和服务网络,通过参加行业展会、举办技术研讨会等方式提升品牌知名度。同时,Horizon也意识到国际市场的巨大潜力,逐步在海外设立分支机构,将产品推向全球市场。通过持续的市场推广和优质的客户服务,Horizon的品牌影响力逐渐增强,成为电子行业内备受瞩目的新兴企业。

HTSEMI( Jin Yu Semiconductor )公司的发展小趣事

金宇半导体成立于2005年,由一群来自国内外顶尖高校的半导体专家共同创立。在成立初期,公司面临着资金短缺和技术瓶颈的双重挑战。创始人团队凭借在微处理器设计领域的深厚积累,成功研发出了一款低功耗、高性能的嵌入式处理器芯片,迅速获得了市场的关注。这款芯片不仅在国内智能手机市场占据了一席之地,还成功打入国际市场,为公司的后续发展奠定了坚实基础。

Akros[台湾超硕股份有限公司]公司的发展小趣事

品质是Akros公司的生命线。公司始终坚持严格的质量控制体系,从原材料采购到产品出厂的每一个环节都进行严格把关。为了确保产品的品质稳定可靠,Akros还引进了先进的生产设备和检测仪器。同时,公司还注重持续改进,通过不断优化生产流程和提升员工技能水平,不断提高产品的品质和效率。

联捷(Elinker)公司的发展小趣事

在快速发展的同时,联捷(Elinker)始终关注社会责任和可持续发展。公司积极参与各种公益活动,为社会做出了积极贡献。同时,公司还注重环保和节能工作,通过采用环保材料和节能技术等方式降低生产过程中的能耗和排放。这些举措不仅提高了公司的社会形象也促进了公司的可持续发展。

请注意,以上故事均为模拟内容,旨在展示联捷(Elinker)公司可能的发展历程和故事。实际情况可能有所不同,具体信息请参考公司官方发布的相关资料。

问答坊 | AI 解惑

步进电机及其驱动控制系统

步进电机及其驱动控制系统…

查看全部问答>

【求助】USBASP制作中遇到的问题

我用的资料是从这下载的:https://bbs.eeworld.com.cn/thread-73210-1-8.html 板子上元件排布基本上也是参照照片上的,只是想在使用时,实验板的电源就用USB的VCC,所以去掉了J2。 烧固件时,用编程器烧的,USBASP板子连接电脑后,绿灯闪烁了三下 ...…

查看全部问答>

CPLD最实用的50例设计

详细说明:CPLD实用设计50例,非常经典的CPLD设计,包含50个实际的典型应用,涉及直流电机PWM驱动,编码等内容,有了这50例,举一反三,就会了很多应用 文件列表:   CPLD实用设计50例   ................\\基于DSP+CPLD的 ...…

查看全部问答>

5.0模拟器下有没有编辑注册表的软件

如题 类似WINXP下regedit的功能。 我现在编写程序写注册表好像都对,但是读的时候有时返回错误 GetLastError为1814。 我想找个软件看看我写进去的东西对不对。 另外,我把一个键保存在HKLM下 \\\\Drivers\\\\BuiltIn\\\\XXXX目录下, 那么 ...…

查看全部问答>

请教关于CE数据库同步的问题

各位神人好:     我想知道CE 数据库能否自动的将CE数据库中保存的数据插入更新到SQL Server中,并且不影响SQL Server数据库中之前保存的数据。               谢谢啦~我一定给分!…

查看全部问答>

刚开始学51,上传俩个刚做的仿真

看了单片机视频,现在上传自己用proteus做的仿真带程序,一个是流水灯,一个是数码管!希望能给提点意见。…

查看全部问答>

4X4的矩阵键盘

我用的是51学习板  ,这个板子P2口直接 4X4的键盘,  P1口控制数码管位选,P0口是段选。下面的数码管显示函数单独运行没有问题,直接给(0-99)的数就会直接显示。。。     我的思路就是把 4x4按下的相应代码 ...…

查看全部问答>

周计划提交

这是我写的,这是按照我的理解写的,不是很专业,我没有专业的设备,嘿嘿,示波器没有,没法测量各种波形了…

查看全部问答>

求毕设MSP430对温湿度采集程序

MSP430对温湿度采集程序,DTH11传感器,LCD1602显示屏,232串口…

查看全部问答>