STM8L151C8学习笔记2:KEY驱动

发布者:数字驿站最新更新时间:2022-01-12 来源: eefocus关键字:学习笔记 手机看文章 扫描二维码
随时随地手机看文章

实现功能:用按键来实现LED灯的亮灭。

按键是外部电路来决定高低电平的,若按键未按下时,默认为高电平;若按键按下时,为低电平。


按键检测主要是根据按键对应I/0口的电平状态,来生成按键信号。


硬件电路

KEY:

KEY

按键程序编写

1.读取I/O口函数

从stm8l15x_gpio.c中的GPIO_ReadInputDataBit()函数来看,该函数返回值是通过GPIO的IDR寄存器读取I/O口状态,然后&上相应的GPIO_Pin_x,最后再将结果强制转换为BitStatus。


STM8的写法返回值可能出现大于1的数,其原因在于原类型的数强制转换成BitStatus后,返回的结果仍为0或1以外的值(可能为0x02,0x04,0x08,0x20,0x40,0x80),强制无效,因为这些值在没法在枚举定义时的元素值中找到,其结果超出了枚举范围。

STM8固件库里的读取I/O口函数:

在这里插入图片描述

STM32固件库中的读取I/O口函数:

在这里插入图片描述

所以可以将STM8中的GPIO_ReadInputDataBit()函数改成如下:


BitStatus GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)

{

  if((GPIOx->ODR & (uint8_t)GPIO_Pin) != RESET)

  {

      return SET;

  }

  else

  {

      return RESET;

  }

}


这样返回值就不会再出现大于1的值了。


2.KEY初始化函数

一般情况下,KEY的GPIO工作方式有两种:


1.浮空输入模式(GPIO_Mode_In_FL_No_IT、GPIO_Mode_In_FL_IT)


2.上拉输入模式(GPIO_Mode_In_PU_No_IT、GPIO_Mode_In_PU_IT)


由于硬件电路没有加上拉电阻,并且我不需要用到外部中断功能,我这里将按键I/0口设置为成GPIO_Mode_In_PU_No_IT。


/* Includes ------------------------------------------------------------------*/

#include "key.h"

#include "delay.h"


/* Parameter Definition ------------------------------------------------------------------*/

/*KEY GPIO*/

#define KEY1_PORT       GPIOE

#define KEY2_PORT       GPIOD


/*KEY PIN*/

#define KEY1_PIN        GPIO_Pin_5

#define KEY2_PIN        GPIO_Pin_0

#define KEY3_PIN        GPIO_Pin_1

#define KEY4_PIN        GPIO_Pin_2


/*KEY Read*/

#define KEY1 GPIO_ReadInputDataBit(KEY1_PORT, KEY1_PIN)

#define KEY2 GPIO_ReadInputDataBit(KEY2_PORT, KEY2_PIN)

#define KEY3 GPIO_ReadInputDataBit(KEY2_PORT, KEY3_PIN)

#define KEY4 GPIO_ReadInputDataBit(KEY2_PORT, KEY4_PIN)


/*KEY Press Value*/

#define KEY1_PRESS      1

#define KEY2_PRESS      2

#define KEY3_PRESS      3

#define KEY4_PRESS      4


/* Source Functions ------------------------------------------------------------------*/

void Key_Init(void)

{

  /*KEY1 Init*/

  GPIO_Init(KEY1_PORT,KEY1_PIN,GPIO_Mode_In_PU_No_IT);

  /*KEY2 Init*/

  GPIO_Init(KEY2_PORT,KEY2_PIN|KEY3_PIN|KEY4_PIN,GPIO_Mode_In_PU_No_IT);

}


3.KEY扫描函数

按键扫描是参照原子哥写的按键扫描,具体如下:


uint8_t Key_Scanf(void)

{

  static uint8_t key_up=1;//按键按松开标志   

  if(key_up&&(KEY1==0||KEY2==0||KEY3==0|KEY4==0))

  {

    Delay_ms(10);//去抖动

    key_up=0;

    if(KEY1==0)                 return KEY1_PRESS;

    else if(KEY2==0)            return KEY2_PRESS;

    else if(KEY3==0)            return KEY3_PRESS;

    else if(KEY4==0)            return KEY4_PRESS;

  }else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)key_up=1;      

  return 0;// 无按键按下

}


