又是LED,但是这一次不同。这次是没有用库的。刚开始出了点问题,问题在这里:
void LED_Init(){
RCC->APB2ENR|=1<<2;
GPIOA->CRH&=0xFFFFFFFF;
GPIOA->CRL&=0xFFFFF0FF;
GPIOA->CRL|=0x00000300;
GPIOA->ODR|=1<<2;
GPIOA->CRL&=0xFFFFFF0F;
GPIOA->CRL|=0x00000030;
GPIOA->ODR|=1<<1;
}
因为初始化的原因,即GPIOx_CRL复位值是0x4444 4444,所以要先把对应值清零,即: GPIOA->CRL&=0xFFFFF0FF;和 GPIOA->CRL&=0xFFFFFF0F;,加上这两句,才把LED调出来。下面是具体的程序:
#include<stm32f10x_lib.h>
#define BITBAND(addr,bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+12)
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
//设置向量表偏移地址
//NVIC_VectTab:基址
//Offset:偏移量
void NVIC_SetVectorTable(u32 NVIC_VectTab,u32 Offset){
SCB->VTOR=NVIC_VectTab|(Offset&(u32)0x1FFFFF80);
}
//不能在这里执行所有外设复位!否则至少引起串口不工作.
//把所有时钟寄存器复位
void RCC_DeInit(){
RCC->APB1RSTR=0x00000000;//复位结束
RCC->APB2RSTR=0x00000000;
RCC->AHBENR=0x00000014;//睡眠模式闪存和SRAM时钟使能,其他关闭
RCC->APB1ENR=0x00000000;//外设时钟关闭
RCC->APB2ENR=0x00000000;
RCC->CR|=0x00000001;//使能内部高速时钟HSION
RCC->CFGR&=0xF8FF0000;//复位SW[1:0],HPRE[3:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC->CR&=0xFEF6FFFF;//复位HSEON,CSSON,PLLON
RCC->CR&=0xFFFBFFFF;//复位HSEBYP
RCC->CFGR&=0xFF80FFFF;//复位PLLLSRC,PLLXTPRE,PLLMUL[3:0] and USBPRE
RCC->CIR=0x00000000;//关闭所有中断
//配置向列表
#ifdef VECT_TAB_RAM
NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);
#else
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif
}
void Stm32_Clock_Init(u8 PLL){
unsigned char temp=0;
RCC_DeInit();//复位并配置向量表
RCC->CR|=0x00010000;//外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
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个延时周期
RCC->CR|=0x01000000;//PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟
while(temp!=0x02){//等待PLL作为系统时钟设置成功
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
static u8 fac_us=0;
static u16 fac_ms=0;
void delay_init(u8 SYSCLK){
SysTick->CTRL&0xFFFFFFFB;
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
void delay_ms(u16 nms){
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
SysTick->VAL=0x00;
SysTick->CTRL=0x01;
do{
temp=SysTick->CTRL;
}while(temp&0x01&&!(temp&(1<<16)));
SysTick->CTRL=0x00;
SysTick->VAL=0x00;
}
void delay_us(u32 nus){
u32 temp;
SysTick->LOAD=nus*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL=0x01;
do{
temp=SysTick->CTRL;
}while(temp&0x01&&!(temp&(1<<16)));
SysTick->CTRL=0x00;
SysTick->VAL=0x00;
}
void LED_Init(){
RCC->APB2ENR|=1<<2;
GPIOA->CRH&=0xFFFFFFFF;
GPIOA->CRL&=0xFFFFF0FF;
GPIOA->CRL|=0x00000300;
GPIOA->ODR|=1<<2;
GPIOA->CRL&=0xFFFFFF0F;
GPIOA->CRL|=0x00000030;
GPIOA->ODR|=1<<1;
}
int main(){
Stm32_Clock_Init(9);
delay_init(72);
LED_Init();
while(1){
PAout(1)=1;
PAout(2)=1;
delay_ms(300);
PAout(1)=0;
PAout(2)=0;
delay_ms(300);
}
}
发现其实不要配置那么多,下面这个程序就可以实现LED
#include<stm32f10x_lib.h>
#define BITBAND(addr,bitnum)((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+12)
void LED_Init(){
RCC->APB2ENR|=1<<2;
GPIOA->CRL&=0xFFFFFF0F;
GPIOA->CRL|=0x00000030;
GPIOA->ODR|=1<<1;
GPIOA->CRL&=0xFFFFF0FF;
GPIOA->CRL|=0x00000300;
GPIOA->ODR|=1<<2;
}
int main(){
LED_Init();
while(1){
}
}
发现代码还可以缩减为:
#include<stm32f10x_lib.h>
void LED_Init(){
RCC->APB2ENR|=1<<2;
GPIOA->CRL&=0xFFFFFF0F;
GPIOA->CRL|=0x00000030;
GPIOA->ODR|=1<<1;
GPIOA->CRL&=0xFFFFF0FF;
GPIOA->CRL|=0x00000300;
GPIOA->ODR|=1<<2;
}
int main(){
LED_Init();
while(1){
}
}
文章评论(0条评论)
登录后参与讨论