从0开始学习stm32 Task1 流水灯

任务一:debug控制单个LED

任务要求

  1. 在debug模式下控制LED的亮灭。

图片展示

实现思路

使用库函数控制led灯的亮灭,RCC_APB2PeriphClockCmd函数用于控制APB2的外设时钟(时钟默认关闭),这里用它来开启GPIOC的外设时钟;GPIO_Init函数用于配置端口模式,初始化GPIO;GPIO_SetBits(GPIOC, GPIO_Pin_13)可将GPIO_Pin_13配置为高电平;相应的,GPIO_ResetBits(GPIOC, GPIO_Pin_13)将端口配置为低电平。

CTRL+F查找字符位置,CTRL+ALT+space调出软件建议,建议可用tab键选中.

关键代码

#include "stm32f10x.h"                  // Device header

int	main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_SetBits(GPIOC, GPIO_Pin_13);
//	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	while(1)
	{
	
	}
}

任务二:实现流水灯

任务要求

  1. 通过固件库函数实现GPIO控制单个LED亮灭。

  2. 实现多个LED有序亮灭完成流水灯。

视频展示

实现思路

GPIO_Write调用端口,通过delay函数实现led灯依次点亮

关键代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	while (1)
	{
		GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000
		Delay_ms(100);
		
	}
}
#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

任务三:按键控制流水灯开启与关闭

任务要求

  1. 按下按键能够启动流水灯,再按下按键能够停止流水灯。

  2. 当前程序有什么问题吗?

视频展示

实现思路

沿用之前的流水灯程序,将流水灯开启封装在代码LED_ON之中,调用GPIO_ReadInputDataBit函数读取GPIO输入

key函数端口要用上拉输入配置

关键代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;

int	main(void)
{
	LED_Init();
	Key_Init();
	
	while(1)
	{
	  KeyNum = Key_GetNum();
		if(KeyNum == 1)
		{
			LED_ON();
		}
	}
	
	 
}
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void LED_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_All);
}

void LED_ON(void)
{
        GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000
		Delay_ms(100);
		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000
		Delay_ms(100);
	    GPIO_SetBits(GPIOA,GPIO_Pin_All);
}

void LED_OFF(void)
{
       GPIO_SetBits(GPIOA,GPIO_Pin_All);
}
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
    uint8_t KeyNum = 0;
	if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0);
		Delay_ms(20);
		KeyNum= 1;
	}
	return KeyNum;
}

进阶任务:随机流水灯

任务要求

  1. 使得每次复位板子后,按下按键后流水灯的顺序随机。

视频展示

//如果需要,请在此处插入视频

实现思路

//这一流水灯是通过for循环延时的,在主函数里……

关键代码

#include "global.h"
……
#include "bsp_led.h"
……

//以下是学习时的记录

STM32的GPIO

1. GPIO的种类

STM32F103C8T6共有2组IO口,每组16个,共16×2=32个,分别为:

GPIOA——>PA0、PA1、PA2…PA15

GPIOB——>PB0、PB1、PB2…PB15

2. GPIO的基本结构

每个GPIO内部都有这样的一个电路结构,如图

3. GPIO输入输出的8种模式

程序中标识

模式

GPIO_Mode_AIN

模拟输入

GPIO_Mode_IN_FLOATING

浮空输入

GPIO_Mode_IPD

下拉输入

GPIO_Mode_IPU

上拉输入

GPIO_Mode_Out_OD

开漏输出

GPIO_Mode_Out_PP

推挽输出

GPIO_Mode_AF_OD

复用开漏输出

GPIO_Mode_AF_PP

复用推挽输出

4. GPIO各模式的使用场景

1 GPIO_Mode_AIN:模拟输入

一般用于ADC模拟输入

2 GPIO_Mode_IN_FLOATING:浮空输入

在外部触发时经常用到……

3 GPIO_Mode_IPD和GPIO_Mode_IPU:下拉输入和上拉输入

这个模式下接入了GPIO内部的上下拉电阻,上下拉电阻的阻值是……

可以看到KEY_UP按下后,IO口应该是3V3电平输入,未按下时为悬空状态,而悬空状态IO输入是未知的,所以为了防止程序跑飞,采用下拉输入,在悬空状态下,使IO输入下拉到低电平。这样,在悬空状态下,IO检测到的是低电平,不会去执行key_up按下后的程序。

4 ……

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值