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 之后就等于 0X42000000, 0X42000000 是外设别名区的起始地址。如
果是 SRAM,则取出的是 2, +0X02000000 之后就等于 0X22000000, 0X22000000 是 SRAM 别名
区的起始地址
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律