STM32学习笔记(六)

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)); //等待按键松开 
			}
		}
	}
}

注意:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值