野火指南者STM32开发板全周期代码记录

一、使用寄存器点亮LED

1.1 应用:简单延时函数,让灯闪烁

#define PERIPH_BASE  ((unsigned int)0x40000000)
#define APB1PERIPH_BASE  PERIPH_BASE
#define APB2PERIPH_BASE  (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE  (PERIPH_BASE+0x20000)

#define RCC_BASE     (AHBPERIPH_BASE+0x1000)
#define GPIOB_BASE     (APB2PERIPH_BASE+0x0C00)

#define RCC_APB2ENR  *(unsigned int*)(RCC_BASE+0x0018)
	
#define GPIOB_CRL  *(unsigned int*)(GPIOB_BASE)
#define GPIOB_CRH  *(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_ODR  *(unsigned int*)(GPIOB_BASE+0x0C)
#include"stm32f10x.h"

void Led_Disp(unsigned char i)
{
		//打开GPIOB端口的时钟
RCC_APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB_CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB_ODR &=~(1<<i);
}

void Led_Clo(unsigned char i)
{
	//打开GPIOB端口的时钟
RCC_APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB_CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB_ODR |=(1<<i);
}

void Delay(unsigned int i)
{
	while(i--);
}

int main()
{
#if 0
//打开GPIOB端口的时钟
*( unsigned int * )0x40021018 |= ( (1) << 3 );
//配置I0口为输出
*( unsigned int * )0x40010C00 |= ( (1) << (4*0) );
//控制ODR寄存器
*( unsigned int * )0x40010C0C &=~(1<<0);
#else
//	//打开GPIOB端口的时钟
//RCC_APB2ENR |= ( (1) << 3 );
////配置I0口为输出
//GPIOB_CRL |= ( (1) << (4*0) );
////控制ODR寄存器
//GPIOB_ODR &=~(1<<0);
	while(1)
	{
	  Led_Disp(0);
		Delay(100000);
		Led_Clo(0);
		Led_Disp(1);
		Delay(100000);
		Led_Clo(1);
		Led_Disp(5);
		Delay(100000);
		Led_Clo(5);
	}
#endif

}

void SystemInit()
{
}

1.2 应用:采用操作BSRR/BRR来编程,点亮LED

#define PERIPH_BASE  ((unsigned int)0x40000000)
#define APB1PERIPH_BASE  PERIPH_BASE
#define APB2PERIPH_BASE  (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE  (PERIPH_BASE+0x20000)

#define RCC_BASE     (AHBPERIPH_BASE+0x1000)
#define GPIOB_BASE     (APB2PERIPH_BASE+0x0C00)

#define RCC_APB2ENR  *(unsigned int*)(RCC_BASE+0x0018)
	
#define GPIOB_CRL  *(unsigned int*)(GPIOB_BASE)
#define GPIOB_CRH  *(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_ODR  *(unsigned int*)(GPIOB_BASE+0x0C)
#define GPIOB_BSRR *(unsigned int*)(GPIOB_BASE+0x10)
#include"stm32f10x.h"

void Led_Disp(unsigned char i)
{
		//打开GPIOB端口的时钟
RCC_APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB_CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB_BSRR |=(1<<(16+i));
}

void Led_Clo(unsigned char i)
{
	//打开GPIOB端口的时钟
RCC_APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB_CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB_BSRR |=(1<<(i));
}

void Delay(unsigned int i)
{
	while(i--);
}

int main()
{
   while(1)
	 {
		 Led_Disp(0);
		 Delay(100000);
		 Led_Clo(0);
		 Delay(100000);
	 }

}

void SystemInit()
{
}

二、自己写库

2.1 寄存器结构体定义

#define PERIPH_BASE  ((unsigned int)0x40000000)
#define APB1PERIPH_BASE  PERIPH_BASE
#define APB2PERIPH_BASE  (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE  (PERIPH_BASE+0x20000)

#define RCC_BASE     (AHBPERIPH_BASE+0x1000)
#define GPIOB_BASE     (APB2PERIPH_BASE+0x0C00)

#define RCC_APB2ENR  *(unsigned int*)(RCC_BASE+0x0018)
	
typedef unsigned int   uint32_t;
typedef unsigned short uint16_t;

typedef struct
{
	uint32_t CRL;
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR    ;
	uint32_t BRR     ;
	uint32_t LCKR    ;
}GPIO_Typedef;

#define GPIOB ((GPIO_Typedef*)GPIOB_BASE)

typedef struct
{
	uint32_t CR;
	uint32_t CFGR;
	uint32_t CIR;
	uint32_t APB2RSTR;
	uint32_t APB1RSTR    ;
	uint32_t AHBENR     ;
	uint32_t APB2ENR    ;
}RCC_Typedef;

#define RCC ((RCC_Typedef*)RCC_BASE)
#include"stm32f10x.h"

void Led_Disp(unsigned char i)
{
		//打开GPIOB端口的时钟
RCC->APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB->CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB->BSRR |=(1<<(16+i));
}

void Led_Clo(unsigned char i)
{
	//打开GPIOB端口的时钟
RCC->APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB->CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIOB->BSRR |=(1<<(i));
}

void Delay(unsigned int i)
{
	while(i--);
}

int main()
{
   while(1)
	 {
		 Led_Disp(0);
		 Delay(100000);
		 Led_Clo(0);
		 Delay(100000);
	 }

}

void SystemInit()
{
}

 2.2 编写端口置位复位函数

#ifndef __STM32F10X_GPIO_H
#define __STM32F10X_GPIO_H

#include"stm32f10x.h"

#define GPIO_Pin_0 ((uint16_t)0x0001)
#define GPIO_Pin_1 ((uint16_t)0x0002)
#define GPIO_Pin_2 ((uint16_t)0x0004)
#define GPIO_Pin_3 ((uint16_t)0x0008)
#define GPIO_Pin_4 ((uint16_t)0x0010)
#define GPIO_Pin_5 ((uint16_t)0x0020)
#define GPIO_Pin_6 ((uint16_t)0x0040)
#define GPIO_Pin_7 ((uint16_t)0x0080)

#define GPIO_Pin_8 ((uint16_t)0x0100)
#define GPIO_Pin_9 ((uint16_t)0x0200)
#define GPIO_Pin_10 ((uint16_t)0x0400)
#define GPIO_Pin_11 ((uint16_t)0x0800)
#define GPIO_Pin_12 ((uint16_t)0x1000)
#define GPIO_Pin_13 ((uint16_t)0x2000)
#define GPIO_Pin_14 ((uint16_t)0x4000)
#define GPIO_Pin_15 ((uint16_t)0x8000)

void GPIO_SetBits(GPIO_Typedef* GPIOx,uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_Typedef* GPIOx,uint16_t GPIO_Pin);
#endif
#include"stm32f10x_gpio.h"

void GPIO_SetBits(GPIO_Typedef* GPIOx,uint16_t GPIO_Pin)
{
	GPIOx->BSRR |=GPIO_Pin;
}

void GPIO_ResetBits(GPIO_Typedef* GPIOx,uint16_t GPIO_Pin)
{
	GPIOx->BRR |=GPIO_Pin;
}

#ifndef __STM32F10X_H
#define __STM32F10X_H

#define PERIPH_BASE  ((unsigned int)0x40000000)
#define APB1PERIPH_BASE  PERIPH_BASE
#define APB2PERIPH_BASE  (PERIPH_BASE+0x10000)
#define AHBPERIPH_BASE  (PERIPH_BASE+0x20000)

#define RCC_BASE     (AHBPERIPH_BASE+0x1000)
#define GPIOB_BASE     (APB2PERIPH_BASE+0x0C00)
	
typedef unsigned int   uint32_t;
typedef unsigned short uint16_t;

typedef struct
{
	uint32_t CRL;
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR    ;
	uint32_t BRR     ;
	uint32_t LCKR    ;
}GPIO_Typedef;

#define GPIOB ((GPIO_Typedef*)GPIOB_BASE)

typedef struct
{
	uint32_t CR;
	uint32_t CFGR;
	uint32_t CIR;
	uint32_t APB2RSTR;
	uint32_t APB1RSTR    ;
	uint32_t AHBENR     ;
	uint32_t APB2ENR    ;
}RCC_Typedef;

#define RCC ((RCC_Typedef*)RCC_BASE)

#endif
#include"stm32f10x.h"
#include"stm32f10x_gpio.h"
void Led_Disp(unsigned char i)
{
		//打开GPIOB端口的时钟
RCC->APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB->CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIO_SetBits(GPIOB,GPIO_Pin_0);
}

void Led_Clo(unsigned char i)
{
	//打开GPIOB端口的时钟
RCC->APB2ENR |= ( (1) << 3 );
//配置I0口为输出
GPIOB->CRL |= ( (1) << (4*i) );
//控制ODR寄存器
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
}

void Delay(unsigned int i)
{
	while(i--);
}

