使用固件库点亮LED灯

1. 项目:使用固件库点亮LED灯。

2. 代码:

  main.c

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"

/*宏定义实现快速移植*/
#define LED_GPIO_PORT                        GPIOB
#define LED_GPIO_CLK_ENABLE            RCC->APB2ENR |= ((1)<<3);
#define LED_G_GPIO_PIN                    GPIO_Pin_0

void Delay(uint32_t count)
{
    for(;count!=0;count--);
}

int main(void)
{

//点亮绿灯
    GPIO_InitTypeDef GPIO_InitStructure;
    
    LED_GPIO_CLK_ENABLE;            //打开GPIOB端口时钟
    GPIO_InitStructure.GPIO_Pin = LED_G_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LED_GPIO_PORT,&GPIO_InitStructure);
    while(1)
    {
        GPIO_SetBits(LED_GPIO_PORT, LED_G_GPIO_PIN);
        Delay(0xfffff);    /*延时*/
        GPIO_ResetBits(LED_GPIO_PORT, LED_G_GPIO_PIN);    
        Delay(0xfffff);
    }
    
}


void SystemInit(void)
{
    //函数体为空,目的是为了骗过编译器报错
}

 

stm32f10x.h

#ifndef __stm32f10x_h
#define __stm32f10x_h

//外设 peripheral

#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 + 0x18)

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;

typedef struct
{
    uint32_t CR;
    uint32_t CFGR;
    uint32_t CIR;
    uint32_t APB2RSTR;
    uint32_t APB1RSTR;
    uint32_t AHBENR;
    uint32_t APB2ENR;
    uint32_t APB1ENR;
    uint32_t BDCR;
    uint32_t CSR;
}RCC_TypeDef;

#define GPIOB        ((GPIO_TypeDef*)GPIOB_BASE)
#define RCC            ((RCC_TypeDef*)RCC_BASE)

#endif /*__stm32f10x_h*/

 

stm32f10x_gpio.c

#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;    /*设置引脚为低电平*/
}

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef * GPIO_InitStruct)        /*GPIO外设指针,GPIO初始化结构体指针*/
{
    uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
    uint32_t tmpreg = 0x00, pinmask = 0x00;
/*--------------------------------GPIO Mode Configuration---------------------------------------*/        
    currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode)&((uint32_t)0x0f);
    
    if (( ((uint32_t)GPIO_InitStruct->GPIO_Mode)&((uint32_t)0x10) )!= 0x00)        /*判断GPIO_Mode的bit4是等于1,则为输出*/
    {
        currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;                /*如果为输出,则设定速率*/
    }
/*--------------------------------GPIO CRL Configuration---------------------------------------*/        
    if (((uint32_t)GPIO_InitStruct->GPIO_Pin &((uint32_t)0x00ff)) != 0x00)    /*通过pin的值判断初始化低8位哪个引脚*/
    {
        tmpreg = GPIOx->CRL;                                                /*先备份CRL寄存器的值*/
        for (pinpos = 0x00; pinpos < 0x08; pinpos++)                        /*0x08: 0000 1000; 循环,从pin0开始配对,找出具体的pin*/
        {
            pos = ((uint32_t)0x01) << pinpos;                                /*pos的值为1,左移pinpos位*/
            currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;                    /*令pos与输入参数GPIO_PIN作位与运算*/
            if (currentpin == pos)                                            /*若currentpin = pos,则找到使用的引脚*/
            {
                pos = pinpos << 2;
                pinmask = ((uint32_t)0x0f) << pos;                            /*清除相同的低控制位*/
                tmpreg &= ~pinmask;
                
                tmpreg |= (currentmode << pos);                                /*在相同位写模式配置*/
                if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)        /*Reset the corresponding ODR bit*/
                {
                    GPIOx->BRR = (((uint32_t)0x01) << pinpos);
                }
                else
                {
                    if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)    /*Set the corresponding ODR bit*/
                    {
                        GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
                    }
                }
            }
        }
        GPIOx->CRL = tmpreg;
    }
/*----------------------------------GPIO CRH Configuration---------------------------------------*/        
    if (GPIO_InitStruct-> GPIO_Pin > 0x00ff)
    {
        tmpreg = GPIOx-> CRH;
        for (pinpos = 0x00; pinpos < 0x08; pinpos++)
        {
            pos = (((uint32_t)0x01) << (pinpos + 0x08));
            currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
            if (currentpin == pos)
            {
                pos = pinpos <<2;
                pinmask = ((uint32_t)0x0f) << pos;
                tmpreg &= ~pinmask;
                tmpreg |= (currentmode << pos);
                if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
                {
                    GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
                }
                if(GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
                {
                    GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
                }
            }
        }
        GPIOx->CRH = tmpreg;
    }
}

stm32f10x_gpio.h

#ifndef __stm32f10x_gpio_h
#define __stm32f10x_gpio_h

#include "stm32f10x.h"

/*GPIO引脚号定义*/
#define GPIO_Pin_0        ((uint16_t)0x0001)            /*选择Pin0 (1<<0)*/
#define GPIO_Pin_1        ((uint16_t)0x0002)            /*选择Pin1 (1<<1)*/
#define GPIO_Pin_2        ((uint16_t)0x0004)            /*选择Pin2 (1<<2)*/
#define GPIO_Pin_3        ((uint16_t)0x0008)            /*选择Pin3 (1<<3)*/
#define GPIO_Pin_4        ((uint16_t)0x0010)            /*Pin4*/
#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)
#define GPIO_Pin_A11    ((uint16_t)0xFFFF)        /*所有数据位都为1*/


/*GPIO初始化结构体*/
typedef struct
{
    uint16_t GPIO_Pin;            /*选择要配置的GPIO引脚*/
    uint16_t GPIO_Speed;        /*选择GPIO引脚的速率*/
    uint16_t GPIO_Mode;            /*选择GPIO引脚的工作模式*/
}GPIO_InitTypeDef;

typedef enum
{
    GPIO_Mode_AIN = 0x00,            //模拟输入        (0000 0000)b
    GPIO_Mode_IN_FLOATING = 0x04,    //浮空输入        (0000 0100)b
    GPIO_Mode_IPD = 0x28,            //下拉输入        (0010 1000)b
    GPIO_Mode_IPU = 0x48,            //上拉输入        (0100 1000)b
    
    GPIO_Mode_Out_OD = 0x14,        //开漏输出        (0001 0100)b
    GPIO_Mode_Out_PP = 0x10,        //推挽输出        (0001 0000)b
    GPIO_Mode_AF_OD = 0x1c,            //复用开漏输出    (0001 1100)b
    GPIO_Mode_AF_PP = 0x18            //复用推挽输出    (0001 1000)b
}GPIOMode_TypeDef;


typedef enum
{
    GPIO_Speed_10MHz = 1,        //10MHz            (01)b
    GPIO_Speed_2MHz,            //2MHz            (10)b
    GPIO_Speed_50MHz,            //50MHz            (11)b
}GPIOSpeed_TypeDef;

void GPIO_SetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef * GPIO_InitStruct);        /*GPIO外设指针,GPIO初始化结构体指针*/

#endif /*__stm32f10x_gpio_h*/

3. 执行结果:

  野火开发板指南者绿色LED灯闪亮。

 

 

参考资料:野火开发板(指南者)视频,B站搜野火即可。

 

posted @ 2022-01-15 20:38  JRS077  阅读(269)  评论(2编辑  收藏  举报