功能实现部分

主函数功能主要如下:

image.png

main.c 如下:


/* Includes ------------------------------------------------------------------*/

#include "stm8l15x.h"

#include "led.h"

#include "key.h"

#include "stdio.h"

/* Parameter Definition ------------------------------------------------------------------*/

uint8_t LED1_State = 1,LED2_State = 0;

/* Functions Declaration ------------------------------------------------------------------*/

void Key_Function(void);

void LED_Flash(void);


/* Source Functions ------------------------------------------------------------------*/

/**

  * @brief  CLK Config.

  * @param  None

  * @retval None

  */

void Clk_Config(void)

{

   CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);//系统1分频,16M

}


/**

  * @brief  Main program.

  * @param  None

  * @retval None

  */

int main(void)

{

  /*System Init*/

  Clk_Config();

  Key_Init();

  Led_Init();

  /* Infinite loop */

  while (1)

  {

//    LED_Flash();

    Key_Function();

  }

}

/**

  * @brief  LED Flash.

  * @param  None

  * @retval None

  */

void LED_Flash(void)

{

  Led_Set(LED2, LED2_State);

  Led_Set(LED1, LED1_State);

  LED1_State = !LED1_State;

  LED2_State = !LED2_State;

  Delay_ms(500); 

}

/**

  * @brief  Key function.

  * @param  None

  * @retval None

  */

void Key_Function(void)

{

   uint8_t Buff[40];

   uint8_t Key;

   

   Key = Key_Scanf();

   /*KEY1 Function*/

   if(Key == KEY1_PRESS)

   {

     printf("KEY1 PRESS!rn");

     LED1_State = !LED1_State;

   }

   /*KEY2 Function*/

   if(Key == KEY2_PRESS)

   {

     LED2_State = !LED2_State;

   }

   /*KEY3 Function*/

   if(Key == KEY3_PRESS)

   {

     LED1_State = 1;

   }

   /*KEY4 Function*/

   if(Key == KEY4_PRESS)

   {

     LED2_State = 1;

   }

   /*LED Function*/

   Led_Set(LED1, LED1_State);

   Led_Set(LED2, LED2_State);

}


总结

由于以前编程的惯性思维(不常去看固件库里给的函数),在按键判断吃了大亏,算是“吃一堑,长一智”吧。

关键字:学习笔记 引用地址:STM8L151C8学习笔记2:KEY驱动

上一篇:单片机C语言程序与数据存储
下一篇:STM8L151C8学习笔记5:低功耗

推荐阅读最新更新时间:2024-11-13 14:02