int main()
{
   while(1)
	 {
		 Led_Disp(0);
		 Delay(100000);
		 Led_Clo(0);
		 Delay(100000);
	 }

}

void SystemInit()
{
}

2.3 初始化函数

用结构体去代替CRL,提高可读性

typedef enum //速度的限制
{
	GPIO_Speed_10MHZ=1,
	GPIO_Speed_2MHZ,
	GPIO_Speed_50MHZ
}GPIO_Speed_Typedef;

typedef enum//模式的限制
{
	GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
	
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP=0x18
}GPIO_Mode_Typedef;


typedef struct
{
	uint16_t GPIO_Pin;
	uint16_t GPIO_Speed;
	uint16_t GPIO_Mode;
}GPIO_Init_Typedef;


GPIO_ InitStructure. GPI0. Pin = GPIO. Pin_ 0:
GPIO_ InitStructure. GPI0. JMode. = GPI0. Jlode_ _0ut_ PP:
GPIO_ InitStructure. GPI0_ Speed = GPI0. Speed_ 50Hz;
GPIO_ Init (GPIOB, &GPIO _InitStructure):

三、固件库编程

3.1 需求分析

1-汇编编写的启动文件
startup_stm32f10x_hd.s: 设置堆栈指针、设置PC指针、初始化中断向量表、配置系统时钟、对用c库函数_ main最终去到c的世界
2-时钟配置文件
system_ stm32f10x.c: 把外部时钟HSE=8M,经过PLL倍频为72M。
3-外设相关的
stm32f10x.h:实现了内核之外的外设的寄存器映射
xxx: GPIO、 USRAT、 I2C、 SPI、FSMC
stm32f10x_xx.c:外设的驱动函数库文件
stm32f10x_xx.h:存放外设的初始化结构体,外设初始化结构体成员的参数列表,外设固件库函数的声明
4-内核相关的
CMSIS - Cortex徼控制器软件接口标准
core_cm3.h: 实现了内核里面外设的寄存器映射
core_cm3.c
NVIC (嵌套向量中断控制器)、sysTick (系统滴答定时器)
misc.h
misc.c
5-头文件的配置文件
stm32f10x_ conf.h:头文件的头文件
//stm32f10x_usart.h
//stm32f10x_i2c.h
//stm32f10x_spi.h
//stm32f10x_adc.h
//stm32f10x_fsmc.h
6-专门存放中断服务函数的c文件
stm32f10x_it.c
stm32f10x_it.h
中断服务函数你可以随意放在其他的地方,并不是一定要放在stm32f10x_it.c


3.2 GPIO输出

注意宏的定义,宏方便编程

#ifndef _BSP_LED_H
#define _BSP_LED_H


#include"stm32f10x.h"


#define LED_G_GPIO_PIN     GPIO_Pin_0
#define LED_G_GPIO_PORT    GPIOB
#define LED_G_GPIO_CLK     RCC_APB2Periph_GPIOB

void LED_GPIO_Config(void);
#endif

#include"bsp_led.h"

void LED_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Pin=LED_G_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_InitStruct );
}

#include"stm32f10x.h"
#include"bsp_led.h"

void Delay(void)
{
	unsigned int i=10000000;
	while(i--);
}
int main()
{
	LED_GPIO_Config();
	while(1)
	{
	GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
		Delay();
	GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
		Delay();
	}
}

应用,实现流水灯

#ifndef _BSP_LED_H
#define _BSP_LED_H

void LED_G_Config(void);
void LED_R_Config(void);
void LED_B_Config(void);

#include"stm32f10x.h"

#define LED_G_GPIO_PIN     GPIO_Pin_0
#define LED_G_GPIO_PORT    GPIOB
#define LED_G_GPIO_CLK     RCC_APB2Periph_GPIOB

#define LED_R_GPIO_PIN     GPIO_Pin_5
#define LED_R_GPIO_PORT    GPIOB
#define LED_R_GPIO_CLK     RCC_APB2Periph_GPIOB

#define LED_B_GPIO_PIN     GPIO_Pin_1
#define LED_B_GPIO_PORT    GPIOB
#define LED_B_GPIO_CLK     RCC_APB2Periph_GPIOB


#endif

#include"bsp_led.h"

void LED_G_Config(void)
{
	GPIO_InitTypeDef GPIO_G_InitStruct;
	GPIO_G_InitStruct.GPIO_Pin=LED_G_GPIO_PIN;
	GPIO_G_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_G_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_R_InitStruct;
	GPIO_R_InitStruct.GPIO_Pin=LED_R_GPIO_PIN;
	GPIO_R_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_R_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_B_InitStruct;
	GPIO_B_InitStruct.GPIO_Pin=LED_B_GPIO_PIN;
	GPIO_B_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_B_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_G_InitStruct );
	GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
	
	GPIO_Init(LED_R_GPIO_PORT,&GPIO_R_InitStruct );
	GPIO_SetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);
	
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_B_InitStruct );
	GPIO_SetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);
}

void LED_R_Config(void)
{
	GPIO_InitTypeDef GPIO_G_InitStruct;
	GPIO_G_InitStruct.GPIO_Pin=LED_G_GPIO_PIN;
	GPIO_G_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_G_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_R_InitStruct;
	GPIO_R_InitStruct.GPIO_Pin=LED_R_GPIO_PIN;
	GPIO_R_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_R_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_B_InitStruct;
	GPIO_B_InitStruct.GPIO_Pin=LED_B_GPIO_PIN;
	GPIO_B_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_B_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_G_InitStruct );
	GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
	
	GPIO_Init(LED_R_GPIO_PORT,&GPIO_R_InitStruct );
	GPIO_ResetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);
	
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_B_InitStruct );
	GPIO_SetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);
}

void LED_B_Config(void)
{
	GPIO_InitTypeDef GPIO_G_InitStruct;
	GPIO_G_InitStruct.GPIO_Pin=LED_G_GPIO_PIN;
	GPIO_G_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_G_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_R_InitStruct;
	GPIO_R_InitStruct.GPIO_Pin=LED_R_GPIO_PIN;
	GPIO_R_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_R_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_InitTypeDef GPIO_B_InitStruct;
	GPIO_B_InitStruct.GPIO_Pin=LED_B_GPIO_PIN;
	GPIO_B_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_B_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_G_InitStruct );
	GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN);
	
	GPIO_Init(LED_R_GPIO_PORT,&GPIO_R_InitStruct );
	GPIO_SetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);
	
	GPIO_Init(LED_G_GPIO_PORT,&GPIO_B_InitStruct );
	GPIO_ResetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);
}

#include"stm32f10x.h"
#include"bsp_led.h"

void Delay(void)
{
	unsigned int i=10000000;
	while(i--);
}


int main()
{
	
	while(1)
	{
	LED_G_Config();
		Delay();
	LED_R_Config();
		Delay();
		LED_B_Config();
		Delay();
	}
}

3.3 Key读入

注意,Key_Read()应该写在while内以保证持续的读。

#include"stm32f10x.h"
#include"bsp_led.h"
#include"bsp_key.h"

void Delay(void)
{
	unsigned int i=10000000;
	while(i--);
}

int main()
{
	LED_G_Config();
	Key_Config();
	while(1)
	{
	if(Key_Read(GPIOA, GPIO_Pin_0)) Led_G_TOGGLE;
  }
}

#ifndef _BSP_KEY_H
#define _BSP_KEY_H
#include"stm32f10x.h"

#define Key1_GPIO_PIN     GPIO_Pin_0
#define Key1_GPIO_PORT    GPIOA
#define Key1_GPIO_CLK     RCC_APB2Periph_GPIOA

void Key_Config(void);
uint8_t Key_Read(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif
#include"bsp_key.h"

void Key_Config(void)
{
	GPIO_InitTypeDef Key1_InitStruct;
	
	Key1_InitStruct.GPIO_Pin =     Key1_GPIO_PIN;
	Key1_InitStruct.GPIO_Mode=     GPIO_Mode_IN_FLOATING;
	
	RCC_APB2PeriphClockCmd(Key1_GPIO_CLK,ENABLE);
	GPIO_Init(Key1_GPIO_PORT,&Key1_InitStruct);
} 

uint8_t Key_Read(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
	if(GPIO_ReadInputDataBit( GPIOx, GPIO_Pin))
	{
		while(GPIO_ReadInputDataBit( GPIOx, GPIO_Pin));
		return 1;
	}
	else return 0;
}

#ifndef _BSP_LED_H
#define _BSP_LED_H

void LED_G_Config(void);

#include"stm32f10x.h"

#define LED_G_GPIO_PIN     GPIO_Pin_0
#define LED_G_GPIO_PORT    GPIOB
#define LED_G_GPIO_CLK     RCC_APB2Periph_GPIOB

#define Led_G_TOGGLE { LED_G_GPIO_PORT->ODR^=LED_G_GPIO_PIN;}
#endif

四、EXTI外部中断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值