0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32单片机点亮LED灯

CHANBAEK 来源:南山府嵌入式 作者:南山府嵌入式 2023-03-01 17:20 次阅读

最近公司事情太多了,将近一个月没有更新了。 我的想法是把我用到的所有单片机都更新一下(当然不局限于这些,后期也会更新一些其他和嵌入式相关的知识点,我就想着先把STM32这整个更新完,再去更新其他的,包括STM32下 RTOS、UI(emwin,LVGL)还有一些项目上的经验什么的。 等STM32相关的更新完之后会写其他的东西。 也会根据实际的情况进行其他内容的更新:我用过STM32 CH32、HC32F4、S32K148等,还有各种传感器啥的。

从本章节开始我们进行一个STM32实战操作,为此我还特意画了个简单的板子。 是物联网相关的,后面会设计一个BMS的板子来写一下。

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}

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

5-位操作

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

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

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

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

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

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

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

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

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

1GPIOD->CRH|=0X00000003;     //设置0~3 位的值为3,不改变其他位的值
  1. 使用移位操作,提高代码的可读性

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

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

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

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

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

1RCC->APB2ENR =0x00000020;

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

  1. 取反位操作的应用

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,其他位保持不变。 这样,读者就能很容易地看明白代码,所以代码的可读性也就非常强的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6035

    文章

    44554

    浏览量

    634653
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304816
  • led灯
    +关注

    关注

    22

    文章

    1592

    浏览量

    107950
  • STM32
    +关注

    关注

    2270

    文章

    10895

    浏览量

    355743
  • RTOS
    +关注

    关注

    22

    文章

    811

    浏览量

    119595
收藏 人收藏

    评论

    相关推荐

    单片机入门之点亮LED

    上一章中我们已经认识了单片机,并且完成了开发环境的搭建,这章中我们正式开始进入单片机编程的学习,本章的学习目标是 点亮一盏LED
    发表于 06-26 15:38 2623次阅读
    <b class='flag-5'>单片机</b>入门之<b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    如何点亮51单片机LED

    如何点亮51单片机LED
    发表于 11-04 07:36

    请问51单片机/STM32单片机/嵌入式Linux是如何点亮LED的?

    请问51单片机/STM32单片机/嵌入式Linux是如何点亮LED的?
    发表于 11-22 07:44

    LED点亮程序

    LED点亮程序,适合初学者使用,单片机c语言程序。
    发表于 03-15 10:42 6次下载

    使用51单片机Keil工程建立点亮LED的详细教程说明

    本文档的主要内容详细介绍的是使用51单片机Keil工程建立点亮LED的详细教程说明。
    发表于 07-17 17:39 2次下载
    使用51<b class='flag-5'>单片机</b>Keil工程建立<b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>的详细教程说明

    如何使用单片机点亮LED

    我们学单片机,第一个程序就是点亮一盏LED,那么我单片机开启面向对象方式的第一步也是点亮一盏
    发表于 07-16 17:39 4次下载
    如何使用<b class='flag-5'>单片机</b><b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    单片机控制LED点亮的实验资料说明

    本文档的主要内容详细介绍的是单片机控制LED点亮的实验资料说明
    发表于 07-01 16:49 17次下载
    <b class='flag-5'>单片机</b>控制<b class='flag-5'>LED</b><b class='flag-5'>灯</b><b class='flag-5'>点亮</b>的实验资料说明

    使用单片机点亮LED的程序和工程文件免费下载

    本文档的主要内容详细介绍的是使用单片机点亮LED的程序和工程文件免费下载。
    发表于 09-25 17:33 15次下载
    使用<b class='flag-5'>单片机</b><b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>的程序和工程文件免费下载

    51单片机——LED点亮

    点亮LED原理单片机点亮LED 利用LED阳极为正阴极为负才会导通
    发表于 11-11 19:21 19次下载
    51<b class='flag-5'>单片机</b>——<b class='flag-5'>LED</b><b class='flag-5'>灯</b>的<b class='flag-5'>点亮</b>

    【蓝桥杯】单片机学习(2)——点亮LED

    为例,下同)#include "reg52.h" //此文件中定义了一些特殊功能寄存器sbit led=P2^0; //将单片机的P2.0端口定义为ledvoid main(){ while(1) { led=0; //P
    发表于 11-14 12:21 0次下载
    【蓝桥杯】<b class='flag-5'>单片机</b>学习(2)——<b class='flag-5'>点亮</b><b class='flag-5'>LED</b>小<b class='flag-5'>灯</b>

    单片机零基础入门(1):点亮1个LED

    单片机入门,相信大家都知道,都是用代码点亮第一个LED开始的吧。单片机简单在于,只需要0和1就控制单片
    发表于 11-18 15:21 15次下载
    <b class='flag-5'>单片机</b>零基础入门(1):<b class='flag-5'>点亮</b>1个<b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    51单片机---点亮LED

    )单片机编程/***点亮一颗***/sbit LED1 = P1^0; //位定义sbit 标识符 = 地址值 地址中的'P'要大写...
    发表于 11-20 19:06 3次下载
    51<b class='flag-5'>单片机</b>---<b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    51单片机——点亮一个LED

    51单片机——点亮一个LED文章目录51单片机——点亮一个
    发表于 11-23 18:06 16次下载
    51<b class='flag-5'>单片机</b>——<b class='flag-5'>点亮</b>一个<b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    基于单片机点亮LED

    单片机点亮LED就像用C语言输出“hello world”一样,是入门的第一课。
    的头像 发表于 05-24 14:25 1818次阅读
    基于<b class='flag-5'>单片机</b><b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>

    基于51单片机点亮LED

    入门51单片机第一步,就是学会点亮一个LED,这是所有初次接触单片机开发的小伙伴的必经之路,管你现在是不是大牛,当年肯定历经此事。
    发表于 07-11 11:38 1754次阅读
    基于51<b class='flag-5'>单片机</b><b class='flag-5'>点亮</b><b class='flag-5'>LED</b><b class='flag-5'>灯</b>