按照上一小节的内容,我们已经能点亮LED了。同样的,把它熄灭非常简单:把对应GPIO设置为低电平即可。回忆上次的内容,想一下那个单刀双掷开关,对吧?

快速开始

结合一下,我们可以得到这样的思路:PD12设置为高电平

PD12设置为低电平

执行步骤1,循环往复

这样的话,我们的灯就会闪烁起来了。至少理论上是这样的。用于设置GPIO低电平的函数和设置高电平的函数用法类似:

GPIO_ResetBits(GPIOD, GPIO_Pin_12);

上面代码即可将PD12设置为低电平,来我们对比一下将PD12设置为高电平的写法:

GPIO_SetBits(GPIOD, GPIO_Pin_12);

可以很明显的感觉到,它们基本是一样的。我们把这两个代码组合一下,按照我们的思路,很容易写出:

while (1)

{

GPIO_SetBits(GPIOD, GPIO_Pin_12);

GPIO_ResetBits(GPIOD, GPIO_Pin_12);

}

这样的话,理论上PD12就会高低电平频繁切换,我们也就能看到LED闪烁起来了。如果你不知道如何组合代码可以参照下图:

好,首先编译,然后下载,最后按下板子的复位键。看到灯闪了吗?如果没问题的话......

看到灯闪了吗?没有?至少我是没有(理论上来说还是可以看到灯亮起的)。

看不到闪烁的原因?

我们一步步的来。检查我们的思路,是否有误:循环切换PD12的高低电平,高电平时候LED亮,低电平的时候LED灭,因此可以实现闪烁

思路,很显然没问题。其次,是板子烧掉了吗?比如没法输出低电平?我找来了一个简陋的示波器(啊啊其实是因为自己穷啊,压根不是因为别的),观察PD12的波形:PD12的波形,纵向一格是1V,横向一格是0.1us

很明显,虽然波形有很明显的变形,但是依旧是先高电平(表现在矩形波上升到最高,然后持平),然后切换为低电平(即波形和x轴重合)。这说明,PD12正如我们期望中的,先输出高电平,然后切换为低电平,然后再切换为高电平...即,芯片是正常的。

注意了一点,横向的一格是0.1us,而高低电平切换一次(一个周期)的时间只有0.3us左右...

稍微玩点游戏的读者应该知道,我们游戏一般是垂直同步在60帧,此时已经几乎不可能感觉得到卡顿了。也就是1/60 ≈ 16.667ms。而我们的LED闪烁频率是每秒钟闪烁三百万次以上...换句话说,人眼压根不可能看得到这个LED在闪。

评论区 @Rivers-Jin 提醒,查证了下,LED的响应速度也确实也没有这么高,所以本身它也不见得反应不过来。

解决方案

总归,人眼看不到我们的LED在闪烁,那么我们延长高电平的时间,也延长低电平的时间不就好了?如此一来,思路就变成这样了:PD12设置为高电平

等待一段时间

PD12设置为低电平

等待一段时间

回到步骤1,循环往复

那么现在主要问题就在于怎么等待了。对于单片机,它只有一个核心的一个CPU,因此可以用一个最简单的方法:等待的时候一直做点什么事情不就完事了,比如一个空循环,循环一百万次:

for (int i = 0; i < 1000000; i += 1)

{

// nothing to do}

我们把它插入到设置高电平完成后和设置低电平设置完成后:

while (1)

{

GPIO_SetBits(GPIOD, GPIO_Pin_12);

for (int i = 0; i < 1000000; i += 1)

{

// nothing to do }

GPIO_ResetBits(GPIOD, GPIO_Pin_12);

for (int i = 0; i < 1000000; i += 1)

{

// nothing to do }

}

整合好你的代码,下载到单片机上运行,应该可以看到LED快速闪烁起来了。如果没有看到,那么就把1000000改大一点,这样就会有更多的等待时间。

我们再测一遍PD12的波形,可以看到高电平持续时间和低电平持续的时间明显长了很多,一个i周期大概有0.15秒:PD12波形,纵向1V每格,横向50ms每格

规范代码

我们的延时部分是一致的,这意味着我们可以把它独立开来,形成一个单独的过程(函数)。例如这样:

// 延时等待// Mcnt表示循环几百万次void delay(int Mcnt)

{

for (int i = 0; i < 1000000 * Mcnt; i += 1)

{

// nothing to do }

}

如此一来,我们就可以把我们的代码变得更加漂亮了。我给程序丰富了点功能,使得四个灯能轮番亮起来,您可以尝试优化这段程序,让它看起来没这么傻:

// 延时等待// Mcnt表示循环几百万次void delay(int Mcnt)

{

for (int i = 0; i < 1000000 * Mcnt; i += 1)

{

// nothing to do }

}

int main(void)

{

// GPID时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

GPIO_InitTypeDef gpioInitInfo;

gpioInitInfo.GPIO_Pin = GPIO_Pin_12 // 要初始化的有12,13,14,15这四个 + GPIO_Pin_13

+ GPIO_Pin_14

+ GPIO_Pin_15;

gpioInitInfo.GPIO_Mode = GPIO_Mode_OUT; // 输出模式 gpioInitInfo.GPIO_OType = GPIO_OType_PP, // 推挽输出 gpioInitInfo.GPIO_PuPd = GPIO_PuPd_NOPULL; // 没有上下拉电阻 gpioInitInfo.GPIO_Speed = GPIO_Speed_100MHz; // 高速模式

GPIO_Init(GPIOD, &gpioInitInfo); // 初始化GPIO, 即PD12, PD13, PD14, PD15

while (1) // 死循环做下面这些事情 {

GPIO_ResetBits(GPIOD, GPIO_Pin_12); // PD12低电平 GPIO_SetBits(GPIOD, GPIO_Pin_13); // PD13高电平

delay(1); // 等待一段时间

GPIO_ResetBits(GPIOD, GPIO_Pin_13); // PD13低电平 GPIO_SetBits(GPIOD, GPIO_Pin_14); // PD14高电平

delay(1); // 等待一段时间

GPIO_ResetBits(GPIOD, GPIO_Pin_14); // PD14低电平 GPIO_SetBits(GPIOD, GPIO_Pin_15); // PD15高电平

delay(1); // 等待一段时间

GPIO_ResetBits(GPIOD, GPIO_Pin_15); // PD15低电平 GPIO_SetBits(GPIOD, GPIO_Pin_12); // PD12高电平

delay(1); // 等待一段时间 }

}

如果运行成功,板子上的四个LED会轮番亮起熄灭。

SUMMARY闪烁LED的思路

人眼看不到那么快的闪烁,因此需要适当延迟。事实上对于电路也是,一些硬件反应不过来,我们也需要适当延迟

未解决的问题似乎没有

F.A.Q.想到/被问到再补充

stm32单片机屏幕一直闪_STM32F407[3] 闪烁LED相关推荐

  1. stm32单片机屏幕一直闪_stm32实现LED灯的闪烁

    stm32单片机设计比较复杂,所以,对于外设的控制就相对于51单片机来说,就复杂很多.那么如何用stm32单片机点亮LED呢?通过一下几个步骤,就可以实现LED的闪烁.这里使用的stm32型号是stm ...

  2. stm32单片机屏幕一直闪_STM32使用HAL库函数点亮OLED

    OLED屏幕应用十分广泛,我们可以使用STM32单片机对其进行控制,使其显示我们需要的各种数字.字母.汉字.图画等.我们此次使用下图这款非常普遍的0.96寸OLED液晶屏.此款OLED屏采用IIC的通 ...

  3. stm32单片机屏幕一直闪_STM32物联网实战项目 - 项目需求

    项目需求 以主流的STM32单片机为主控,GPRS与WIFI为联网模组,配合丰富的外设与接口,设计一款功能齐全的开发板,让学员在学习产品设计的过程中,熟练的掌握STM32单片机的应用. 一.功能需求 ...

  4. stm32单片机屏幕一直闪_用STM32做一个微型掌上示波器项目——终于鼓起在大牛前献丑的无比勇气...

    这是我第一次在这个论坛上发表东西,其实本人进入芯片的世界的时间并不长,从接触51单片机到现在还不到一年,所以可以算是小白啦~想了很久,总算拿出在论坛大牛前献丑的无比勇气,写起该帖:dizzy::diz ...

  5. stm32单片机屏幕一直闪_基于STM32单片机实现屏幕休眠后OLED屏幕滚动效果

    这次做项目时需要实现OLED屏幕上字符滚动的功能,从网上找到一个参考:https://blog.csdn.net/tbmmagic/article/details/111999673 int main ...

  6. stm32单片机屏幕一直闪_STM32单片机常见的工作异常现象分析及解决方案

    贴了两块样板,烧写同样的固件.其中一块工作正常,但是另外一块出现了很奇怪的现象:在线调试正常:每次烧写完后工作正常:重新上电有时候工作正常,有时候工作不正常:工作不正常时,按下复位按键,恢复正常. 工 ...

  7. 计算机屏幕闪烁黑屏,显示器屏幕一闪一闪的黑屏怎么办_电脑屏幕黑屏一闪一闪如何解决...

    显示器使用久了总避免不了遇到一些故障,比如有用户反映说遇到显示器屏幕一闪一闪的,过一会就黑屏的了,这让很多小伙伴很困扰,该怎么处理呢,接下来给大家带来电脑屏幕黑屏一闪一闪的详细解决步骤. 显示器黑屏一 ...

  8. 打开计算机屏幕总是闪,电脑显示器老是闪烁怎么解决

    电脑显示器闪烁的情况,大家或多或少都会遇到,那该怎么办呢?那么下面就由学习啦小编来给你们说说电脑显示器老是闪烁的解决方法吧,希望可以帮到你们哦! 电脑显示器老是闪烁的解决方法一: 一.你的电源工作不稳 ...

  9. STM32单片机怎么学最快?用这个方法只需要一周!

    最近看到很多小伙伴学STM32学的一脸茫然,有些甚至学1年都不会,有些虽然学会了外设使用,一做起项目来无从下手. 那今天通过自己的经历来告诉大家STM32怎么学最快,领悟到了1周学会绝对没问题! 一. ...

最新文章

  1. 实战|手把手教你用Python爬取存储数据,还能自动在Excel中可视化
  2. CTFshow 命令执行 web37
  3. linux误修改文件名恢复,如何在 Linux 中找出最近或今天被修改的文件-linux修改文件名...
  4. VTK:网格之TableBasedClipDataSetWithPolyData2
  5. 201203阶段二FFMPEG图片解码及线程
  6. CF438E:The Child and Binary Tree(生成函数)
  7. oracle集群监听启动,在RAC中lsnrctl和srvctl操作监听区别
  8. 兔子--百度地图所需的jar+so下载地址
  9. 我用Python爬取1000封情书助力室友表白班花,却反转再反转...原来这就是班花的终极秘密!
  10. android的按钮状态,保持android按钮选择状态
  11. dynamic image
  12. css3 flex布局九宫格,css3最全flex布局结构整理
  13. win7 NVMe驱动 SSD固态硬盘 补丁 免重装 DISM++ Windows6.1-KB3087873-v2-x64.msu
  14. CC2530实现流水灯
  15. 1024:为什么这些游戏这么火?
  16. O2O模式成功案例分享 汲取精华化为己用
  17. 小米强制淘汰老破小,苹果华为带了好头
  18. 《计算机网络 自顶向下方法》(第7版)答案(第二章)(二)
  19. 行业洞察丨小微企业信息化管理痛点与解决方案
  20. vue3 腾讯地图输入地址或拖动标记获取经纬度

热门文章

  1. 《从零开始学Swift》学习笔记(Day 10)——运算符是“ +、-、*、/ ”吗?
  2. LAMP中apache的配置步骤
  3. 关于C语言中单双引号的问题
  4. Linux下如何查看哪些端口处于监听状态
  5. 服务器缓存策略(304)
  6. Mach-O 二进制文件解析
  7. golang go get 命令行安装库 报错 go: cannot use path@version syntax in GOPATH mode 解决方法
  8. linux 查看线程数的方法
  9. nginx php-fpm 运行原理
  10. python3 socket 超时设置