当前位置:   article > 正文

小兴教你做平衡小车-stm32程序开发(点亮小灯)_stm32点亮小灯

stm32点亮小灯

1 前言

今天呢,是stm32程序开发的第一个程序。因为之前设计的stm32单片机最小系统板还在进行焊接工作,所以暂时先用现有的stm32最小系统板来进行程序的开发。
手中使用的是小马哥研制的stm32最小系统和DAP Link下载器。
在这里插入图片描述
在这里插入图片描述

2 单片机原理图分析

从原理图中可以看到控制LED灯的引脚是PC13引脚,当控制单片机PC13引脚输出低电平的时候,小灯会点亮。当控制单片机PC13引脚输出高电平的时候,小灯会熄灭。
在这里插入图片描述
在这里插入图片描述

3 单片机程序(库函数版本)

关键程序如下图所示(库函数版本)。
main.c文件的内容如下。

#include "stm32f10x.h"
#include "led.h"
//粗略延时
void delay(uint32_t timers)
{
	uint16_t i=0,j=0;
	for(i = 0;i<timers;i++)
	{
		for(j =0;j<65535;j++);
	}
}

int main(void)
{
	LED_Init();
	while(1)
	{
		LED_ON();
		delay(100);
		LED_OFF();
		delay(100);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

led.c文件的内容如下。

#include "stm32f10x.h"
#include "led.h"

void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	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);
}

void LED_ON(void)
{
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);
}

void LED_OFF(void)
{
	GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
  • 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

led.h文件的内容如下。

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LED_ON(void);
void LED_OFF(void);

#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以看出库函数版本很简单的。你可以暂且把他当作一个模板。如果想要控制其他引脚,只需要修改一小部分内容即可。
如果是想要更深入的了解stm32的内部寄存器的操作,就请看下面的寄存器版本吧。

4 单片机程序(寄存器版本)

首先需要了解的是APB2 外设时钟使能寄存器(RCC_APB2ENR)
在这里插入图片描述
因为我们要控制PC13引脚,也可以理解为需要打开其对应的时钟。我们使用下面的代码来实现在APB2 外设时钟使能寄存器中令IOPCEN这一位置为1。

RCC->APB2ENR |= (uint32_t)0x00000010;
  • 1

后面的好理解,但是前面的RCC->APB2ENR这个是什么东东嘞。我查找了一下RCC的定义。然后我就一点点的包起来"洋葱"。
在这里插入图片描述
这时候呢,出现了一个(RCC_TypeDef *)。可以看出RCC_TypeDef是一个结构体变量,如果在后面加一个小星,也就成为了结构体指针了。在这里插入图片描述RCC_BASE 可以运算出等于0x40021000。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此外,在手册中也有表明0x40021000主要负责外设:复位和时钟控制。
在这里插入图片描述

综上所示,#define RCC ((RCC_TypeDef *) RCC_BASE),可以改为#define RCC ((RCC_TypeDef *) 0x40021000)
RCC变量这里指的是(RCC_TypeDef *) 0x40021000,是结构体指针类型的。

RCC->APB2ENR可以理解为直接对内存中的APB2ENR的寄存器进行操作。
运行语句前。
在这里插入图片描述
运行语句后。
在这里插入图片描述
当芯片的时钟配置好之后,需要配置引脚的具体的功能。比如:是输入还是输出,如果是输出频率是多大等等。从下图中,我看我们可以看到如果想控制PC13引脚,那只需要修改其中的20、21、22、23位即可。我们可以使用下面的语句实现。这时候你会发现我这里做了一步清零的操作,这个是非常重要的。有知道的小伙伴可以把答案打在评论区。

	GPIOC->CRH   &= (uint32_t)0xFF0FFFFF;//使用前清零
	GPIOC->CRH   |= (uint32_t)0x00300000;//配置PC13为推挽输出,最大速度50MHz
  • 1
  • 2

在这里插入图片描述
当我们引脚的具体功能设置完成后,下面只需要操作寄存器控制引脚输出高低电平即可。我们可以用下面的代码来实现PC13引脚输出高电平。

GPIOC->BSRR  =  (uint32_t)0x00002000;//PC13引脚输出高电平
  • 1

在这里插入图片描述
之后,我们可以用下面的代码来实现PC13引脚输出低电平。

GPIOC->BRR  =   (uint16_t)0x2000;    //PC13引脚输出低电平
  • 1

在这里插入图片描述
具体的参考代码如下。

#include "stm32f10x.h"
//粗略延时
void delay(uint32_t timers)
{
	uint16_t i=0,j=0;
	for(i = 0;i<timers;i++)
	{
		for(j =0;j<65535;j++);
	}
}
int main(void)
{
	RCC->APB2ENR |= (uint32_t)0x00000010;//打开GPIOC时钟
	GPIOC->CRH   &= (uint32_t)0xFF0FFFFF;//使用前清零
	GPIOC->CRH   |= (uint32_t)0x00300000;//配置PC13为推挽输出,最大速度50MHz
	
	while(1)
	{
		GPIOC->BSRR  =  (uint32_t)0x00002000;//PC13引脚输出高电平
		delay(100);
		GPIOC->BRR  =   (uint16_t)0x2000;    //PC13引脚输出低电平
		delay(100);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

5 芯片的GPIO的特点介绍

芯片的GPIO的特点。
下图主要介绍了控制GPIO使用的寄存器,以及GPIO端口模式介绍。
在这里插入图片描述

5.1 芯片的GPIO口的基本结构

下图是GPIO口的基本结构。
在这里插入图片描述

5.2 输入模式

下图是输入浮空、输入上拉、输入下拉。
在这里插入图片描述
在这里插入图片描述

5.3 输出模式

下图是输出模式。
在这里插入图片描述
在这里插入图片描述

5.4 复用模式

下图是复用模式。
在这里插入图片描述
在这里插入图片描述

5.5 模拟输入

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号