STM8学习笔记---点亮LED灯

对单片机操作时一般有三个步骤,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 );
    }
}

这样通过宏定义处理后,程序的可读性就提高了很多。

发布了76 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_20222919/article/details/99454812