GPIO位带操作点亮LED,且使用按键控制开关

1. 项目

  类似与C51单片机的位操作使能引脚来点亮LED.

  例如,sbit P0^0 = 0 

     LED1 = P0^0; 

2. 代码

  main.c

  

#include "stm32f10x.h"			//相当于51单片机中的 	#include <reg51.h>
#include "bsp_key.h"
#include "bsp_led.h"

#define GPIOB_ODR_Addr		(GPIOB_BASE + 0x0c)
#define PBout(n)					*(unsigned int*)((GPIOB_ODR_Addr & 0xf0000000) + 0x02000000 + ((GPIOB_ODR_Addr &0x00ffffff)<<5) + (n<<2))

#define GPIOC_IDR_Addr		(GPIOC_BASE + 0x08)
#define PCin(n)					*(unsigned int*)((GPIOC_IDR_Addr & 0xf0000000) + 0x02000000 + ((GPIOC_IDR_Addr &0x00ffffff)<<5) + (n<<2))

void Delay(uint32_t count)
{
	for(; count!=0; count--);
}

int main(void)
{
	//来到这里是,系统的时钟已经被配置到72MHz了
	LED_GPIO_Config();
	KEY_GPIO_Config();	//初始化KEY函数
#if 0	//GPIO输出
	while(1)
	{
		PBout(5) = 1;
		Delay(0xfffff);

		PBout(5) = 0;
		Delay(0xfffff);
		
	}
#else	//GPIO输入
		while(1)
	{		
			if(PCin(13) == KEY_ON)
			{
				while(PCin(13) == KEY_ON);
				LED_R_TOGGLE;
			}
		
	}
#endif

}

  

  bsp_led.c

//bsp: board support package板机支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(LED_R_GPIO_CLK, ENABLE);
	GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_PIN; 	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(LED_R_GPIO_PORT, &GPIO_InitStruct);
}

  

  bsp_led.h

//头文件
#ifndef __bsp_led_h
#define __bsp_led_h

#include "stm32f10x.h"

#define LED_R_GPIO_PIN						GPIO_Pin_5
#define LED_R_GPIO_PORT					GPIOB
#define LED_R_GPIO_CLK						RCC_APB2Periph_GPIOB

//C语言中的二进制运算符
//与1异或改变,与0异或不变

#define LED_R_TOGGLE				{LED_R_GPIO_PORT->ODR ^= LED_R_GPIO_PIN;}
void LED_GPIO_Config(void);
#endif /*__bsp_led._h*/

  

  bsp_key.c

#include "bsp_key.h"
void KEY_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;	
	RCC_APB2PeriphClockCmd(KEY2_GPIO_CLK, ENABLE);
	GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
	
}


uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
	if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON )
	{
		//松手检测
		while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
		return KEY_ON;
	}
	else return KEY_OFF;
}

  

  bsp_key.h

#ifndef __bsp_key_h
#define __bsp_key_h

#include "stm32f10x.h"

#define KEY_ON				1
#define KEY_OFF				0

#define KEY2_GPIO_PIN						GPIO_Pin_13
#define KEY2_GPIO_PORT					GPIOC
#define KEY2_GPIO_CLK						RCC_APB2Periph_GPIOC

void KEY_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
#endif/*__bsp_key_h*/

3. 参考资料

  •   原理图
  •  

      addr & 0xF0000000 是为了区别 SRAM 还是外设,实际效果就是取出 4 或者 2,如果是外设,则

    取出的是 4+0X02000000 之后就等于 0X420000000X42000000 是外设别名区的起始地址。如
    果是 SRAM,则取出的是 2+0X02000000 之后就等于 0X220000000X22000000 SRAM 别名
    区的起始地址

原文地址:https://www.cnblogs.com/kevin-hou1991/p/15435606.html