历史上的今天
今天是:2024年10月18日(星期五)
2021年10月18日 | stm32专题一:GPIO输出—点亮LED
2021-10-18 来源:eefocus
新建led文件夹和bsp_led.c和bsp_led.h的板级支持包。
在bsp_led.c中,函数LED_GPIO_Config(void)提供了gpio的初始化过程:
定义GPIO初始化结构体;
开启RCC时钟,这一步非常重要,要找到对应的总线和外设时钟;
给初始化结构体成员赋值,由于和硬件相关,都在bsp_led.h中定义成宏,提高可移植性。
bsp_led.c
// bsp: board support package 板级支持包
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
// 定义GPIO初始化结构体
GPIO_InitTypeDef GPIO_InitStruct;
// 开启RCC时钟,非常关键
RCC_APB2PeriphClockCmd(LED_R_GPIO_CLK | LED_G_GPIO_CLK | LED_B_GPIO_CLK, ENABLE);
// 配置初始化结构体,传入具体参数
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
// 初始化3个LED灯的GPIO
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_PIN;
GPIO_Init(LED_R_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = LED_B_GPIO_PIN;
GPIO_Init(LED_B_GPIO_PORT, &GPIO_InitStruct);
// 初始状态关闭所有LED灯
GPIO_SetBits(LED_R_GPIO_PORT, LED_R_GPIO_PIN);
GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
GPIO_SetBits(LED_B_GPIO_PORT, LED_B_GPIO_PIN);
}
在bsp_led.h中,大量使用了宏定义,来封装硬件相关的函数
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
#define LED_G_GPIO_PIN GPIO_Pin_0
#define LED_G_GPIO_PORT GPIOB
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB
#define LED_B_GPIO_PIN GPIO_Pin_1
#define LED_B_GPIO_PORT GPIOB
#define LED_B_GPIO_CLK RCC_APB2Periph_GPIOB
// 直接操作寄存器的方法控制IO
#define digitalHi(port, pin) do {port->BSRR |= pin;} while (0) // 置位
#define digitalLo(port, pin) do {port->BRR |= pin;} while (0) // 复位
#define digitalToggle(port, pin) do {port->ODR ^= pin;} while (0) // 反转
// 定义控制IO的宏
#define LED_R_TOGGLE digitalToggle(LED_R_GPIO_PORT, LED_R_GPIO_PIN)
#define LED_R_ON digitalLo(LED_R_GPIO_PORT, LED_R_GPIO_PIN)
#define LED_R_OFF digitalHi(LED_R_GPIO_PORT, LED_R_GPIO_PIN)
#define LED_G_TOGGLE digitalToggle(LED_G_GPIO_PORT, LED_G_GPIO_PIN)
#define LED_G_ON digitalLo(LED_G_GPIO_PORT, LED_G_GPIO_PIN)
#define LED_G_OFF digitalHi(LED_G_GPIO_PORT, LED_G_GPIO_PIN)
#define LED_B_TOGGLE digitalToggle(LED_B_GPIO_PORT, LED_B_GPIO_PIN)
#define LED_B_ON digitalLo(LED_B_GPIO_PORT, LED_B_GPIO_PIN)
#define LED_B_OFF digitalHi(LED_B_GPIO_PORT, LED_B_GPIO_PIN)
// 颜色设置
#define LED_RED do {LED_R_ON; LED_G_OFF; LED_B_OFF;} while (0)
#define LED_GREEN do {LED_R_OFF; LED_G_ON; LED_B_OFF;} while (0)
#define LED_BLUE do {LED_R_OFF; LED_G_OFF; LED_B_ON;} while (0)
#define LED_YELLOW do {LED_R_ON; LED_G_ON; LED_B_OFF;} while (0)
#define LED_PURPLE do {LED_R_ON; LED_G_OFF; LED_B_ON;} while (0)
#define LED_CYAN do {LED_R_OFF; LED_G_ON; LED_B_ON;} while (0)
#define LED_ALL_ON do {LED_R_ON; LED_G_ON; LED_B_ON;} while (0)
#define LED_ALL_OFF do {LED_R_OFF; LED_G_OFF; LED_B_OFF;} while (0)
void LED_GPIO_Config(void);
#endif /* __BSP_LED_H */
然后在主函数中进行调用
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
void delay(uint32_t count);
int main(void)
{
LED_GPIO_Config();
while (1)
{
LED_CYAN;
delay(0XFFFFF);
LED_ALL_OFF;
delay(0XFFFFF);
}
}
void delay(uint32_t count)
{
for (; count != 0; count--);
}
GPIO具有锁定机制,可以冻结该GPIO的配置,即在下次复位前,不能更改GPIO的配置。

锁定操作的寄存器为GPIOx_LCKR,具体描述如下

上面的说明起始我感觉挺难理解的,于是找到了标准库里面的源码,发现写的非常清晰,具体如下
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
uint32_t tmp = 0x00010000;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
tmp |= GPIO_Pin;
/* Set LCKK bit */
GPIOx->LCKR = tmp;
/* Reset LCKK bit */
GPIOx->LCKR = GPIO_Pin;
/* Set LCKK bit */
GPIOx->LCKR = tmp;
/* Read LCKK bit*/
tmp = GPIOx->LCKR;
/* Read LCKK bit*/
tmp = GPIOx->LCKR;
}
tmp为LCCK位置1,然后把GPIO_Pin的相应值也置1。接下来就是对相应的位执行写入序列操作。
首先是写1,即写入带LCCK和GPIO_Pin的位;
然后写0,写只带GPIO_Pin的位;
然后重复写1;
接下来读GPIOx_LCKR的值到tmp,连续读取两次,完成操作。
史海拾趣
|
最近用VHDL编程,发现有很多时候遇到《Error (10327): VHDL error at and2.vhd(11): can\'t determine definition of operator \"\"+\"\" -- found 0 possible definitions》这样的问题,开始不知道为什么,后来在知道不同的数据类型的运算是定义在 ...… 查看全部问答> |
|
原来我的9650输出图像时30万像素的,可以正常显示图像。 可是我从代理要到了130万像素的配置后,图像发红,而且是很红。 不知道有没有遇到这种情况的?是如何解决的?… 查看全部问答> |
|
要想让你的问题尽快得到解答,我想以下几条是你应该注意的: 1.首先说清楚你使用的软,硬件平台。比如:我使用wince5.0在 2440上做开发... 2.问题要尽量具体,不要问诸如:我要做一个什么项目,该怎么做?或者我要做一个什么软件,该怎么做这类的 ...… 查看全部问答> |
|
我用的uversion4,lm3s8962的芯片。 我建立一个全局变量 uchar a[9000]100]; 按道理应该超过ram的容量了,但是怎么编译后不报错呢?如何才知道内存有没有超?… 查看全部问答> |
|
replyreload += \',\' + 1365593;这份报告是基于一个8W LED驱动电源临时做的一个基本范例,是考虑有公司商业机密的问题,略作修改: 1.不对版权负责,只供参考. 2.不对内容负责,不做解释.每家公司各不相同,难于解释不同.敬请谅解. Timson,如果您要 ...… 查看全部问答> |
|
我用AD采样,然后想通过串口发出,结果只能得到FF。大家帮我看看那里出现了问题,谢谢 #include \"msp430g2553.h\" #define uchar unsigned char long temp; void uart_init(void) { BCSCTL1 = CAL ...… 查看全部问答> |




