STM32 实战之点亮LED

简介: STM32 实战之点亮LED

1-编写第一个程序点亮LED灯

下面是原理图,连接的是PC0-PC7引脚:


1static void Led_Cofig(void)
 2{
 3    /*定义一个GPIO_InitTypeDef类型的结构体*/
 4    GPIO_InitTypeDef GPIO_InitStructure;
 5    /*开启LED相关的GPIO外设时钟*/
 6    RCC_APB2PeriphClockCmd(LED_GPIO_CLCK, ENABLE);
 7    /*选择要控制的GPIO引脚*/
 8    GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;
 9    /*设置引脚模式为通用推挽输出*/
10    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
11    /*设置引脚速率为50MHz */
12    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //(指的是内部驱动电路的响应速度,速度越大越快,一般情况是有多个不同的速度,也可根据自己的需要安排)
13    GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);
14    /* 关闭led灯    */
15    GPIO_SetBits(LED_GPIO_PORT,  LED1_GPIO_PIN);
16}


1/*LED连接GPIO的定义,程序开发者如果要修改引脚只需要修改这里就好*/
 2#define LED_GPIO_PORT GPIOC                // GPIO端口定义,为了方便修改
 3#define LED_GPIO_CLCK RCC_APB2Periph_GPIOC /* GPIO端口时钟 */
 4/*GPIO引脚*/
 5#define LED1_GPIO_PIN GPIO_Pin_0
 6#define LED2_GPIO_PIN GPIO_Pin_1
 7#define LED3_GPIO_PIN GPIO_Pin_2
 8#define LED4_GPIO_PIN GPIO_Pin_3
 9#define LED5_GPIO_PIN GPIO_Pin_4
10#define LED6_GPIO_PIN GPIO_Pin_5
11#define LED7_GPIO_PIN GPIO_Pin_6
12#define LED8_GPIO_PIN GPIO_Pin_7


2-代码说明

1:

GPIO_InitTypeDef GPIO_InitStructure 语句是声明一个结构体GPIO_InitStructure结构体原型由GPIO_InitTypeDef确定(这点是C语言的基础知识)设置完之后就可以对GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);进行操作。
2:

GPIO_SetBits()是库函数,可以对多个I/O口同时置1。

这里还有一个GPIO_ResetBits()库函数,可以对多个I/O口置0。

注释和工程添加就不说了,网上相关的也挺多的。

GPIO_InitStructure.XXXX后面的speed什么的也不说了,不知道的可以去STM32知识篇看看。这里主要讲述函数配置什么的,毕竟是实战嘛,指定是不能都介绍的。

3-main函数

1int main()
2{
3  LED_Init();
4  while (1)
5  {
6
7    GPIO_ResetBits(LED_GPIO_PORT, LED1_GPIO_PIN);
8  }
9}

因为接的是正极,点亮LED灯两端需要电压差,所以在这里使用GPIO_ResetBits才能点亮,如果你的一端接的是地,则是使用GPIO_SetBits。这点要知道。就是不管是哪种器件,只有保持电压差才能进行一个数据的接收,灯的点亮,我认为是这样的,可以说是所有的元器件芯片都是这样的,但不是绝对的,只能说大部分。

上面点亮之后,我们这样感觉修改太麻烦。可以在头文件之后对其设置一个宏定义函数,如下:

1/*标准库点亮LED灯*/
2/*当a=0时,LED灯灭,当LED=1时,LED灯亮*/
3#define LED1(a)                                       \
4    if (a)                                            \
5    {                                                 \
6        GPIO_ResetBits(LED_GPIO_PORT, LED1_GPIO_PIN); \
7    }                                                 \
8    else                                              \
9        GPIO_SetBits(LED_GPIO_PORT, LED1_GPIO_PIN);

当a=1时,灯亮,0时灯灭。

1int main()
2{
3  LED_Init();
4  while (1)
5  {
6    //GPIO_ResetBits(LED_GPIO_PORT,LED1_GPIO_PIN);
7    LED1(1);
8  }
9}


最后来个视频:

image.png

下面说一说位操作,这是嵌入式开发中最常用的。

5-位操作

什么是位操作,我认为位操作就是吃羊肉串,从前面吃,从后面吃,从中间吃这样的。但是官方说法比我这好听。其实位操作操作的是二进制或者十六进制这样的,你看像不像你在吃羊肉串,比如二进制0b0000 0001,你看从后面读取就相当于你从后面开始吃羊肉串。下面说正经的、

