• 最小系统板 STM32入门,呼吸灯实现(STM32F103C6T6)


    Hi, I’m Shendi

    接着前一篇
    https://blog.csdn.net/qq_41806966/article/details/126894938

    这一次使用库来进行 LED 灯的开关,及延时的实现


    呼吸灯实现

    之前使用直接修改地址的方式实现点灯,这次用 GPIO 实现点灯,并加上延迟,实现一开一关的呼吸灯

    首先需要在 keil 中开启对应的运行环境,点击 Manager Run-Time,选择Device
    勾选以下内容

    GPIO

    StdPeriph Drivers -> Framework

    StdPeriph Drivers -> GPIO

    StdPeriph Drivers -> RCC(时钟)

    StdPeriph Drivers -> TIM(定时器所需)

    其中,之前的 StartUp 和 Core 是必勾选的
    在这里插入图片描述

    开启后就可以使用 GPIO 了



    GPIO使用

    首先需要开启时钟,通过以下函数

    // 第一个参数为外设名称
    // 第二个参数为 ENABLE(启用) 或者 DISABLE(禁用)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
    • 1
    • 2
    • 3

    然后初始化,使用 GPIO_Init 函数

    // 有两个参数, 第一个参数为使用的I/O,例如 GPIOC(单片机上标出来了 ABC...)
    // 第二个参数则需要定义结构体
    GPIO_InitTypeDef typeDef;
    // 这个地方是指定端口,例如我的是 PC13,那么就是13
    typeDef.GPIO_Pin = GPIO_Pin_13;
    typeDef.GPIO_Mode=GPIO_Mode_Out_PP;
    typeDef.GPIO_Speed=GPIO_Speed_50MHz;
    
    // 最后初始化
    GPIO_Init(GPIOC, &typeDef);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    最后可以通过输入/输出函数控制GPIO口

    例如点灯

    // 将指定GPIO口置为高电平(关)
    GPIO_SetBits(GPIOC, GPIO_Pin_13);
    // 将指定GPIO口置为低电平(开)
    GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    
    • 1
    • 2
    • 3
    • 4

    代码如下,就可以实现刚开始的点灯了

    #include "stm32f10x.h"
     
    int main(void) {
    	/* 开启时钟, 使用的都是已经封装好的函数 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
     
    	/* 初始化 */
    	GPIO_InitTypeDef typeDef;
    	typeDef.GPIO_Pin = GPIO_Pin_13;
    	typeDef.GPIO_Mode=GPIO_Mode_Out_PP;
    	typeDef.GPIO_Speed=GPIO_Speed_50MHz;
    	
        GPIO_Init(GPIOC, &typeDef);
     
    	/* 开 */
    	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    每次烧录都需要按下Reset键才能看到结果



    延时

    知道了开关后,加上延时,就可以做出呼吸灯的效果了

    可以用循环的方式让单片机做无意义的事情来消耗时间,但这样精确度低

    延时代码如下,首先需要执行定时器初始化才可以进行延时

    /** 初始化定时器 */
    void TIM3_Init(void)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	TIM_TimeBaseInitStructure.TIM_Period    = 50000-1;
    	TIM_TimeBaseInitStructure.TIM_Prescaler = 60-1;
    	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
    }
    
    // 微秒级延时
    void TIM3_Delayus(u16 xus)
    {
    	// 启动定时器
    	TIM_Cmd(TIM3,ENABLE); 
    	while(TIM3->CNT < xus);
    	TIM3->CNT = 0;
    	// 关闭定时器
    	TIM_Cmd(TIM3,DISABLE);
    }
    
    // 毫秒级延时
    void TIM3_Delayms(u16 xms)
    {
    	int i;
    	for(i=0;i<xms;i++)
    	{
    		TIM3_Delayus(1000);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32


    效果

    最终效果如下,代码如下

    STM32呼吸灯实现,示例视频


    完整代码如下

    #include "stm32f10x.h"
    
    /** 初始化定时器 */
    void TIM3_Init(void)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	TIM_TimeBaseInitStructure.TIM_Period    = 50000-1;
    	TIM_TimeBaseInitStructure.TIM_Prescaler = 60-1;
    	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
    }
    
    // 微秒级延时
    void TIM3_Delayus(u16 xus)
    {
    	// 启动定时器
    	TIM_Cmd(TIM3,ENABLE); 
    	while(TIM3->CNT < xus);
    	TIM3->CNT = 0;
    	// 关闭定时器
    	TIM_Cmd(TIM3,DISABLE);
    }
    
    // 毫秒级延时
    void TIM3_Delayms(u16 xms)
    {
    	int i;
    	for(i=0;i<xms;i++)
    	{
    		TIM3_Delayus(1000);
    	}
    }
    
    int main(void) {
    	/* 开启时钟, 使用的都是已经封装好的函数 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
     
    	/* 初始化 */
    	GPIO_InitTypeDef typeDef;
    	typeDef.GPIO_Pin = GPIO_Pin_13;
    	typeDef.GPIO_Mode=GPIO_Mode_Out_PP;
    	typeDef.GPIO_Speed=GPIO_Speed_50MHz;
    	
        GPIO_Init(GPIOC, &typeDef);
     
    	// 初始化定时器
    	TIM3_Init();
    	
    	while (1) {
    		/* 开 */
    		GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    		// 延时一秒
    		TIM3_Delayms(1000);
    		// 关
    		GPIO_SetBits(GPIOC, GPIO_Pin_13);
    		// 延时一秒
    		TIM3_Delayms(1000);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
  • 相关阅读:
    第十六章《正则表达式》第4节:Matcher类
    直播回顾 | 2022年长安链三季度研发工作总结及四季度计划
    学位英语短语
    映翰通C++ 一面(技术面、65min、offer)
    期货自动止损止盈 易盛极星
    20-Java备忘录模式 ( Memento Pattern )
    FTP 基础 与 使用 Docker 搭建 Vsftpd 的 FTP 服务
    数仓开发之DIM层
    【MySQL系列】 第四章 · 约束
    Jmeter执行接口自动化测试-如何初始化清空旧数据
  • 原文地址:https://blog.csdn.net/qq_41806966/article/details/126904664