天天看點

STM8學習筆記---點亮LED燈

對單片機操作時一般有三個步驟,1.系統時鐘選擇。2.單片機外設初始化。3主程式編寫。

同樣要點亮LED燈時,也要按照這個步驟來。

首先選擇系統時鐘,打開STM8S中文參考手冊,找到時鐘寄存器

STM8學習筆記---點亮LED燈

可以看到時鐘寄存器有13個,那麼該用哪個呢。STM8的主時鐘源有4種,我們要用的是16M内部RC振蕩器。

STM8學習筆記---點亮LED燈

是以隻需要設定主時鐘切換寄存器CLK_SWR寄存器即可。

STM8學習筆記---點亮LED燈

寄存器值為0XE1時,HSI為主時鐘,是以将CLK_SWR值設定為0xE1。

CLK_SWR = 0xe1; //HSI為主時鐘源 16MHz CPU時鐘頻率

然後設定時鐘分頻值

STM8學習筆記---點亮LED燈

時鐘分頻寄存器預設值為0x18也就是8分頻,我們希望單片機16M時鐘運作,不分頻。是以将分頻寄存器的值設定為0。

CLK_CKDIVR = 0x00; //CPU時鐘0分頻,系統時鐘0分頻

為了友善以後程式調用,将系統時鐘設定封裝為一個函數

//系統時鐘初始化
void SysClkInit( void )
{
    CLK_SWR = 0xe1;       //HSI為主時鐘源  16MHz CPU時鐘頻率
    CLK_CKDIVR = 0x00;    //CPU時鐘0分頻,系統時鐘0分頻
}
           

系統時鐘設定好之後,下來需要設定IO口。

在中文參考手冊中找到GPIO相關寄存器。

STM8學習筆記---點亮LED燈

LED控制是輸出口,是以需要設定 輸出資料寄存器、資料方向寄存器、控制寄存器。

首先設定選擇端口的資料方向

STM8學習筆記---點亮LED燈

LED在PB5口接,是以需要将PB5口設定為1

PB_DDR |= 1 << 5 ;

然後設定控制寄存器

STM8學習筆記---點亮LED燈

通過PB5口輸出高低電平來控制LED燈的亮滅,是以輸出模式選擇推挽輸出。

PB_CR1 |= 1 << 5 ;

STM8學習筆記---點亮LED燈

控制寄存器2在輸出模式時可以設定輸出速度,由于我們輸出口接的是LED,是以輸出速度對LED亮滅來說影響不大。這個寄存器我們也可以不設定使用預設值0就行。

STM8學習筆記---點亮LED燈

輸出資料寄存器,向這個寄存器中寫1輸出為高電平,向寄存器中寫0,輸出為低電平。

這樣循環的給這個寄存器ODR5位置寫0,寫1時,PB口接的LED燈就亮、滅、亮、滅。循環。

到這裡寄存器就設定完了,然後在主程式中循環改變PB_ODR寄存器中ODR的值就可以實作LED燈的閃爍了。

led.c中程式如下:

//LED端口初始化
void LED_GPIO_Init( void )
{
    PB_DDR |= ( 1 << 5 );        //PB5 輸出 led
    PB_CR1 |= ( 1 << 5 );        //PB5 推挽輸出
}
           

Main.c中程式如下:

#include "iostm8s003F3.h"
#include "led.h"

//系統時鐘初始化
void SysClkInit( void )
{
    CLK_SWR = 0xe1;       //HSI為主時鐘源  16MHz CPU時鐘頻率
    CLK_CKDIVR = 0x00;    //CPU時鐘0分頻,系統時鐘0分頻
}
//延時函數
void delay_ms( unsigned int ms )
{
    unsigned char i;
    while( ms != 0 )
    {
        for( i = 0; i < 250; i++ );
        for( i = 0; i < 75; i++ );
        ms--;
    }
}

void main(void)
{
    SysClkInit();
    LED_GPIO_Init();
    while(1)
    {
      PB_ODR |= ( 1 << 5 );
      delay_ms(500);
      PB_ODR &= ~( 1 << 5 );
      delay_ms(500);
    }
}
           

進入main函數後,首先進行時鐘選擇,然後對LED端口初始化,下來進入死循環中,循環改變LED口的值。這樣LED燈就可以一亮已滅的閃爍了。

程式的功能是讓LED燈閃爍,但是從代碼中直接操作寄存器看起來不直覺,可以使用宏定義,給寄存器重新取個直覺的名字。

在led.h 頭檔案中添加宏定義

#define LED PB_ODR_ODR5

這樣就把PB_ODR寄存器中的第5位ODR5 重命名為 LED,這樣就對LED指派時,就相當于對 PB_ODR_ODR5 進行指派。于是程式中的循環可以改為

void main( void )
{
    SysClkInit();
    LED_GPIO_Init();
    while( 1 )
    {
        LED = 1;
        delay_ms( 500 );
        LED = 0;
        delay_ms( 500 );
    }
}
           

這樣通過宏定義處理後,程式的可讀性就提高了很多。