菜鳥學STM32之跑馬燈


微信公眾號:小樊Study
關注共同學習,問題或建議,請公眾號留言!!!

作為一名程序員,在初步學習編程想必都繞不開一個最為基礎的入門級示例“Hello World”,那么,在學習單片機時,最基礎的入門示例是什么呢?沒錯,那就是“點亮一盞LED燈”本次將通過一個經典的跑馬燈程序,帶大家開啟 STM32F4 之旅,通過本次的學習,你將了解到 STM32F4 的 IO 口作為輸出使用的方法。
我們將通過代碼控制STM32F4 開發板上的兩個 LED:DS0 和 DS1 交替閃爍,實現類似跑馬燈的效果。

硬件連接

 

 

GPIO工作方式

  • 4種輸入模式:
      輸入浮空
      輸入上拉
      輸入下拉
      模擬輸入

  • 4種輸出模式:
     開漏輸出(帶上拉或者下拉)
     開漏復用功能(帶上拉或者下拉)
     推挽式輸出(帶上拉或者下拉)
     推挽式復用功能(帶上拉或者下拉)

  • 4種最大輸出速度:
      -2MHZ
      -25MHz
      -50MHz
      -100MHz

軟件設計

led.c

#include "led.h" 
//////////////////////////////////////////////////////////////////////////////////     


//初始化PF9和PF10為輸出口.並使能這兩個口的時鍾            
//LED IO初始化
void LED_Init(void)
{         
  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF時鍾

  //GPIOF9,F10初始化設置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1對應IO口
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽輸出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
    
    GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10設置高,燈滅

}

 

該代碼里面就包含了一個函數 void LED_Init(void),該函數的功能就是用來實現配置 PF9和 PF10 為推挽輸出。這里需要注意的是:在配置 STM32 外設的時候,任何時候都要先使能該外設的時鍾!GPIO 是掛載在 AHB1 總線上的外設,在固件庫中對掛載在 AHB1 總線上的外設時鍾使能是通過函數RCC_AHB1PeriphClockCmd ()來實現的。

在設置完時鍾之后,LED_Init 調用 GPIO_Init 函數完成對 PF9 和 PF10 的初始化配置,然后調用函數 GPIO_SetBits 控制 LED0 和 LED1 輸出 1(LED 滅)。至此,兩個 LED 的初始化完畢。這樣就完成了對這兩個 IO 口的初始化。

led.h

#ifndef __LED_H
#define __LED_H
#include "sys.h"

//////////////////////////////////////////////////////////////////////////////////     
                                  
//////////////////////////////////////////////////////////////////////////////////     


//LED端口定義
#define LED0 PFout(9)    // DS0
#define LED1 PFout(10)    // DS1     

void LED_Init(void);//初始化                             
#endif

 

這里使用的是位帶操作來實現操作某個 IO 口的 1 個位的

在 main 函數里面編寫如下代碼:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"


//跑馬燈實驗 -庫函數版本

    
int main(void)
{ 
 
    delay_init(168);          //初始化延時函數
    LED_Init();                //初始化LED端口
  while(1)
    {
     LED0=0;              //LED0亮
       LED1=1;                //LED1滅
         delay_ms(500);
         LED0=1;                //LED0滅
         LED1=0;                //LED1亮
         delay_ms(500);
     }
}

 

代碼包含了#include "led.h"這句,使得 LED0、LED1、LED_Init 等能在 main()函數里被調用。這里我們需要重申的是,在固件庫中,系統在啟動的時候會調用 system_stm32f4xx.c 中的函數SystemInit()對系統時鍾進行初始化,在時鍾初始化完畢之后會調用 main()函數。所以我們不需要再在 main()函數中調用 SystemInit()函數。當然如果有需要重新設置時鍾系統,可以寫自己的時鍾設置代碼,SystemInit()只是將時鍾系統初始化為默認狀態。main()函數非常簡單,先調用 delay_init()初始化延時,接着就是調用 LED_Init()來初始化GPIOF.9 和 GPIOF.10 為輸出。最后在死循環里面實現 LED0 和 LED1 交替閃爍,間隔為 500ms。

然后按

編譯工程

可以看到沒有錯誤,也沒有警告。從編譯信息可以看出,我們的代碼占用 FLASH 大小為:5672 字節(5248+424),所用的 SRAM 大小為:1880 個字節(1832+48)。這里我們解釋一下,編譯結果里面的幾個數據的意義:Code:表示程序所占用 FLASH 的大小(FLASH)。RO-data:即 Read Only-data,表示程序定義的常量(FLASH)。RW-data:即 Read Write-data,表示已被初始化的變量(SRAM)ZI-data:即 Zero Init-data,表示未被初始化的變量(SRAM)有了這個就可以知道你當前使用的 flash 和 sram 大小了,所以,一定要注意的是程序的大小不是.hex 文件的大小,而是編譯后的 Code 和 RO-data 之和。

下載驗證

下載完之后,LED0 和 LED1 循環閃爍


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM