硬件状况
DS0灯接线方式


链路:3.3V --- DS0 --- LED0 --- PB5 | --- CPU  
 分析:
     PB5, 为高电平, 那么DS0灯 熄灭 
     PB5, 为低电平, 那么DS0灯 亮
PB5的配置
配置PB5引脚为输出模式, 输出高电平(灭), 输出低电平(亮),配置为推挽输出 
 PB5 - GPIOB组控制器对应的第5个引脚,CPU核访问GPIOB控制器内部的寄存器
寻找GPIOB控制器内部的寄存器
寻找寄存器
GPIOx_CRL  
         GPIOA_CRL
         GPIOB_CRL
         GPIOC_CRL
         GPIOD_CRL
         ...
 GPIO每一组的控制器都会有一个CRL寄存器
寄存器地址 = 控制器首地址 + 寄存器偏移量 
         控制器首地址 = GPIOB_BASE
         寄存器偏移量 = 寄存器说明
总线
st公司将控制器分成3堆,每堆称为一条总线,一共有三条总线


使用的PB5属于GPIO,在APB2这根总线中
//三根总线地址
#define PERIPH_BASE      ((unsigned int)0x40000000)//所有控制器的基地址
#define APB1PERIPH_BASE  PERIPH_BASE               //APB1总线外设的基地址
#define APB2PERIPH_BASE  (PERIPH_BASE + 0x10000)   //APB2总线外设的基地址
#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000)   //AHB总线外设的基地址
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)      //GPIOA控制器基地址
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)      //GPIOB控制器基地址
PB的寄存器位置-GPIOB_CRL
#define GPIOB_CRL   (*(unsigned int *)(GPIOB_BASE +0x00))
#define GPIOB_CRH   (*(unsigned int *)(GPIOB_BASE +0x04))
#define GPIOB_ODR   (*(unsigned int *)(GPIOB_BASE +0x0C))例如:
     GPIOB_CRL 
         GPIOB_BASE + CRL寄存器的偏移量 = GPIOB_BASE + 0X00 
             拿到了GPIOB_CRL的首地址  
     
     GPIOE_CRL 
         首地址 = GPIOE_BASE + 0X00 
     GPIOB_CRL
         首地址 = GPIOB_BASE + 0X00 
         MODE5[1:0] - 描述GPIOB5的模式 
             [21:20] = 11 配置PB5为输出模式, 最大速度50MHz
         CNF5[1:0] - 确定了输入/输出模式, 具体模式选择 
             [23:22] = 00 推挽输出 
配置PB5为推挽输出, 50MHz
输出高低电平-GPIOB_ODR
    GPIOB_ODR
         首地址 = GPIOB_BASE + 0X0C
         ODR5 - GPIOB的第5个引脚 
             [5] = 0, PB5输出低电平, 亮
                  = 1, PB5输出高电平, 灭
GPIOB控制器的时钟-RCC_APB2ENR

RCC控制器位于AHB总线
#define PERIPH_BASE     ((unsigned int)0x40000000)
#define AHBPERIPH_BASE   (PERIPH_BASE + 0x20000)
#define RCC_BASE    (AHBPERIPH_BASE + 0x1000)单灯闪亮代码实现
#include "stm32f10x.h"
void delay(unsigned int i){
	while(i--);
}
// @brief SystemInit函数, 防止报错 
void  SystemInit(void)
{
	// ....
}
// @brief main函数, 入口函数 
int main(void){
	// DS0灯 
	// 1.打开GPIOB控制器的时钟 [3] = 1
	RCC_APB2ENR |= (1 << 3);
	
	// 2.配置GPIOB5为推挽输出, 50MHz
	// GPIOB_CRL [23:20] = 0011
	GPIOB_CRL &= ~(0XF << 20); // [23:20] = 0000
	GPIOB_CRL |= (3 << 20); // [21:20]=11  [23:20] = 0011
	
	
	while(1){
		// 开灯
		GPIOB_ODR &= ~(1 << 5); 
		// 延时 
		delay(0xfffff);
		// 关灯
		GPIOB_ODR |= (1 << 5); 
		// 延时 
		delay(0xfffff);
	}跑马灯实现
接线

需要将J10接到PE管脚上
接线如图:

代码实现
// main.c
#include "stm32f10x.h"
void delay(unsigned int i){
	while(i--);
}
// @brief SystemInit函数, 防止报错 
void  SystemInit(void)
{
	// ....
}
// @brief main函数, 入口函数 
int main(void){
	// 跑马灯
	// 1.打开GPIOE控制器的时钟 [6] = 1
	RCC_APB2ENR |= (1 << 6);
	
	// 2.配置GPIOE为推挽输出, 50MHz
	// GPIOE_CRL = 0x33333333
	GPIOE_CRL &= ~(0xffffffff << 0);
	GPIOE_CRL |= (0x33333333 << 0);
	
	while(1){
		//从0到7依次循环
		for(int i = 0;i<8;i++){
			//开灯
			GPIOE_ODR &=~(1<<i);
			delay(0xf0ff);
			//关灯
			GPIOE_ODR |=(1<<i);
			delay(0xf0ff);
	}
}


















