当前位置:   article > 正文

STM32入门学习 第二天_pfout(1)

pfout(1)

提示:今天是STM32入门学习的第二天,重点学习了GPIO的工作原理,通过库函数、寄存器、位操作来实现跑马灯。


目录

 第一讲 STM32GPIO工作原理

1.GPIO功能描述

2.每组GPIO端口的寄存器

第二讲 库函数——跑马灯

1.初始化

2.手把手写跑马灯实验-库函数

第三讲 寄存器——跑马灯

第四讲 位操作——跑马灯


第一讲 STM32GPIO工作原理

1.GPIO功能描述

每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。

根据数据手册中列出的每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置 成多种模式。

4种输入模式

  • 输入浮空
  • 输入上拉
  • 输入下拉
  • 模拟输入
u 4 种输出模式:
  • 开漏输出
  • 推挽式输出
  • 推挽式复用功能
  • 开漏复用功能

每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访 问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这 样,在读和更改访问之间产生IRQ时不会发生危险。 下图给出了一个I/O端口位的基本结构

 3种最大翻转速度

 GPIO的输入工作模式1—输入浮空模式

GPIO的输入工作模式2—输入上拉模式

 GPIO的输入工作模式3—输入下拉模式

 GPIO的输入工作模式4—模拟模式

 GPIO的输出工作模式1—开漏输出模式

 GPIO的输出工作模式2—开漏复用输出模式

 GPIO的输出工作模式3—推挽输出模式

 GPIO的输出工作模式4—推挽复用输出模式

推挽输出:可以输出强高低电平,连接数字器件 

开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)

2.每组GPIO端口的寄存器

两个32位配置寄存器(GPIOx_CRL GPIOx_CRH)

两个32位数据寄存器 (GPIOx_IDRGPIOx_ODR)

一个32位置位/ 复位寄存器(GPIOx_BSRR)

一个16位复位寄存器(GPIOx_BRR)

一个32位锁定寄存器(GPIOx_LCKR)

每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)

例如:STM32F103ZET6:一共有7组IO口,每组IO口有16个IO,一共16X7=112个IO。GPIOA,GPIOB---GPIOG。每组IO口含下面7个寄存器,也就是7个寄存器,一共可以控制一组GPIO的16个IO口。

32位寄存器配置每个IO口要四位,所以只能配置八个IO口,而有十六个IO口,故需要两个端口配置寄存器。CRL控制0—7的IO口,CRH控制8—15个IO口。

2.1 端口配置低寄存器(GPIOx_CRL)

观察使用时先确定MODY是在输出还是输入,若为00则为输入,此时在看CNYF是输入的那个状态,其中10有上拉和下拉是在ODR这个寄存器里面。

2.2 端口配置高寄存器(GPIOx_CRH)

 2.3 端口输入数据寄存器(GPIOx_IDR)

2.4 端口输出数据寄存器(GPIOx_ODR) 

 输出为1则是高电平,输出为0则是低电平。和输出寄存器一样,主要是这个寄存器控制着上拉还是下拉电阻。其中0为下拉1为上拉。

2.5 端口位设置/清除寄存器(GPIOx_BSRR)

2.6 端口位清除寄存器(GPIOx_BRR)

设置那个IO口就是那个IO口。不过经常以这个寄存器清除低位,以2.5那个寄存器清除高位。 

a.端口重映射功能:就是可以把某些功能引脚映射到其他引脚。 比如串口1默认引脚是PA9,PA10可以通过配置重映射映,射到PB6,PB7。作用:方便布线 
端口复用功能:STM32的大部分端口都具有复用功能。所谓复用,就是一些端口不仅仅可以做为通用IO口,还可以复用为一些外设引脚,比如PA9,PA10可以复用为STM32的串口1引脚。作用:最大限度的利用端口资源

第二讲 库函数——跑马灯

GPIO输出方式:推挽输出,可以输出强高低电平。

库函数的介绍:操作IO口必须引入的源文件和头文件。

头文件:stm32f10x_gpio.h

源文件:stm32f10x_gpio.c

1.初始化

重要函数:

1个初始化函数:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

2个读取输入电平函数:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

2个读取输出电平函数:

uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

4个设置输出电平函数:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);输出高

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);输出低

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

1个初始化函数:此函数调用的时候要输入两个参数,对于第一个参数来说进入是一个结构体里面存放了IO口的七个寄存器,而范围是GPIOA~GPIOG  。第二个参数是来初始化的里面是如下方框里的一个结构体,后面跟着一个指针变量。

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

作用:初始化一个或者多个IO口(同一组)的工作方式和速度。

该函数主要是操作GPIO_CRL(CRH)寄存器,在上拉或者下拉的时候有设置BSRR或者BRR寄存器

