29.按键控制LED程序
微动开关,按下去导通(低电平),按键放开(高电平)。
key.c文件
#include "key.h"
void KEY_Init(void){ //微动开关的接口初始化
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的初始化枚举结构
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动相应总线时钟
GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2; //选择端口号(0~15或all)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //**上拉电阻**
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)
GPIO_Init(KEYPORT,&GPIO_InitStructure);
}
选择IO接口工作方式:
GPIO_Mode_AIN 模拟输入
GPIO_Mode_IN_FLOATING 浮空输入
GPIO_Mode_IPD 下拉输入
GPIO_Mode_IPU 上拉输入
GPIO_Mode_Out_PP 推挽输出
GPIO_Mode_Out_OD 开漏输出
GPIO_Mode_AF_PP 复用推挽输出
GPIO_Mode_AF_OD 复用开漏输出
*/
key.h文件
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
//#define KEY1 PAin(0)// PA0
//#define KEY2 PAin(1)// PA1
#define KEYPORT GPIOA //定义IO接口组
#define KEY1 GPIO_Pin_0 //定义IO接口
#define KEY2 GPIO_Pin_1 //定义IO接口
void KEY_Init(void);//初始化
#endif
程序名: 按键控制LED程序
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h" //调用按键相关程序
int main (void){//主程序
u8 a; //定义变量
//初始化程序
RCC_Configuration(); //时钟设置
LED_Init();//LED初始化
KEY_Init();//按键初始化(调用了key.c当中的按键初始化)
//主循环
while(1){
//示例1:无锁存(按下点亮,松开熄灭)
if(GPIO_ReadInputDataBit(KEYPORT(使用了哪一组IO端口),KEY1(具体的哪一位))){ //读按键接口的电平 //ReadInputdataBit读取指定端口管脚的输入
GPIO_ResetBits(LEDPORT,LED1); //LED灯都为低电平(0)
}else{
GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1)
}
//示例2:无锁存
// GPIO_WriteBit(LEDPORT,LED1,(BitAction)(!GPIO_ReadInputDataBit(KEYPORT,KEY1)));
//使用了端口写的操作,BitAction:如果括号内结果为1,则输出高电平,为0对应IO端口输出低电平,熄灭。
//函数内套函数。
//示例3:有锁存
// 先判断按键是否按下,如果按下则延时20ms,接着再判断是否按下,如果按下,则进行按键按下相对应的操作,最后等待按键放开,放开才能退出。
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// delay_ms(20); //延时去抖动
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //LED取反
// while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开
// }
// }
//示例4:有锁存
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// delay_ms(20); //延时20ms去抖动
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// //在2个LED上显示二进制加法
// a++; //变量加1
// if(a>3){ //当变量大于3时清0
// a=0;
// }
// GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上)
// while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开
// }
// }
}
}
//经典示例3:有锁存
// 先判断按键是否按下,如果按下则延时20ms,接着再判断是否按下,如果按下,则进行按键按下相对应的操作,最后等待按键放开,放开才能退出。
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// delay_ms(20); //延时去抖动
// if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
// GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //LED取反
// while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开
// }
// }
按键消抖:
经过20毫秒的等待才进入平稳状态
30.FLASH读写程序
用flash保存led的开关状态通过ASP按键开关使得之前的状态保持。
flash.c文件
#include "flash.h"
//FLASH写入数据
void FLASH_W(u32 add,u16 dat){ //参数1:32位FLASH地址。参数2:16位数据
// RCC_HSICmd(ENABLE); //打开HSI时钟
FLASH_Unlock(); //解锁FLASH编程擦除控制器
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
//清除标志位
FLASH_ErasePage(add); //擦除指定地址页(每次写入数据之前要擦除)
FLASH_ProgramHalfWord(add,dat); //从指定页的addr地址开始写
FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
//清除标志位
FLASH_Lock(); //锁定FLASH编程擦除控制器
}
//FLASH读出数据
u16 FLASH_R(u32 add){ //参数1:32位读出FLASH地址。返回值:16位数据
u16 a;
a = *(u16*)(add);//从指定页的addr地址开始读
return a;
}
FLASH进行擦除时,按页来擦除。
要知道哪一个地址对应哪一个页。
main文件
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "flash.h"
#define FLASH_START_ADDR 0x0801f000 //写入的起始地址(不在第一页开始,防止占用用户数据)
int main (void){//主程序
u16 a; //定义变量
//初始化程序
RCC_Configuration(); //时钟设置
LED_Init();//LED初始化
KEY_Init();//按键初始化
a = FLASH_R(FLASH_START_ADDR);//从指定页的地址读FLASH
GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上)
//主循环
while(1){
//示例4:有锁存按键控制LED操作
if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
delay_ms(20); //延时20ms去抖动
if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平
//在2个LED上显示二进制加法
a++; //变量加1
if(a>3){ //当变量大于3时清0
a=0;
}
GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上)
FLASH_W(FLASH_START_ADDR,a); //从指定页的地址写入FLASH
while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开
}
}
}
}
注意: