基于keil5新建STM32F10x寄存器版本工程

87 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第23天,点击查看活动详情

一、前言

前面文章分享了很多关于STM32F103系列知识点、物联网相关的小项目,工程都采用的是寄存器方式编写;很多小伙伴接触STM32开始都采用库函数编程,不清楚如何使用寄存器方式开发STM32;这篇文章就讲一下如何新建寄存器风格的STM32工程,并介绍需要用到哪些官方系统文件等。

二、环境介绍

开发环境: keil5.25

编程语言: C语言

操作系统: win10 64位

MCU型号: ST32F103C8T6 (F103系列都是通用的,区分容量即可)

库函数的版本: 3.5 (新建工程需要用到库函数包里的一些系统必要文件)

STM32系列简介:

STM32系列专为要求高性能、低成本、低功耗的嵌入式应用设计的。 主流产品(STM32F0、STM32F1、STM32F3)、超低功耗产品(STM32L0、STM32L1、STM32L4、STM32L4+)、高性能产品(STM32F2、STM32F4、STM32F7、STM32H7)

以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:

1STM32STM32代表ARM Cortex-M内核的32位微控制器。
2FF代表芯片子系列--通用系列。
3103103代表增强型系列。
4RR这一项代表引脚数,其中T代表36脚,C代表48脚,R代表64脚,V代表100脚,Z代表144脚,I代表176脚。
5BB这一项代表内嵌Flash容量,其中6代表32K字节Flash,8代表64K字节Flash,B代表128K字节Flash,C代表256K字节Flash,D代表384K字节Flash,E代表512K字节Flash,G代表1M字节Flash。
6TT这一项代表封装,其中H代表BGA封装,T代表LQFP封装,U代表VFQFPN封装。
766这一项代表工作温度范围,其中6代表-40——85℃,7代表-40——105℃。

STM32L电路的设计目的是以低电压实现高性能,有效延长电池供电设备的充电间隔。片上模拟功能的最低工作电源电压为1.8V。数字功能的最低工作电源电压为1.65V,在电池电压降低时,可以延长电池供电设备的工作时间。

从应用类别来说,STM32可以有以下用处:

(1). 无人机制作:现在无人机主流的微控制器所用的就是stm32控制器。

(2). 简单仪器仪表:stm32可以用作简单示波器、频率计,对采集的数字信号进行处理并送入屏幕显示。

(3). 机器人:常看到的就是家用的扫地机器人,还要就是国内各种机器人比赛的小型机器人,几乎都用的是stm32控制器,毕竟现在stm32接口种类齐全、功能又多、价格便宜、资料齐全。

(4). 电源控制器:全国电子设计大赛常考题的电源题,很多同学制作电源首选控制器也大多会选择stm32。

三、新建工程

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

接下来就可以写代码点亮第一盏LED灯。

 #include "stm32f10x.h"
 int main()
 {
     while(1)
     {
         
     }
 }

编写LED流水灯代码:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
int main()
{
	u8 val;
	LED_Init();
	BEEP_Init();
	KeyInit();
	while(1)
	{
		val=KeyScan();
		if(val)
		{
			 BEEP=!BEEP;
			 LED1=!LED1;
			 LED2=!LED2;
			 LED3=!LED3;
			 LED4=!LED4;
		}
	}
}

#include "led.h"
/*
函数功能: LED灯初始化
硬件连接:
					LED1-->PF7
					LED2-->PB5
					LED3-->PA8
					LED4-->PA1
*/
void LED_Init(void)
{
		/*1. 开时钟*/
		RCC->APB2ENR|=1<<2; //PA
	  RCC->APB2ENR|=1<<3; //PB
	  RCC->APB2ENR|=1<<7; //PF
		
		/*2. 配置GPIO模式*/
		GPIOF->CRL&=0x0FFFFFFF;
		GPIOF->CRL|=0x30000000;
		
		GPIOB->CRL&=0xFF0FFFFF;
		GPIOB->CRL|=0x00300000;
	
	  GPIOA->CRH&=0xFFFFFFF0;
		GPIOA->CRH|=0x00000003;
	
	  GPIOA->CRL&=0xFFFFFF0F;
		GPIOA->CRL|=0x00000030;
	
		/*3. 上拉GPIO口电平(关闭LED)*/
	  GPIOF->ODR|=1<<7;
	  GPIOA->ODR|=1<<8;
		GPIOA->ODR|=1<<1;
		GPIOB->ODR|=1<<5;
}

/*
函数功能: 蜂鸣器初始化
硬件连接: PB8
*/
#define RCC_APB2   *((u32*)(0x40021000+0x18))
#define GPIOB_CRH  *((u32*)(0x40010C00+0x04))
void BEEP_Init(void)
{
		/*1. 开时钟*/
	//RCC->APB2ENR|=1<<3; //PB
	  RCC_APB2|=1<<3; //PB
	
		/*2. 配置GPIO口模式*/
	//	GPIOB->CRH&=0xFFFFFFF0;
	//	GPIOB->CRH|=0x00000003;
		GPIOB_CRH&=0xFFFFFFF0;
	  GPIOB_CRH|=0x00000003;
}

#include "key.h"
/*
函数功能: 按键初始化
硬件连接: 
				KEY_UP->PA0
				KEY2--->PE4
				KEY3--->PE3
				KEY4--->PE2
*/
void KeyInit(void)
{
	 /*1. 开时钟*/
		RCC->APB2ENR|=1<<2; //PA
		RCC->APB2ENR|=1<<6; //PE
		
	 /*2. 配置模式*/
	 GPIOA->CRL&=0xFFFFFFF0;
	 GPIOA->CRL|=0x00000008;
	 GPIOE->CRL&=0xFFF000FF;
	 GPIOE->CRL|=0x00088800;
	
	 /*3. 配置上下拉*/
	 GPIOA->ODR&=~(1<<0); //下拉,输出低电平
	 GPIOE->ODR|=0x7<<2;  //上拉
}

/*
函数功能: 获取按键值
返 回 值: 返回检测到按键值(0,1,2,3,4) 0表示没有按键按下
按键有两种情况: 单击按下、连续按下
*/
u8 KeyScan(void)
{
		static u8 flag=0;
		/*只要有一个按键就进入if语句*/
	  if((KEY_UP||KEY2==0||KEY3==0||KEY4==0)&&flag==0)
		{
				flag=1;      //记录按下按键已经按下
				DelayMs(50); //按键消抖
				if(KEY_UP)return 1;  //按键值1
			  if(KEY2==0)return 2; //按键值1
			  if(KEY3==0)return 3; //按键值1
			  if(KEY4==0)return 4; //按键值1
		}
		else if(KEY_UP==0&&KEY2&&KEY3&&KEY4) //所有的按键松开之后再进去
		{
			  flag=0;      //记录按下按键已经松开
		}
		return 0;		
}