對單片機操作時一般有三個步驟,1.系統時鐘選擇。2.單片機外設初始化。3主程式編寫。
同樣要點亮LED燈時,也要按照這個步驟來。
首先選擇系統時鐘,打開STM8S中文參考手冊,找到時鐘寄存器
可以看到時鐘寄存器有13個,那麼該用哪個呢。STM8的主時鐘源有4種,我們要用的是16M内部RC振蕩器。
是以隻需要設定主時鐘切換寄存器CLK_SWR寄存器即可。
寄存器值為0XE1時,HSI為主時鐘,是以将CLK_SWR值設定為0xE1。
CLK_SWR = 0xe1; //HSI為主時鐘源 16MHz CPU時鐘頻率
然後設定時鐘分頻值
時鐘分頻寄存器預設值為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相關寄存器。
LED控制是輸出口,是以需要設定 輸出資料寄存器、資料方向寄存器、控制寄存器。
首先設定選擇端口的資料方向
LED在PB5口接,是以需要将PB5口設定為1
PB_DDR |= 1 << 5 ;
然後設定控制寄存器
通過PB5口輸出高低電平來控制LED燈的亮滅,是以輸出模式選擇推挽輸出。
PB_CR1 |= 1 << 5 ;
控制寄存器2在輸出模式時可以設定輸出速度,由于我們輸出口接的是LED,是以輸出速度對LED亮滅來說影響不大。這個寄存器我們也可以不設定使用預設值0就行。
輸出資料寄存器,向這個寄存器中寫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 );
}
}
這樣通過宏定義處理後,程式的可讀性就提高了很多。