单片机学习笔记——中断原理及应用
单片机中断原理(外部中断) 中断概念: 中断发生:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理。 中断响应和中断服务:CPU暂时中断当前的工作,转去处理事件B。 中断返回:待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A。 这一过程被称为中断。 中断过程示意图: 一些关于中断过程的名词: 中断源:引起CPU中断的根源。 中断源向CPU提出中断请求。 断点:原来被中断的地方。 中断系统:实现上述中断功能的部件。 80C51中断系统的结构: 5个中断源(8052有6个),2个优先级。 可实现二级中断嵌套。 结构如下图: 中断过程: I
[单片机]
单片机<font color='red'>学习</font><font color='red'>笔记</font>——中断原理及应用
我的HD7279学习笔记——基于msp430g2553
Created on: 2012-9-7 Author: zhang bin 学习笔记 for msp430g2553 redesigned by zhang bin 2012-09-07 versions :12_09_01 All Rights Reserved HD7279的基本说明如下: HD7279是一片具有串行接口的,可同时驱动8位共阴式数码管(或64只独立led)的智能显示驱动芯片,该芯片同时还可连接多达64键的键盘矩阵,单片即可完成led显示、键盘接口的全部功能。 HD7279内部含有译码器,可直接接受BCD码或16进制码,并同时具有2种译码方式。此外,还具有多种控制指令
[单片机]
STM32学习笔记-Flash作为存储器储存数据
说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装芯片配置、芯片ID、自举程序等等。当然, FLASH还可以用来装数据。 自己收集了一些资料,现将这些资料总结了一下,不想看的可以直接调到后面看怎么操作就可以了。 FLASH分类 根据用途,STM32片内的FLASH分成两部分:主存储块、信息块。 主存储块用于存储程序,我们写的程序一般存储在这里。 信息块又分成两部分:系统存储器、选项字节。 系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。这个区域由芯片厂写入Boot
[单片机]
OK6410A学习笔记四:嵌入式Linux驱动之LED驱动进阶
作为上一篇介绍的LED驱动的续篇,主要的改动之处在于实现了利用Linux系统支持的mdev机制在驱动加载的过程中自动创建设备节点的功能,另外,对write函数有了比较大的改进。 //s3c6410_led.c driver file #include linux/kernel.h #include linux/module.h #include linux/fs.h #include linux/mm.h #include linux/device.h #include linux/types.h #include linux/io.h #include asm/uaccess.h #define DEV_
[单片机]
OK6410A<font color='red'>学习</font><font color='red'>笔记</font>四:嵌入式Linux<font color='red'>驱动</font>之LED<font color='red'>驱动</font>进阶
STM32F4学习笔记9——独立看门狗与窗口看门狗
STM32F4xx内置俩个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看门狗设备可用来检测和解决由软件错误引起的故障;当计数器大道给定的超时值触发一个中断(触发中断仅适用于窗口看门狗)或产生系统复位。 地理看门狗IWDG有用们的低速时钟LSI驱动,及时主时钟发生故障他也任然有效。窗口看门狗由APB1是中国分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。 IWDG最时候用于哪些需要一个看门狗在主程序之外能够独立工作并且对时间精度要求较低的场合,WWDG适合用于哪些要求看门狗在精确计算计时窗口起作用的应用程序。 IWDG主要特性与功能 ·自由运行的递减计数器 ·时钟由独立RC振荡器提供
[单片机]
STM32F4<font color='red'>学习</font><font color='red'>笔记</font>9——独立看门狗与窗口看门狗
单片机之AD学习笔记
最近调试了几个单片机的AD转换模块,碰到了一些问题,总结了一下 AD转换就是选通道、比较电压、要采集电压的端口设置为模拟端口 1、选择参考电压源 2、选择AD转换时钟 3、要采集电压的端口设置为模拟端口 4、选择要采样的模拟通道 5、使能AD模块 PIC24FJ 开始看此部分是调试电池电量的时候,是由于电池电量显示不准确,debug模式下,看ad采集到的电压被转换成的数据,发现寄存器ADC1BUF中的数据只有关开机是正确的,以后的值都是不对的好像大多数的值是零,后来发现是由于在主循环中的某个模块又把原来配置为模拟输入端口引脚还原成了普通的I/O口了(就是AD1PCFGbits.PCFG0先被配置为0后又被置1,我用的
[单片机]
四、Timer【MSP430学习笔记
MSP430之定时器 定时器A相关寄存器: 例程: //定时器初始化 void TimeA_Init(void) { TACCR0 = 6553; //定时200ms TACTL = TASSEL_1 + MC_1; //定时器A的时钟为ACLK,时钟不分频,增计数模式 TACCTL0 | = CCIE; //定时器模式为比较模式,使能比较中断 } //定时器A中断 #pragma vector = TIMERA0_VECTOR _interrupt void Timer_ISR(void) { //在这里添加事件 LED_HL; //翻转LED灯状态 }
[单片机]
四、Timer【MSP430<font color='red'>学习</font><font color='red'>笔记</font>】
单片机中断学习笔记
一、基本概念 1、 89C51单片机中共有5 个中断源:两个外部中断,两个定时/计数器中断(溢出),一个串行口中断。 2、 单片机中断系统中有两种不同类型的中断:一种称为非屏蔽中断,用户不能用软件方法加以禁止;另一种称为屏蔽中断,本文描述的都是这种类型。 3、 二、控制字 1、 外部中断。单片机的12、13(P3.2、P3.3)脚引入,名称为INT0、INT1。以上的TCON寄存器用于控制外部中断。 IT0:INT0的触发方式。0表示低电平触发;1表示负跳变触发。 IE0:有外部中断进入时,该位置1。CPU响应后自动清0。 2、 内部中断。TCON寄存器,定时器中已描述。 3、 串行口中断。 4、 中断允许寄存
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved