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

1. 项目

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

  例如,sbit P0^0 = 0 

     LED1 = P0^0; 

2. 代码

  main.c

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//头文件
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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 别名
    区的起始地址

 

posted @   JRS077  阅读(745)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示