使用STM32最小系统点亮LED灯

文章目录

  • 一、STM32最小系统板
  • 二、GPIO初始化设置
  • 三、Keil开发STM32环境搭建
  • 四、点亮LED灯
  • 五、实验结果
  • 六、总结
  • 实验目的
    1、了解STM32F103C8T6最小核心板的主要引脚接口;
    2、掌握Keil开发STM32程序的环境搭建和设置;
    3、使用GPIO引脚,外接LED 灯,实现LED灯周期性点亮。

    一、STM32最小系统板

    最小系统板的引脚原理图如下:

    STM32最小系统板的电路原理图:

    二、GPIO初始化设置

    (一)开启GPIO时钟
    1.根据芯片手册查询端口地址

    2.RCC寄存器地址



    因为RCC起始地址为:0x40021000

    APB2外设时钟使能寄存器的偏移地址是0x18

    所以实际地址为:0x40021000+0x18= 0x40021018

    使能GPIOA、GPIOB、GPIOC时钟代码如下:

    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    // 打开时钟
    RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
    RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟
    RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟
    

    (二)端口配置寄存器
    端口1-7为低,端口8-15为高。 每个引脚由四个位控制。
    GPIO口有八种模式:
    ●输入浮空
    ●输入上拉
    ●输入下拉
    ●模拟输入
    ●开漏输出
    ●推挽式输出.
    ●推挽式复用功能
    ●开漏复用功能
    本次实验使用推挽输出:根据手册可以知道使用此输出需要看CNF加端口号。上面bit为置为00。
    此次实验最大速度是10MHz,因此MODE加端口号上面的bit位需要变为01。



    PB0、PC15、PA0的设置具体代码如下::

    #define GPIOB_CRH (*(unsigned int *)0x40010C04)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    // 设置 GPIO 为推挽输出,即00,同时频率为10MHz,即01
    // 设置 GPIOB 最后四位为 0001 (B0)
    GPIOB_CRL |= (1<<0); // 最后一位设置为1
    GPIOB_CRL &= ~(0xE); // 倒数二、三、四位设置为0
    // 设置 GPIOC 前四位为 0001 (C15)
    GPIOC_CRH |= (1<<28); // 第四位设置为1
    GPIOC_CRH &= ~(0xE0000000); // 前三位设置为0
    // 设置 GPIOA 最后四位为 0001 (A0)
    GPIOA_CRL |= (1<<0); // 最后一位设置为1
    GPIOA_CRL &= ~(0xE); // 倒数二、三、四位设置为0
    

    (三)配置高电平
    将相应的bit位设置为高电位则灯不亮,GPIO的A0、B0、C15代码如下:

    //给GPIOA、GPIOB、GPIOC配置输入寄存器
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    // 3个LED初始化为不亮(即高点位)
    GPIOB_ODR |= (1<<0); // 最后一位设置为1
    GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
    GPIOA_ODR |= (1<<0); // 最后一位设置为1
    

    三、Keil开发STM32环境搭建

    选择STM32F103C8系列芯片

    勾选CORE和Startup

    选择ST-Link Debugger并点击setting进入设置

    勾选Reset and Run

    四、点亮LED灯

    1.使用GPIOA、GPIOB、GPIOC点亮红、蓝、黄三种LED灯
    以stm32最小板芯片,采用GPIOA、GPIOB、GPIOC点亮红、蓝、黄三种LED灯轮流闪烁。具体代码如
    下:

    #define GPIOB_BASE 0x40010C00 //定义GPIOB地址
    #define GPIOC_BASE 0x40011000 //定义GPIOC地址
    #define GPIOA_BASE 0x40010800 //定义GPIOA地址
    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    //给GPIOA、GPIOB、GPIOC配置寄存器
    #define GPIOB_CRL (*(unsigned int *)0x40010C00)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    //给GPIOA、GPIOB、GPIOC配置输入寄存器
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    void SystemInit(void);
    void Delay_ms(volatile unsigned int);
    void Delay_ms( volatile unsigned int t)
    {
    unsigned int i;
    while(t--)
    for (i=0;i<800;i++);
    }
    int main(){
    // 开启时钟
    RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    // 设置 GPIO 为推挽输出,即00,同时频率为10MHz,即01
    // 设置 GPIOB 最后四位为 0001 (B0)
    GPIOB_CRL |= (1<<0); // 最后一位设置为1
    GPIOB_CRL &= ~(0xE); // 倒数二、三、四位设置为0
    // 设置 GPIOC 前四位为 0001 (C15)
    GPIOC_CRH |= (1<<28); // 第四位设置为1
    GPIOC_CRH &= ~(0xE0000000); // 前三位设置为0
    // 设置 GPIOA 最后四位为 0001 (A0)
    GPIOA_CRL |= (1<<0); // 最后一位设置为1
    GPIOA_CRL &= ~(0xE); // 倒数二、三、四位设置为0
    // 3个LED初始化为不亮(即高点位)
    GPIOB_ODR |= (1<<0); // 最后一位设置为1
    GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
    GPIOA_ODR |= (1<<0); // 最后一位设置为1
    while(1){
    GPIOB_ODR &= ~(1<<0); // 点灯1
    Delay_ms(1000);
    GPIOB_ODR |= (1<<0); // 灭灯1
    Delay_ms(1000);
    GPIOC_ODR &= ~(1<<15); // 点灯2
    Delay_ms(1000);
    GPIOC_ODR |= (1<<15); // 灭灯2
    Delay_ms(1000);
    GPIOA_ODR &= ~(1<<0); // 点灯3
    Delay_ms(1000);
    GPIOA_ODR |= (1<<0); // 灭灯3
    Delay_ms(1000);
    }
    }
    void SystemInit(){
    }
    

    2.将P13口加入流水灯的闪烁中
    STM32最小系统核心板子出厂时已经焊接好了1个led灯(PC13处),一般可通过此灯的点亮让编程者验
    证自己烧录的代码是否正常运行,将此口P13口加入程序中重新烧录,和具体代码如下:

    #define GPIOB_BASE 0x40010C00
    #define GPIOC_BASE 0x40011000
    #define GPIOA_BASE 0x40010800
    #define RCC_APB2ENR (*(unsigned int *)0x40021018)
    #define GPIOB_CRH (*(unsigned int *)0x40010C04)
    #define GPIOC_CRH (*(unsigned int *)0x40011004)
    #define GPIOA_CRL (*(unsigned int *)0x40010800)
    #define GPIOB_ODR (*(unsigned int *)0x40010C0C)
    #define GPIOC_ODR (*(unsigned int *)0x4001100C)
    #define GPIOA_ODR (*(unsigned int *)0x4001080C)
    void SystemInit(void);
    void Delay_ms(volatile unsigned int);
    void A_LED_LIGHT(void);
    void B_LED_LIGHT(void);
    void C_LED_LIGHT(void);
    void Delay_ms( volatile unsigned int t)
    {
    unsigned int i;
    while(t--)
    for (i=0;i<800;i++);
    }
    void A_LED_LIGHT(){
    GPIOA_ODR=0x0<<4; //PA4低电平
    GPIOB_ODR=0x1<<9; //PB9高电平
    GPIOC_ODR=0x1<<13; //PC13高电平
    }
    void B_LED_LIGHT(){
    GPIOA_ODR=0x1<<4; //PA4高电平
    GPIOB_ODR=0x0<<9; //PB9低电平
    GPIOC_ODR=0x1<<13; //PC13高电平
    }
    void C_LED_LIGHT(){
    GPIOA_ODR=0x1<<4; //PA4高电平
    GPIOB_ODR=0x1<<9; //PB9高电平
    GPIOC_ODR=0x0<<13; //PC13低电平
    }
    int main(){
    int j=100;
    // 开启时钟
    RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
    RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
    RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
    // 设置 GPIO 为推挽输出
    GPIOB_CRH&= 0xffffff0f; //设置位 清零
    GPIOB_CRH|=0x00000020; //PB9推挽输出
    GPIOC_CRH &= 0xff0fffff; //设置位 清零
    GPIOC_CRH|=0x00300000; //PC15推挽输出
    GPIOA_CRL &= 0xfff0ffff; //设置位 清零
    GPIOA_CRL|=0x00010000; //PA4推挽输出
    // 3个LED初始化为不亮(即高点位)
    GPIOB_ODR |= (1<<9);
    GPIOC_ODR |= (1<<13);
    GPIOA_ODR |= (1<<4);
    while(j){
    B_LED_LIGHT();
    Delay_ms(2000);//单片机上2000 100
    C_LED_LIGHT();
    Delay_ms(3000);//单片机上3000 200
    A_LED_LIGHT();
    Delay_ms(3000);//单片机上3000 200
    }
    }
    void SystemInit(){
    }
    

    五、实验结果

    Proteus仿真如下:

    STM32点灯

    六、总结

    初学STM32使用寄存器点亮LED虽然难度并不大,但其中需要注意的细节有很多,包括Keil软件的配置及寄存器相关地址的准确。

    作者:暴富奥利奥

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用STM32最小系统点亮LED灯

    发表回复