一、使用寄存器点亮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