GPIOx: GPIOA~GPIOG    

  1. typedef struct
  2. {
  3. uint16_t GPIO_Pin; //指定那一组中要初始化的IO口
  4. GPIOSpeed_TypeDef GPIO_Speed; //设置IO口输出速度
  5. GPIOMode_TypeDef GPIO_Mode; //设置工作模式:8种中的一个
  6. }GPIO_InitTypeDef;

注意:外设(包括GPIO)在使用之前,几乎都要先使能对应的时钟。

GPIO_Init函数初始化样:

  1. GPIO_InitTypeDef GPIO_InitStructure;
  2. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置
  3. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  4. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
  5. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5

2个读取输入电平函数:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:读取某个GPIO的输入电平。实际操作的是GPIOx_IDR寄存器。

例如:GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);//读取GPIOA.5的输入电平

uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

作用:读取某组GPIO的输入电平。实际操作的是GPIOx_IDR寄存器。

例如:GPIO_ReadInputData(GPIOA);//读取GPIOA组中所有io口输入电平

4个设置输出电平函数:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:设置某个IO口输出为高电平(1)。实际操作BSRR寄存器

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

作用:设置某个IO口输出为低电平(0)。实际操作的BRR寄存器。

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

 这两个函数不常用,也是用来设置IO口输出电平。

2.手把手写跑马灯实验-库函数

使能IO口时钟。调用函数RCC_APB2PeriphColckCmd();

不同的IO组,调用的时钟使能函数不一样。

初始化IO口模式。调用函数GPIO_Init();
操作IO口,输出高低电平。GPIO_SetBits();GPIO_ResetBits();
  1. #include"led.h"
  2. #include"stm32f10x.h"
  3. void LED_Init(void)
  4. {
  5. GPIO_InitTypeDef GPIO_InitStructture;
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//ʹÄÜʱÖÓ
  8. GPIO_InitStructture.GPIO_Mode=GPIO_Mode_Out_PP;
  9. GPIO_InitStructture.GPIO_Pin=GPIO_Pin_5;
  10. GPIO_InitStructture.GPIO_Speed=GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOB,&GPIO_InitStructture);
  12. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  13. GPIO_InitStructture.GPIO_Mode=GPIO_Mode_Out_PP;
  14. GPIO_InitStructture.GPIO_Pin=GPIO_Pin_5;
  15. GPIO_InitStructture.GPIO_Speed=GPIO_Speed_50MHz;
  16. GPIO_Init(GPIOE,&GPIO_InitStructture);
  17. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  18. }
  1. #include "stm32f10x.h"
  2. #include "delay.h"
  3. #include "led.h"
  4. int main(void)
  5. {
  6. delay_init();
  7. LED_Init();
  8. while(1){
  9. GPIO_SetBits(GPIOB,GPIO_Pin_5);
  10. GPIO_SetBits(GPIOE,GPIO_Pin_5);
  11. delay_ms(500);
  12. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  13. GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  14. delay_ms(500);
  15. }
  16. }

第三讲 寄存器——跑马灯

在了解下GPIO相关的寄存器,在库函数里操作寄存器。

两个32位配置寄存器(GPIOx_CRL ,GPIOx_CRH) ,

两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR),

一个32位置位/ 复位寄存器(GPIOx_BSRR),

一个16位复位寄存器(GPIOx_BRR),

一个32位锁定寄存器(GPIOx_LCKR)。

手把手写跑马灯实验-寄存器
使能IO口时钟。配置寄存器RCC_APB2ENR。
初始化IO口模式。配置寄存器GPIOx_CRH/CRL
操作IO口,输出高低电平。配置寄存器GPIOX_ODR或者BSRR/BRR。
  1. #include"led.h"
  2. #include"stm32f10x.h"
  3. void LED_Init(void)
  4. {
  5. RCC->APB2ENR!=1<<3;//寄存器只要第三位,其他不改变
  6. RCC->APB2ENR!=1<<6;//寄存器第六位
  7. GPIOB->CRL&=0XFF0FFFFF;//GPIOB.5
  8. GPIOB->CRL|=0X00300000;//先清零在赋值
  9. GPIO->ODR=1<<5;
  10. GPIOB->CRL&=0XFF0FFFFF;//GPIOB.6
  11. GPIOB->CRL|=0X00300000;//先清零在赋值
  12. GPIO->ODR=1<<5;
  13. }
  1. #include"stm32f10x.h"
  2. #include"delay.h"
  3. #include"led.h"
  4. int main(void)
  5. {
  6. delay_init();
  7. LED_Init();
  8. while(1){
  9. GPIOB->|=1<<5;
  10. GPIOE->|=1<<5;
  11. delay_init(500);
  12. GPIOB->ODR=~(1<<5);
  13. delay_init(500);
  14. }
  15. }

第四讲 位操作——跑马灯

位操作:支持了位带 中,有两个区中实现了位带。其中一个是 SRAM 区的最低 1MB 范围,第二个则是片内外设 区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自 己的“位带别名区”,位带别名区把每个比特膨胀成一个 32 位的字。当你通过位带别名区访 问这些字时,就可以达到访问原始比特的目的。

也可以理解成把每个比特膨胀为一个32位的字,当访问这些字的时候就达到了访问比特的目的,比如说BSRR寄存器有32个位,那么可以映射到32个地址上,我们去访问(读--写)32个地址就达到访问32个比特的目的。

 举例如下:

映射关系:

位带区:支持位带操作的地址区

位带别名:对别名地址的访问最终作用到位带区的访问上(注意:这中间有一个地址映射过程)

手把手写跑马灯实验-位带操作。

使能IO口时钟。调用函数RCC_APB2PeriphColckCmd();

初始化IO口模式。调用函数GPIO_Init();

操作IO 口,输出高低电平。 使用位带操作
sys.h里面对GPIO输入输出部分功能实现了位带操作:
  1. #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
  2. #define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
  3. #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
  4. //IO口地址映射
  5. #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
  6. #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
  7. #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
  8. #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
  9. #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
  10. #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
  11. #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
  12. //IO口操作,只对单一的IO口!
  13. //确保n的值小于16!
  14. #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
  15. #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
  16. #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
  17. #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
  18. #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
  19. #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
  20. #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
  21. #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "delay.h"
  4. int main(void)
  5. {
  6. delay_init();
  7. LED_Init();
  8. while(1){
  9. PBout(5)=1;
  10. PEout(5)=1;
  11. delay_ms(500);
  12. PBout(5)=0;
  13. PEout(5)=0;
  14. delay_ms(500);
  15. }
  16. }

第五讲 蜂鸣器实验

1.蜂鸣器简介

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 我们使用的开发板板载的蜂鸣器是电磁式的有源蜂鸣器。这里的有源不是指电源的“源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路, 一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供 2~5Khz 左右的方波驱动, 才能发声。

STM32 的单个 IO 最大可以提供 25mA 电流(来自数据手册),而蜂鸣器的驱动电流是 30mA 左右,两 者十分相近,但是全盘考虑,STM32 整个芯片的电流,最大也就 150mA,如果用 IO 口直接驱 动蜂鸣器,其他地方用电就得省着点了…所以,我们不用 STM32 的 IO 直接驱动蜂鸣器,而是 通过三极管扩流后再驱动蜂鸣器,这样 STM32 的 IO 只需要提供不到 1mA 的电流就足够了。

2.硬件设计 

1)指示灯 DS0

2)蜂鸣器

 NPN 三极管(S8050)来驱动蜂鸣器,R60 主要用于防止蜂鸣器的误发 声。当 PB.8 输出高电平的时候,蜂鸣器将发声,当 PB.8 输出低电平的时候,蜂鸣器停止发声。

3.软件介绍

  1. #include "beep.h"
  2. //初始化 PB8 为输出口.并使能这个口的时钟
  3. //LED IO 初始化
  4. void BEEP_Init(void)
  5. {
  6. GPIO_InitTypeDef GPIO_InitStructure;
  7. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  8. //使能 GPIOB 端口时钟
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //BEEP-->GPIOB.8 端口配置
  10. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度为 50MHz
  12. GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数初始化 GPIOB.8
  13. GPIO_ResetBits(GPIOB,GPIO_Pin_8); //输出 0,关闭蜂鸣器输出
  14. }

void BEEP_Init(void),该函数的作用就是使能 PORTB 的时钟, 同时配置 PB8 为推挽输出。这里的初始化内容跟跑马灯实验几乎是一样的,这里就不做 深入的讲解。

  1. 在 main.c 里面编写如下代码:
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. //ALIENTEK 战舰 STM32 开发板实验 2
  7. //蜂鸣器实验
  8. int main(void)
  9. {
  10. delay_init(); //延时函数初始化
  11. LED_Init(); //初始化与 LED 连接的硬件接口
  12. BEEP_Init(); //初始化蜂鸣器端口
  13. while(1)
  14. { LED0=0;
  15. BEEP=0;
  16. delay_ms(300);
  17. LED0=1;
  18. BEEP=1;
  19. delay_ms(300);
  20. }
  21. }

第六讲 按键输入实验

1.STM32 IO 口简介

STM32F1 的 IO 口已经有了比较详细的介绍。STM32F1 的 IO 口做输入使用的时候,是通过调用函数 GPIO_ReadInputDataBit()来读取 IO 口的状态的。就可以开始我们的代码编写了。 这一章,我们将通过 ALIENTEK 战舰 STM32 开发板上载有的 4 个按钮(WK_UP、KEY0、 KEY1 和 KEY2),来控制板上的 2 个 LED(DS0 和 DS1)和蜂鸣器,其中 WK_UP 控制蜂鸣器, 按一次叫,再按一次停;KEY2 控制 DS0,按一次亮,再按一次灭;KEY1 控制 DS1,效果同 KEY2;KEY0 则同时控制 DS0 和 DS1,按一次,他们的状态就翻转一次。

2.硬件设计

本实验用到的硬件资源有:

1) 指示灯 DS0、DS1

2) 蜂鸣器

3) 4 个按键:KEY0、KEY1、KEY2、和 WK_UP。 

KEY0、KEY1 和 KEY2 是低电平有效的,而 WK_UP 是高电平有效的, 并且外部都没有上下拉电阻,所以,需要在 STM32 内部设置上下拉。

3.软件设计

按键实验工程引入了 key.c 文件以及头文件 key.h。下面我们首先打开 key.c 文件,代码如下:

  1. #include "key.h"
  2. #include "sys.h"
  3. #include "delay.h"
  4. //按键初始化函数
  5. void KEY_Init(void) //IO 初始化
  6. {
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
  9. RCC_APB2Periph_GPIOE,ENABLE); //使能 PORTA,PORTE 时钟
  10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;//GPIOE.2~4
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
  12. GPIO_Init(GPIOE, &GPIO_InitStructure); //初始化 GPIOE2,3,4
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //初始化 WK_UP-->GPIOA.0
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 设置成输入,下拉
  15. GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 GPIOA.0
  16. }
  17. //按键处理函数
  18. //返回按键值
  19. //mode:0,不支持连续按;1,支持连续按;
  20. //0,没有任何按键按下;1KEY0 按下;2KEY1 按下;3KEY2 按下 ;4KEY3 按下 WK_UP
  21. //注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
  22. u8 KEY_Scan(u8 mode)
  23. {
  24. static u8 key_up=1; //按键按松开标志
  25. if(mode)key_up=1; //支持连按
  26. if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3==1))
  27. {
  28. delay_ms(10); //去抖动
  29. key_up=0;
  30. if(KEY0==0)return KEY0_PRES;
  31. else if(KEY1==0)return KEY1_PRES;
  32. else if(KEY2==0)return KEY2_PRES;
  33. else if(KEY3==1)return WKUP_PRES;
  34. }else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3==0)key_up=1;
  35. return 0; // 无按键按下
  36. }

接下来我们看看头文件 key.h 里面的代码: 

  1. #ifndef __KEY_H
  2. #define __KEY_H
  3. #include "sys.h"
  4. #define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键 0
  5. #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键 1
  6. #define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键 2
  7. #define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键 3(WK_UP)
  8. #define KEY0_PRES 1 //KEY0 按下
  9. #define KEY1_PRES 2 //KEY1 按下
  10. #define KEY2_PRES 3 //KEY2 按下
  11. #define WKUP_PRES 4 //WK_UP 按下(即 WK_UP/WK_UP)
  12. void KEY_Init(void); //IO 初始化
  13. u8 KEY_Scan(u8); //按键扫描函数
  14. #endif

位操作也可以:

  1. #define KEY0 PEin(4) //PE4
  2. #define KEY1 PEin(3) //PE3
  3. #define KEY2 PEin(2) //PE2
  4. #define WK_UP PAin(0) //PA0 WK_UP

主函数:

  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "beep.h"
  6. //ALIENTEK 战舰 STM32 开发板实验 3
  7. //按键输入实验
  8. int main(void)
  9. {
  10. u8 key;
  11. delay_init(); //延时函数初始化
  12. LED_Init(); //LED 端口初始化
  13. KEY_Init(); //初始化与按键连接的硬件接口
  14. BEEP_Init(); //初始化蜂鸣器端口
  15. LED0=0; //先点亮红灯
  16. while(1)
  17. {
  18. key =KEY_Scan(0); //得到键值
  19. if(key)
  20. { switch(t)
  21. { case WKUP_PRES: //控制蜂鸣器
  22. BEEP=!BEEP;break;
  23. case KEY2_PRES: //控制 LED0 翻转
  24. LED0=!LED0;break;
  25. case KEY1_PRES: //控制 LED1 翻转
  26. LED1=!LED1;break;
  27. case KEY0_PRES: //同时控制 LED0,LED1 翻转
  28. LED0=!LED0;
  29. LED1=!LED1;break;
  30. }
  31. }else delay_ms(10);
  32. }
  33. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/479364
推荐阅读
相关标签
  

闽ICP备14008679号