- //STM32F103RBT6,包含的启动代码是 STM32F10x.s
- #include "mytype.h"
-
- //GPIOA8是 LED0
- #define GPIOA_CRL (*(vu32*)(0x40000000+0x10000+0x0800+0x00)) //volatile unsigned long
- #define GPIOA_CRH (*(vu32*)(0x40000000+0x10000+0x0800+0x04))
- #define GPIOA_IDR (*(vu32*)(0x40000000+0x10000+0x0800+0x08))
- #define GPIOA_ODR (*(vu32*)(0x40000000+0x10000+0x0800+0x0C))
- #define PERIPH_BASE ((u32)0x40000000) //外设基址
- #define APB1PERIPH_BASE PERIPH_BASE //APB1总线上的外设基址
- #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
- #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) //AHB总线外设基址
- #define FLASH_R_BASE (AHBPERIPH_BASE + 0x2000) //flash相关寄存器基址
- #define FLASH_ACR (*(vu32*)(FLASH_R_BASE+0x00))//闪存控制0x40000000+0x20000+0x2000+0x00
- #define RCC_BASE (AHBPERIPH_BASE + 0x1000) //0x40000000+0x20000+0x1000
- #define RCC ((RCC_TypeDef*)RCC_BASE) //时钟相关
-
- typedef struct
- { //偏移,寄存器名称
- vu32 CR; //0x00,时钟控制
- vu32 CFGR; //0x04,时钟配置
- vu32 CIR; //0x08,时钟中断
- vu32 APB2RSTR; //0x0c,APB2外设复位
- vu32 APB1RSTR; //0x10,APB1外设复位
- vu32 AHBENR; //0x14,AHB外设时钟使能
- vu32 APB2ENR; //0x18,APB2外设时钟使能
- vu32 APB1ENR; //0x1c,APB1外设时钟使能
- vu32 BDCR; //0x20,备份域控制
- vu32 CSR; //0x24,控制/状态
- } RCC_TypeDef;
-
- void delay(unsigned long i)//8M内部时钟的超级不精确的软延时,9倍频后延时是之前的9倍
- {
- int j;
- while(i--)
- {
- for(j=0;j<1500;j++)
- {}
- }
- }
-
- void Stm32_Clock_Init(u8 PLL) //时钟初始化
- {
- unsigned char temp=0;
- RCC->CR|=0x00010000; //外部高速时钟使能HSEON
- while(!(RCC->CR>>17));//检测第17位HSERDY为1表示外部时钟就绪
- RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
- PLL-=2; //抵消2个单位,参数匹配
- RCC->CFGR|=PLL<<18; //设置PLL值 2~16
- RCC->CFGR|=1<<16; //PLLSRC ON
- FLASH_ACR|=0x32; //FLASH配2个等待周期,匹配72M系统时钟
-
- RCC->CR|=0x01000000; //PLLON
- while(!(RCC->CR>>25));//等待PLL锁定
- RCC->CFGR|=0x00000002;//设置PLL作为系统时钟
- while(temp!=0x02) //等待PLL作为系统时钟设置成功
- {
- temp=RCC->CFGR>>2;
- temp&=0x03;
- }
- }
-
- int main(void)
- {
- Stm32_Clock_Init(9); //启用外部8M时钟,9倍频,即72M
-
- { //GPOIA的led初始化
- RCC->APB2ENR= 1<<2; //打开PA时钟,
- GPIOA_CRH &= 0XFFFFFFF0; //准备配置PA8 ,PA8是LED0
- GPIOA_CRH |= 0X00000003; //PA8 推挽输出
- GPIOA_ODR |= 1<<8; //PA8 输出高,即先关闭led
- }
-
- while(1)
- {
- GPIOA_ODR=clBit(GPIOA_ODR,8); //第8位置0,点亮led
- delay(3000); //用一样的参数,和之前使用内部8M时钟的比较效果
- GPIOA_ODR=enBit(GPIOA_ODR,8); //第8位置1,熄灭led
- delay(3000);
- }
- }
-
- //目测led翻转速度差不多是原来9倍
复制代码
|