640.png

我们对上面这个表进行一些介绍和使用说明

1. 在不改变其他位的状况下,对某几个位赋值

针对这种情况,应该怎么做才能实现对某几个位赋值呢?我们可以把“&”和“|”两个位操作结合起来使用,步骤如下。

(1)先对需要设置的位用“&”操作符进行清零操作。

(2)再用“|”操作符赋值。

例如,在初始化时,若配置PD8引脚为推挽输出、速度为50 MHz,需将GPIOD->CRH的0~3位设置为3(即二进制0011B),这时可先对寄存器的0~3位进行“&”清零操作。


1GPIOD->CRH&=0Xfffffff0;      //清掉原来的设置,同时不影响其他位设置

然后再与需要设置的值进行“|”运算:

1GPIOD->CRH|=0X00000003;     //设置0~3 位的值为3,不改变其他位的值


2. 使用移位操作,提高代码的可读性

移位操作在STM32程序开发中也非常重要。比如在初始化时,若需要使能GPIOD口的时钟,就可使用移位操作来实现,使能PORTD时钟的语句是:

1RCC->APB2ENR|=1<<5;

使能GPIOD和GPIOE口时钟的语句是:

1RCC->APB2ENR|=3<<5;

这个左移位操作,就是将RCC->APB2ENR寄存器的第5位设置为1,使能PORTD时钟。为什么要通过左移而不是直接设置一个固定的值来对寄存器进行操作呢?其实,这样做是为了提高代码的可读性以及可重用性。读者可以很直观明了地看到,这行代码是将第5位设置为1。如果写成:

1RCC->APB2ENR =0x00000020;

但是这样代码写出来不太友好,首先是不可重复使用,其次真烦呀。反正这种挺多的,大家可以自己多练练。

3. 取反位操作的应用

SR寄存器的每一位都代表一个状态。在某个时刻,我们希望设置某一位为0,同时其他位都保留为1,简单的做法是直接给寄存器设置一个值。


1TIMx->SR=0xF7FF;

上述代码设置第11位为0,但代码可读性不太友好。但是我们可以这样写:

1#define TIM_FLAG_Update   ((uint16_t)0x0001)
2TIMx->SR &=~(TIM_FLAG_Update <<11);

从上面的代码中,我们可以从第一条语句看出,宏定义了TIM_FLAG_Update第0位是1,其他位是0;第二条语句让TIM_FLAG_Update左移11位取反,第11位就为0,其他位都为1;最后通过按位与操作,使第11位为0,其他位保持不变。这样,读者就能很容易地看明白代码,所以代码的可读性也就非常强的。

今天就到这里了,有关位的部分STM32知识篇也介绍过,有兴趣的可以去看看。

相关文章
|
11月前
|
存储 数据安全/隐私保护
STM32实战项目—密码锁
本文完整详细地介绍了一个密码锁项目的要求,设计思路,程序实现,问题总结和成果展示内容。
221 2
STM32实战项目—密码锁
|
11月前
|
芯片
最详细STM32,cubeMX 按键点亮 led
最详细STM32,cubeMX 按键点亮 led
175 0
|
11月前
|
传感器 芯片
最详细STM32,cubeMX 点亮 led
最详细STM32,cubeMX 点亮 led
132 0
|
3月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
235 2
|
2月前
STM32CubeMX FreeRTOS点亮LED
STM32CubeMX FreeRTOS点亮LED
54 10
|
2月前
STM32CubeMX 按键控制LED
STM32CubeMX 按键控制LED
36 0
|
2月前
STM32CubeMX 点亮LED
STM32CubeMX 点亮LED
42 0
|
2月前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。
|
11月前
|
存储 索引
STM32实战项目—停车计费系统
本文详细介绍了一个停车计费系统的任务要求,实现思路。最后,给出了详细的程序设计和测试结果。
221 2
STM32实战项目—停车计费系统
|
11月前
STM32实战项目—楼宇人员计数系统
本文介绍了一个基于红外对管的楼宇人员计数系统设计。简单介绍了一下红外对管的原理和使用方法。针对任务要求给出了详细的实现思路和程序设计。
84 3
STM32实战项目—楼宇人员计数系统