STM32f103精英版之用寄存器实现按键控制led流水灯的流向

1.前言

2020.11.29,用正点原子的STM32f103精英版做寄存器
实现按键控制led流水灯的流向的实验,遇到很多坑,还是写一下缓解我这想哭的心情。

2.环境+stm32f103ZET6精英版用到的引脚介绍

MDK
正点原子stm32f103zet6,
led灯---PE5 和PB5 是两个led灯  -->低电平有效
key0  -- PE4    -->低电平有效

3.遇到的问题

1.key0的模式设置不对到底用那个模式
2.led就两个,怎么看到底是那个流向是什么
3.u8 变量      导致一些低级问题。
4.按键到底是不是生效了,什么时机按下。

4.全部代码(测试调通代码,还没优化)

例如:按键消抖我都还没+。

/*
按键控制灯的循环闪烁

ke0  --pe4--低电平有效
key1 --pe3

BSRR -   RESET   set
BRR - 保留 RESET
ODR - 保留 对应输出。
//模式设置寄存器。
CRL  低位0-7
CRH
*/


#include "stm32f10x.h"
//#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
void Key_Init(void);
int key_Scan(void);


void delay_nms(u16 time);   //毫秒延时。
int main(void){
	u8 inputDataBit=1;
	int flag=-1;
	

	//开启GPIO时钟
	
	RCC->APB2ENR |=1<<3;//开启 GPIOB
	RCC->APB2ENR |=1<<6;//开启 GPIOE
	
	//先清零PIN5
	GPIOB->CRL &=0xff0fffff;
	GPIOE->CRL &=0xff0fffff;
	
	//设置pin5的输出模式--复用推挽输出 50MHz
	GPIOB->CRL |=0x00300000;

	GPIOE->CRL |=0X00300000;
	
	//按键设置成输入模式---1000 --8;
	Key_Init();
	

	
	//这是置 PE5,PB5 为高电平。
	GPIOE->ODR|=1<<5;
	GPIOB->ODR|=1<<5;
	
	//GPIOE->ODR|=0xffdf;   --这样不对呀。   或上一个0 就相当于没有操作呀。
	
	//GPIOE->BRR|=0x0020;
	//GPIOB->ODR=~(1<<5);  

	while(1){
	
		if(key_Scan()){
			flag=!flag;
		
		}
		
			
				/*
				delay_nms(10);
				if(inputDataBit==1){
					while(inputDataBit);
						//这里表示按下一次,
						flag=!flag;
				
				
				}
				*/
			
			

				
			//也就说,这里的逻辑对了,
			if(flag==1){

				
				//快速
					GPIOE->ODR|=1<<5;
					GPIOB->ODR=~(1<<5); 
					delay_nms(100);
					GPIOB->ODR|=1<<5;
					GPIOE->BRR|=0x0020;
					delay_nms(100);
				
				
				
			
			
			}else if(flag==-1){

				
				//这是从绿到蓝。 慢速。
								
					GPIOB->ODR|=1<<5;
					GPIOE->BRR|=0x0020;
					delay_nms(500);
					GPIOE->ODR|=1<<5;
					GPIOB->ODR=~(1<<5); 
					delay_nms(500);
				
		
			
			}

			
			
			
					
	}
	
	
	
	
	
	
}

int key_Scan(void){
	//按下了,我们就返回一个1.
	
		if(!GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)){
				return 1;
			
			} else{
				return 0;
			
			} 




}
			
				


void delay_nms(u16 time) //延时子程序
{
	u16 i=0;
	while(time--){
	i=12000;
	while(i--);
	
	}


}


void Key_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
	

	//开启GPIOE 的时钟
	RCC->APB2ENR |=1<<6;
	//设置PE4/3 为输出,默认下拉
	
	GPIOE->CRL&=0xfff0ffff;//PE4;  -->
	GPIOE->CRL|=0x00040000;   //-->   设置为浮空输入。
	
	
	
	
}

5.问题分析

1.key0的模式设置不对到底用那个模式
看最后:开始我是使用GPIOE->CRL|=0x00080000; 设置为上拉/下拉输入,**具体是上拉下拉,还得看PxODR寄存器的状态。**所以还是又改成浮空输入:
对这两个进行区分:
自己理解。自己理解
网上: https://www.21ic.com/app/mcu/201808/780648.htm
在这里插入图片描述
所以这里做按键的时候,应该选择浮空输入。

//
void Key_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
	

	//开启GPIOE 的时钟
	RCC->APB2ENR |=1<<6;
	//设置PE4/3 为输出,默认下拉
	
	GPIOE->CRL&=0xfff0ffff;//PE4;  -->
	//看这里1。
	GPIOE->CRL|=0x00040000;   //-->   设置为浮空输入。
	
	
	
	
}

2.led就两个,怎么看到底是那个流向是什么
本来就两个led 很容易看不明白。所以
选择两种状态切换频率。(用时间来控制,)

if(flag==1){

				
				//快速
					GPIOE->ODR|=1<<5;
					GPIOB->ODR=~(1<<5); 
					delay_nms(100);
					GPIOB->ODR|=1<<5;
					GPIOE->BRR|=0x0020;
					delay_nms(100);
				
				
				
			
			
			}else if(flag==-1){

				
				//这是从绿到蓝。 慢速。
								
					GPIOB->ODR|=1<<5;
					GPIOE->BRR|=0x0020;
					delay_nms(500);
					GPIOE->ODR|=1<<5;
					GPIOB->ODR=~(1<<5); 
					delay_nms(500);
				
		
			
			}

3.u8 变量 导致一些低级问题。
unsigned 是无符号的,记得不要有 -1,之类的 例如 led = !led 这是错的 。

4.按键到底是不是生效了,什么时机按下。
这个问题也是大问题,因为采用查询的方法,所以一定要在key_Scan()指令执行之前进行按下。

6.存在问题:

1.还是不能从高频率变回来。

7.还是好好学学中断,用中断来进行控制

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以为您介绍一下STM32F103按键流水灯的基本概念和实现方法。 一、概念 STM32F103按键流水灯是一个常见的嵌入式系统项目,它利用STM32F103微控制器的I/O口和按键接口,实现了一种动态的LED灯效果。具体来说,就是当按下某个按键时,LED灯会依次亮起,仿佛水流一样流动。这种效果可以用于各种嵌入式应用中,如智能家居、工业控制等。 二、实现方法 1. 硬件准备 你需要准备以下硬件: * STM32F103微控制器(如STM32F103C8T6) * LED灯(至少4个) * 按键(至少一个) * 杜邦线(用于连接微控制器和LED灯) * 面包板(用于连接按键) 2. 代码编写 首先,你需要编写一个简单的C语言程序来控制LED灯和按键。以下是一个基本的示例代码: ```c #include "stm32f1xx.h" // 引入STM32库文件 #define KEY_PIN 0 // 按键连接到微控制器的第0号GPIO口 #define LED_PIN 1 // LED灯连接到微控制器的第1号GPIO口 int main(void) { while(1) { // 无限循环 if(GPIO_ReadInputDataBit(GPIOA, KEY_PIN) == Bit_RESET) { // 检测按键按下 for(int i=0; i<4; i++) { // 依次点亮LED灯 GPIO_SetBits(GPIOA, LED_PIN); // 点亮LED灯 delay(100); // 延时一段时间,模拟水流流动效果 GPIO_ResetBits(GPIOA, LED_PIN); // 熄灭LED灯 } } } } ``` 这段代码使用STM32F1xx库函数来控制GPIO口和按键,并通过循环检测按键状态来控制LED灯的亮灭。当按下按键时,LED灯会依次亮起并熄灭,形成流水灯效果。 注意:这段代码只是一个基本的示例,实际应用中可能需要根据你的硬件配置和需求进行修改和优化。 3. 电路连接 将LED灯的引脚连接到微控制器的GPIO口,将按键的引脚连接到面包板或其他绝缘材料上。确保所有连接都正确无误,避免短路等问题。 4. 调试和运行 将代码下载到STM32F103微控制器中,并使用调试器或J-Link等工具进行调试。确保代码正常运行,LED灯能够按照预期的流水灯效果亮灭。 这就是一个基本的STM32F103按键流水灯实现方法。你可以根据自己的需求进行修改和扩展,如添加其他功能、优化性能等。希望这个介绍对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值