#include "stdio.h"

#define _IO volatile

typedef unsigned int uint32_t;

typedef _IO uint32_t vu32;

typedef unsigned short int uint16_t;

#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)

#define GPIO_Pin_All       ((uint16_t)0xFFFF)

#define   RCC_APB2Periph_AFIO      ((uint32_t)0x00000001)

#define   RCC_APB2Periph_GPIOA     ((uint32_t)0x00000004)

#define   RCC_APB2Periph_GPIOB     ((uint32_t)0x00000008)

#define   RCC_APB2Periph_GPIOC     ((uint32_t)0x00000010)

#define   RCC_APB2Periph_GPIOD     ((uint32_t)0x00000020)

#define LEDON    (GPIOD->BRR = GPIO_Pin_2)

#define LEDOFF   (GPIOD->BSRR = GPIO_Pin_2)

#define BITBAND(addr,bitnum)  ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+ (bitnum<<2))

/*******这个的公式是FLASH的话,   0X4200 0000 + ((add-0x4000 0000)*8+n)*4;

其中add是你要绑定的寄存器的地址,n是你要绑定的寄存器的位,

现在将其变成这种形式((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5 + (bitnum)<<2))

:addr & 0xF000 0000是将其保留最高的思位比如说addr地址是0x4201 8000那么他现在是0x4000 0000

+0x2000000变成了0x4200 0000;(addr-0x4000 0000)这其实就是保留它的后7位(在这里的改变的寄存器的地址都是

0x4001 0000的那么就是说进一步保存的是后五位)(这里注意一点,0x2200_0000这个地址每增加1,实际上就是增加

8个bit(一个地址对应一个字节),实际寄存器中的1个bit对应32个bit,所以就乘以4,地址本身增加1是8bit,

8bit乘以4倍刚好是32bit。)那么现在(addr &0XFFFFF)其实就是保留后五位,<<5就是*32(2^5),<<2就是*4(2^2);

将((A-0x4000 0000)(这个就是addr &0xFFFFF)*8+n)*4拆开就是(addr & 0XFFFFF)<<5 +(bitnum)<<2了

**********/

#define MEM_ADDR(addr)   *((volatile unsigned  long *)(addr))

#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr, bitnum))

#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)

#define KEY1   PCin(4)

typedef struct

{

_IO uint32_t   CRL;

_IO uint32_t   CRH;

_IO uint32_t   IDR;

_IO uint32_t   ODR;

_IO uint32_t   BSRR;

_IO uint32_t   BRR;

_IO uint32_t   LCKR;

}GPIO_TypeDef;

typedef struct

{

_IO uint32_t  ACR;

_IO uint32_t  KEYR;

_IO uint32_t  OPTKEYR;

_IO uint32_t  SR;

_IO uint32_t  CR;

_IO uint32_t  AR;

_IO uint32_t  OBR;

_IO uint32_t  WRPR;

}FLASH_TypeDef;

/************GPIOD管脚的内存对应地址********/

#define PERIPH_BASE          ((uint32_t)0x40000000)

#define APB2PERIPH_BASE      (PERIPH_BASE + 0x10000)

#define GPIOD_BASE           (APB2PERIPH_BASE + 0x1400)

#define GPIOD                     ((GPIO_TypeDef *)GPIOD_BASE)

//#define PERIPH_BASE          ((uint32_t) 0x40000000)

//#define APB2PERIPH_BASE      (PERIPH_BASE + 0x10000)

#define GPIOC_BASE           (APB2PERIPH_BASE + 0x1000)

#define GPIOC                ((GPIO_TypeDef *)GPIOC_BASE)

#define GPIOC_IDR_Addr       (GPIOC_BASE+8)

#define FLASH_BASE           ((uint32_t)0x40022000)

#define FLASH                ((FLASH_TypeDef *)FLASH_BASE)

typedef struct

{

_IO uint32_t CR;

_IO uint32_t CFGR;

_IO uint32_t CIR;

_IO uint32_t APB2RSTR;

_IO uint32_t APB1RSTR;

_IO uint32_t AHBENR;

_IO uint32_t APB2ENR;

_IO uint32_t APB1ENR;

_IO uint32_t BDCR;

_IO uint32_t CSR;

_IO uint32_t AHBRSTR;

_IO uint32_t CFGR2;

}RCC_TypeDef;

/****************RCC时钟************/

#define AHBPERIPH_BASE     (PERIPH_BASE         + 0x20000)

#define RCC_BASE           (AHBPERIPH_BASE + 0x1000)

#define RCC                ((RCC_TypeDef *)RCC_BASE)

void RCC_init(void)

{

RCC->CR|=1<<16;

while(!(RCC->CR>>17));

RCC->CFGR2|=4<<4;

RCC->CFGR2|=6<<8;

RCC->CFGR2|=1<<16;

RCC->CR|=1<<26;

while(!(RCC->CR>>27));

RCC->CFGR2|=1<<2;

RCC->CFGR|=1<<16;

RCC->CFGR|=7<<18;

FLASH->ACR|=0x32;

RCC->CR|=1<<24;

while(!(RCC->CR>>25));

//FLASH->ACR|=0x32;//

RCC->CFGR|=1<<1;

}

void LED_init()

{

RCC->APB2ENR|=RCC_APB2Periph_GPIOD;

GPIOD->CRL&=0xFFFFF0FF;

GPIOD->CRL|=0x00000300;

}

void Delay(vu32 nCount)

{

for(;nCount!=0;nCount--);

}

void Key_init()

{

RCC->APB2ENR|=RCC_APB2Periph_GPIOC;//如果你写成RCC->APB2ENR=RCC_APB2Periph_GPIOC;

//就不行了,因为这样的话RCC的时钟只为GPIOC打开了,

GPIOC->CRL&=0xFFF0FFFF;

GPIOC->CRL|=0x00080000;

}

int main(void)

{

unsigned int key_up=1,flag;

RCC_init();

LED_init();

Key_init();

while(1)

{

if(key_up)

LEDON;

else

LEDOFF;

/************键盘消抖**********

这里,因为键盘按下的时候,会有一段波动,不稳定.所以在这里,我们需要消抖

首先,我们的按键是按下的时候是0,所以进来一个while()循环(主要是stm32的运转速率太快了)

然后在里面我们进行延时等待,为了防止按一下按键stm32跑了很多次的情况,我们设置一个标志flag

,只让他按一下不论多长时间,LED只亮一次。*/

while(KEY1==0)//键盘消抖

{

Delay(0xfffff);

flag++;

if(flag==1)

{

key_up=!key_up;

}

}

flag=0;

}

}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