其实这个小实验就是学会运用GPIO这个外设。

GPIO是一个片上高速外设,它是由几个寄存器来控制的,每个寄存器占据0x04:

GPIOx_BSSR:

端口位设置/清除寄存器,这个寄存器的BSy位是0-15位(BS0-BS15),BRy位是16-31位(BR0-BR15);通过这两个位可以控制16个引脚;BSy只写,写0对ODRy无作用,写1置ODRy位1;BRy只写,写0对ODRy无作用,写1清除ODRy为0;如若两个位同时设置,BSy位起作用。

GPIOx_CRL/CRH:

端口配置低/高寄存器,用到了两个寄存器来配置16个引脚,每个引脚由低位开始按顺序每四个位控制一个引脚;MODEy[1:0],这两位00表示输入模式;01为输出模式,最大速度10MHz;10为输出模式,最大速度为2MHz;11为输出模式,最大速度位50MHz;CNFy[1:0],在输入/输出模式,这两位就可以配置四种不同的输入/输出模式。

GPIOx_IDR:

端口输入数据寄存器,IDRy[0:15](16-31位保留),这些位只能以字(16位)的形式的只读,读出的值就是对应引脚的状态。

GPIOx_ODR:

端口输出数据寄存器, IDRy[0:15](16-31位保留),这些位能以字(16位)的形式的读写,读出的值就是对应引脚的状态。

GPIOx_BRR:

端口位清除寄存器,BRy[0:15](16-31位保留),这些位只能以字(16位)的形式的只写,写0对相应的ODRy无作用,写1对对应的ODRy为0。

GPIOx_LCKR:

端口配置锁定寄存器,LCKK[16],改位可随时读出,但只可以通过锁键写入序列来修改,写0锁键位激活;写1,锁键位激活,下次复位前该寄存器被锁住;

LCKy[0:15],每个锁定位锁定CRL/CRH对应的四个位,这些锁定位可读,在锁键位为0时写入;写0不锁定端口的配置;写1锁定端口的配置。

用单片机点亮一个LED灯,可以通过寄存器,也可以通过库函数;

下面是寄存器版本:

#include"stm32f10x.h"
#define PERIPH_BASE1 ((unsigned int)0x40000000)

/*APB2 总线基地址 */
#define APB2PERIPH_BASE1 (PERIPH_BASE1 + 0x10000)
/* AHB总线基地址 */
#define AHBPERIPH_BASE1 (PERIPH_BASE1 + 0x20000)

/*GPIOB外设基地址*/
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)

/* GPIOB寄存器地址,强制转换成指针 */
#define GPIOB_CRL	*(unsigned int*)(GPIOB_BASE+0x00)
#define GPIOB_CRH	*(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_IDR	*(unsigned int*)(GPIOB_BASE+0x08)
#define GPIOB_ODR	*(unsigned int*)(GPIOB_BASE+0x0C)
#define GPIOB_BSRR	*(unsigned int*)(GPIOB_BASE+0x10)
#define GPIOB_BRR	*(unsigned int*)(GPIOB_BASE+0x14)
#define GPIOB_LCKR	*(unsigned int*)(GPIOB_BASE+0x18)

/*RCC外设基地址*/
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1时钟使能寄存器地址,强制转换成指针*/
#define RCC_APB2ENR	*(unsigned int*)(RCC_BASE+0x18)
int main()
{
RCC_APB2ENR |=(1<<3);//开启GPIOB的时钟
GPIOB_CRL&=~(0x0F<<(4*0));//清零PB0的控制位
GPIOB_CRL|=(1<<(4*0));//配置PB0的控制位
GPIOB_ODR&=~(1<0);//PB0输出低电平
while(1);
}

  

 下面是库函数版本的bsp_led.h文件:

#ifndef __LED_H
#define __LED_H
#include"stm32f10x.h"
//定义端口,时钟,引脚
#define red_PORT GPIOB
#define red_PIN GPIO_Pin_5
#define red_LCK RCC_APB2Periph_GPIOB

#define green_PORT GPIOB
#define green_PIN GPIO_Pin_0
#define green_LCK RCC_APB2Periph_GPIOB

#define blue_PORT GPIOB
#define blue_PIN GPIO_Pin_1
#define blue_LCK RCC_APB2Periph_GPIOB

#define ON 0//低电平点亮led
#define OFF 1
//定义7种颜色的显示
#define red(a) if(a) GPIO_SetBits(red_PORT,red_PIN);\
else GPIO_ResetBits(red_PORT,red_PIN)
#define green(a) if(a) GPIO_SetBits(green_PORT,green_PIN);\
else GPIO_ResetBits(green_PORT,green_PIN)
#define blue(a) if(a) GPIO_SetBits(blue_PORT,blue_PIN);\
else GPIO_ResetBits(blue_PORT,blue_PIN)

#define yellow red(ON);green(ON);blue(OFF)
#define purple red(ON);green(OFF);blue(ON)
#define cyan red(OFF);green(ON);blue(ON)
#define white red(ON);green(ON);blue(ON)

void LED_GPIO_Config(void);

#endif

 


下面是bsp_led.c文件:

#include "bsp_led.h"
void LED_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO结构体
    RCC_APB2PeriphClockCmd(red_LCK|green_LCK|blue_LCK,ENABLE);//使能外设时钟
    GPIO_InitStructure.GPIO_Pin=red_PIN;//配置引脚,模式,速度
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(red_PORT,&GPIO_InitStructure);//初始化配置
    
    GPIO_InitStructure.GPIO_Pin=green_PIN;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(green_PORT,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin=blue_PIN;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(blue_PORT,&GPIO_InitStructure);
    
    red(OFF);
    green(OFF);
    blue(OFF);
}

 

下面是main.c:

#include"stm32f10x.h"
#include"bsp_led.h"
int main(void)
{
LED_GPIO_Config();
while(1)
{
red(ON);
}
}

 

以上代码能正常运行的前提是已经搭建好你自己的程序基础框架。

 

posted on 2018-06-19 18:59  lzd626  阅读(1567)  评论(0编辑  收藏  举报